Skip to content

1.7 Step | CreateDbRole

Omisen edited this page Jul 26, 2026 · 2 revisions

Crea il ruolo PostgreSQL per Odoo (db_user), in modo reversibile. Vive in src/steps/create_db_role.rs. Port di create_db_user di lib/postgres.sh.


Ciclo di vita

Fase Comportamento
snapshot il ruolo esiste già? (SELECT 1 FROM pg_roles WHERE rolname = ...) → Preexisting/Untracked
run Preexisting → skip. Assente → CREATE ROLE "<user>" WITH LOGIN CREATEDB [PASSWORD '…'], poi CreatedByUs. dry_run → solo log
undo solo CreatedByUs: DROP ROLE IF EXISTS "<user>". Idempotente, best-effort

Con password (dal .env DB_PASSWORD) → ... PASSWORD '<escaped>'; senza → autenticazione peer (default sicuro locale, dove utente OS e ruolo PG hanno lo stesso nome).


Coordinamento con il database (ordine inverso)

DROP ROLE fallisce se il ruolo possiede oggetti — e il ruolo possiede il database creato da 1.8 CreateDatabase. È lo stesso pattern del coordinamento home in 1.2 CreateOdooUser: ogni step possiede la rimozione di ciò che ha creato, e l'ordine inverso garantisce la sequenza corretta.

produzione:  CreateDbRole → CreateDatabase
rollback:    undo CreateDatabase (drop DB) → undo CreateDbRole (drop ruolo)

Il DB sparisce prima del ruolo che lo possiede. Un test lo verifica eseguendo l'engine con un log condiviso e asserendo che DROP DATABASE preceda DROP ROLE.


Sicurezza della password (mai nei log)

La password arriva dal tipo Secret (Debug redatto). Il valore in chiaro è estratto solo al punto di chiamata del confine SystemOps (pg_create_role), e non viene mai loggato: il log riporta al massimo with_password = true/false.

Dentro il confine (dove sta tutto il rischio):

  • l'identifier (nome ruolo) è validato come identifier in Fase 1 e comunque double-quotato;
  • la password è un literal SQL con gli apici singoli raddoppiati (escape_sql_literal);
  • l'SQL viaggia via stdin, non in argv (non compare nella command line dei processi);
  • in caso di errore lo stderr è soppresso: psql ristampa la riga fallita, che conterrebbe la password. Si perde il dettaglio diagnostico pur di non rischiare un leak.

Il mock nei test registra solo has_password: bool, mai il valore.


Note di design

  • Non-aggressività sui preesistenti: un ruolo che c'era già non viene né creato né droppato.
  • Undo best-effort e idempotente (DROP ROLE IF EXISTS).
  • Test: ruolo assente (create/drop con argomenti attesi), password con apice singolo (escape corretto, valore non registrato), ruolo Preexisting (mai toccato), escape puro '''.

Clone this wiki locally