Initial commit: CI Agent competitive-intelligence monitoring app
FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
"""Symmetric encryption for secrets stored at rest - currently just
|
||||
per-user API keys (app/models/user_api_key.py). Not used for passwords
|
||||
(those are one-way hashed via app.core.security, never decrypted) - this
|
||||
is specifically for secrets the app must later read back out in plaintext
|
||||
to actually call a third-party API on the user's behalf.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from cryptography.fernet import Fernet, InvalidToken
|
||||
|
||||
from app.core.config import Settings
|
||||
|
||||
|
||||
def encrypt_secret(plaintext: str, settings: Settings) -> str:
|
||||
return Fernet(settings.api_key_encryption_secret).encrypt(plaintext.encode()).decode()
|
||||
|
||||
|
||||
def decrypt_secret(ciphertext: str, settings: Settings) -> str:
|
||||
try:
|
||||
return Fernet(settings.api_key_encryption_secret).decrypt(ciphertext.encode()).decode()
|
||||
except InvalidToken as exc:
|
||||
# Only real cause in practice: api_key_encryption_secret was
|
||||
# rotated after this value was encrypted under the old one.
|
||||
raise ValueError("Stored value cannot be decrypted with the current key") from exc
|
||||
Reference in New Issue
Block a user