Jul 2nd - Optimized code 3

This commit is contained in:
2026-07-02 16:11:39 -04:00
parent 19c719ea98
commit f58fb095dd
6 changed files with 67 additions and 30 deletions
+45
View File
@@ -0,0 +1,45 @@
"""
Symmetric encryption for secrets stored in SystemSetting (currently just
the IMAP mailbox password used by email ingestion).
The Fernet key is derived from SECRET_KEY rather than a separately managed
key, so no extra key-rotation story is needed for a single-tenant on-prem
app — rotating SECRET_KEY (which already invalidates sessions) also
invalidates encrypted secrets, which is an acceptable trade-off here.
"""
import base64
import hashlib
from cryptography.fernet import Fernet, InvalidToken
from flask import current_app
def _fernet() -> Fernet:
secret = current_app.config['SECRET_KEY'].encode()
key = base64.urlsafe_b64encode(hashlib.sha256(secret).digest())
return Fernet(key)
def encrypt_secret(plain: str) -> str:
"""Encrypt a secret for storage. Empty input passes through unchanged."""
if not plain:
return ''
return _fernet().encrypt(plain.encode()).decode()
def decrypt_secret(stored: str) -> str:
"""Decrypt a secret previously written by encrypt_secret().
Falls back to returning the value unchanged if it isn't a valid Fernet
token. This covers values saved before encryption was introduced, so
existing configurations (e.g. email ingestion set up before this change)
keep working without a manual data migration — the value is simply
re-encrypted the next time it's saved through the settings form.
"""
if not stored:
return ''
try:
return _fernet().decrypt(stored.encode()).decode()
except (InvalidToken, ValueError):
return stored
+2 -1
View File
@@ -295,7 +295,8 @@ def _run_ingestion(app):
host = _get_setting('email_ingestion_host', '')
port = int(_get_setting('email_ingestion_port', '993'))
username = _get_setting('email_ingestion_user', '')
password = _get_setting('email_ingestion_password', '')
from app.services.crypto_service import decrypt_secret
password = decrypt_secret(_get_setting('email_ingestion_password', ''))
folder = _get_setting('email_ingestion_folder', 'INBOX')
move_to = _get_setting('email_ingestion_move_to', 'Processed')