reorganize service and add timer, require auth on viewer
This commit is contained in:
parent
1fad7e1b23
commit
fb1180ae60
23
README.md
23
README.md
|
@ -12,16 +12,33 @@ Does not support different accounts.
|
|||
|
||||
## Install
|
||||
|
||||
### Archiver
|
||||
|
||||
1. Create a venv
|
||||
2. `pip install -r requirements.txt`
|
||||
3. `cp config.yml.sample config.yml`
|
||||
4. Edit `config.yml` and configure your login info.
|
||||
5. `python3 run.py`
|
||||
5. `python3 archiver.py`
|
||||
|
||||
A sample systemd service file is included.
|
||||
### Viewer
|
||||
|
||||
1. `sudo mkdir /etc/secrets`
|
||||
2. `sudo chown -R root:root /etc/secrets`
|
||||
3. Generate your password:
|
||||
```shell
|
||||
echo -n "<your password>" | base64
|
||||
```
|
||||
4. Edit `/etc/secrets/imapviewer` with this content:
|
||||
```shell
|
||||
SQLITE3_DB=<path to your sqlite3 database>
|
||||
HTTP_AUTH_PASS=<your encoded password>
|
||||
```
|
||||
5. `sudo chmod 600 /etc/secrets/imapviewer`
|
||||
6. Reload and start the service.
|
||||
|
||||
Sample systemd services file is included.
|
||||
|
||||
## To Do
|
||||
|
||||
- [ ] Fix subject decoding. Some character sets aren't detected correctly.
|
||||
- [ ] Sync Gmail categories as folders.
|
||||
- [ ] In the viewer, format the raw email to something viewable.
|
||||
|
|
|
@ -3,4 +3,5 @@ chardet==5.2.0
|
|||
humanize==4.9.0
|
||||
mmh3==4.1.0
|
||||
flask==3.0.2
|
||||
python-magic==0.4.27
|
||||
python-magic==0.4.27
|
||||
flask_httpauth==4.8.0
|
25
server.py
25
server.py
|
@ -1,3 +1,4 @@
|
|||
import base64
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
|
@ -6,11 +7,31 @@ from pathlib import Path
|
|||
|
||||
import magic
|
||||
from flask import Flask, render_template, send_from_directory
|
||||
from flask_httpauth import HTTPBasicAuth
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
if not os.environ.get('SQLITE3_DB'):
|
||||
raise Exception('SQLITE3_DB not set.')
|
||||
if not os.environ.get('HTTP_AUTH_PASS'):
|
||||
raise Exception('HTTP_AUTH_PASS not set.')
|
||||
|
||||
try:
|
||||
user_password = base64.b64decode(os.environ.get('HTTP_AUTH_PASS')).decode().replace('\n', '')
|
||||
except UnicodeDecodeError:
|
||||
raise Exception('Cannot decode password. Is it base64 encoded?')
|
||||
|
||||
auth = HTTPBasicAuth()
|
||||
users = {
|
||||
'admin': user_password,
|
||||
}
|
||||
|
||||
|
||||
@auth.get_password
|
||||
def get_pw(username):
|
||||
if username in users:
|
||||
return users.get(username)
|
||||
return None
|
||||
|
||||
|
||||
def get_db_connection():
|
||||
|
@ -24,6 +45,7 @@ def dict_from_row(row):
|
|||
|
||||
|
||||
@app.route('/')
|
||||
@auth.login_required
|
||||
def index():
|
||||
conn = get_db_connection()
|
||||
folders = conn.execute('SELECT name, table_name FROM folders_mapping').fetchall()
|
||||
|
@ -36,6 +58,7 @@ def index():
|
|||
|
||||
|
||||
@app.route('/folder/<table_name>')
|
||||
@auth.login_required
|
||||
def folder(table_name):
|
||||
conn = get_db_connection()
|
||||
emails = conn.execute(f'SELECT * FROM {table_name} ORDER BY timestamp DESC').fetchall()
|
||||
|
@ -47,6 +70,7 @@ def folder(table_name):
|
|||
|
||||
|
||||
@app.route('/email/<table_name>/<id>')
|
||||
@auth.login_required
|
||||
def email(table_name, id):
|
||||
conn = get_db_connection()
|
||||
email = conn.execute(f'SELECT * FROM {table_name} WHERE id = ?', (id,)).fetchone()
|
||||
|
@ -58,6 +82,7 @@ def email(table_name, id):
|
|||
|
||||
|
||||
@app.route('/attachments/<path:filename>')
|
||||
@auth.login_required
|
||||
def download_file(filename):
|
||||
mimetype = magic.from_file(str(Path('attachments', filename)), mime=True)
|
||||
return send_from_directory('attachments', filename, mimetype=mimetype)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=IMAP archiver service timer
|
||||
|
||||
[Timer]
|
||||
OnBootSec=15min
|
||||
OnUnitActiveSec=12h
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=IMAP archiver viewer
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
User=emailsync
|
||||
Group=emailsync
|
||||
EnvironmentFile=/etc/secrets/imapviewer
|
||||
ExecStart=/srv/email/imap-archiver/venv/bin/python3 /srv/email/imap-archiver/server.py
|
||||
SyslogIdentifier=imap-viewer
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
Loading…
Reference in New Issue