feat(5.20): US-013 retragere accounts.rar_creds_enc -> per-env + DROP cu garda
Toate citirile pe coloana legacy accounts.rar_creds_enc mutate pe sloturile per-env (rar_creds_test_enc/rar_creds_prod_enc): worker fallback+keepalive, are_creds (web) si are_creds_rar (integrare, +are_creds_test/_prod), write-back API la reactivare, purjare la stergere cont, _get_acasa_context/_fetch_cont_env_state. Contract API (aditiv): POST /v1/conturi/rar-creds primeste rar_target optional (test/prod), scrie in slotul corect + activeaza mediul; DELETE primeste ?env (sterge un slot sau ambele). Documentat in docs/api-rar-contract.md. DROP cu garda in db.py (schema.sql fara coloana pe DB fresh): - 6a: eliminat ADD COLUMN rar_creds_enc (fara ping-pong re-ADD dupa DROP) - 6b: try/except fail-safe (nu crapa boot-ul) + garda sqlite_version >= 3.35 - 6c: re-backfill old->new imediat inainte de assert (ancora globala) - garda orfane: DROP anulat daca vreun creds legacy nu a aterizat in slot per-env - backup criptat accounts_rar_creds_enc_backup inainte de DROP - 6d: verificare prin PRAGMA table_info (NU grep — submissions are aceeasi coloana) Garda one-way, idempotenta la boot repetat (verificat). submissions.rar_creds_enc ramane neatinsa. tests/test_retragere_creds_enc.py: niciun read pe coloana veche, conturi rar-creds env-aware, are_creds per-env, DROP blocat de garda la lipsa copiere. 9 teste existente actualizate pe sloturi per-env. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,11 +11,12 @@ Ruleaza ca proces separat sub `restart: always` (docker compose).
|
||||
- lease/timeout pe randuri 'sending' orfane.
|
||||
- re-login la token expirat (401 mid-sesiune) — JWT 30h, retry NU plafonat la 30h.
|
||||
|
||||
Creds per-cerere: fiecare submission poarta creds RAR CRIPTATE (rar_creds_enc).
|
||||
Creds per-cerere: fiecare submission poarta creds RAR CRIPTATE (submissions.rar_creds_enc).
|
||||
Worker-ul face login per CONT cu acele creds, cache-uieste JWT (30h) in memorie si
|
||||
STERGE creds-urile contului dupa primul login reusit. Token-ul in memorie acopera
|
||||
STERGE creds-urile efemere dupa primul login reusit. Token-ul in memorie acopera
|
||||
restul trimiterilor; la restart token-ul se pierde si contul re-logheaza la urmatorul
|
||||
submission care aduce creds proaspete (degradare acceptata).
|
||||
submission care aduce creds proaspete (degradare acceptata). Fallback durabil: slotul
|
||||
per-env al contului (accounts.rar_creds_{env}_enc, US-013; coloana legacy dropata).
|
||||
Dev: `worker_use_test_creds` foloseste creds <test> cand submission-ul nu are enc.
|
||||
|
||||
Pornire: python -m app.worker
|
||||
@@ -161,8 +162,8 @@ def requeue_with_backoff(conn, settings: Settings, submission_id: int, *, reason
|
||||
def claim_one(conn) -> dict | None:
|
||||
"""Claim atomic 'queued' -> 'sending', respectand next_attempt_at. Intoarce randul sau None.
|
||||
|
||||
Randul include `account_id` si `rar_creds_enc` (creds RAR criptate) pentru
|
||||
login-ul per-cont din `run`.
|
||||
Randul include `account_id` si `submissions.rar_creds_enc` (creds RAR criptate efemere)
|
||||
pentru login-ul per-cont din `run`.
|
||||
"""
|
||||
conn.execute("BEGIN IMMEDIATE")
|
||||
try:
|
||||
@@ -431,18 +432,17 @@ def _creds_for(claimed: dict, settings: Settings) -> dict | None:
|
||||
|
||||
|
||||
def _creds_from_account(conn, account_id: int, rar_env: str = "test") -> dict | None:
|
||||
"""Creds RAR durabile per-cont din slotul per-env, cu fallback la coloana legacy.
|
||||
"""Creds RAR durabile per-cont din slotul per-env (US-013 — coloana legacy dropata).
|
||||
|
||||
Canal web: creds in accounts.rar_creds_{rar_env}_enc (per-env). Fallback la
|
||||
accounts.rar_creds_enc (legacy, back-compat inainte de US-013 care dropa coloana veche).
|
||||
Canal web: creds in accounts.rar_creds_{rar_env}_enc (per-env, singurul slot valid).
|
||||
"""
|
||||
env_slot = f"rar_creds_{rar_env}_enc"
|
||||
row = conn.execute(
|
||||
f"SELECT {env_slot}, rar_creds_enc FROM accounts WHERE id=?", (account_id,)
|
||||
f"SELECT {env_slot} FROM accounts WHERE id=?", (account_id,)
|
||||
).fetchone()
|
||||
if not row:
|
||||
return None
|
||||
enc = row[env_slot] or row["rar_creds_enc"] # per-env intai, legacy fallback
|
||||
enc = row[env_slot]
|
||||
return decrypt_creds(enc) if enc else None
|
||||
|
||||
|
||||
@@ -450,16 +450,16 @@ def _keepalive_target(conn, settings: Settings) -> tuple[int | None, dict | None
|
||||
"""Un cont cu creds durabile pentru login-ul de proba (sau creds <test> in dev).
|
||||
|
||||
Ancora M2: cauta in slotul per-env al mediului `settings.rar_env` (ancora globala).
|
||||
Fallback la coloana legacy `rar_creds_enc` (back-compat inainte de US-013).
|
||||
Sare conturile ale caror creds NU se decripteaza sub cheia curenta — in dev
|
||||
`start.sh both` genereaza o cheie efemera noua la fiecare pornire.
|
||||
US-013: coloana legacy accounts.rar_creds_enc a fost dropata — se foloseste EXCLUSIV
|
||||
slotul per-env. Sare conturile ale caror creds NU se decripteaza sub cheia curenta
|
||||
(in dev `start.sh both` genereaza o cheie efemera noua la fiecare pornire).
|
||||
"""
|
||||
env_slot = f"rar_creds_{settings.rar_env}_enc"
|
||||
rows = conn.execute(
|
||||
f"SELECT id, {env_slot}, rar_creds_enc FROM accounts ORDER BY id"
|
||||
f"SELECT id, {env_slot} FROM accounts ORDER BY id"
|
||||
).fetchall()
|
||||
for row in rows:
|
||||
enc = row[env_slot] or row["rar_creds_enc"] # per-env intai, legacy fallback
|
||||
enc = row[env_slot]
|
||||
if not enc:
|
||||
continue
|
||||
creds = decrypt_creds(enc)
|
||||
|
||||
Reference in New Issue
Block a user