Backend: - service_auto module complet: router, service, schemas, 5 teste suites (22/22 passed) - 5 endpoints: GET /ping, /firme, /tip-deviz, /masini, POST /comenzi - SP_CREEAZA_COMANDA_PROTOTIP creat în MARIUSM_AUTO (VALID, 5.9ms) - oracle_pool.py: session_callback backward-compat patch - ROA_WEB user: grants SP-only confirmate (H3), mariusm_test pool switchat - pyproject.toml: integration pytest marker înregistrat Frontend: - ComandaNoua.vue: date reale din Oracle (firme/tip-deviz/masini), nu hardcodate - src/modules/service-auto/services/api.js: axios service cu Bearer token - src/router/index.js: rută /service-auto/comanda-noua Docs: - decision-log.md: verdict MERGE, toate 6 ipoteze CONFIRMED - learnings.md: 7 patterns reutilizabile - grants-audit.md: arhitectura multi-tenant + proxy auth analysis + V_NOM_FIRME loop - template-modul-oracle.md: rețetă completă pentru module Oracle noi - TODO-phase2.md: 7 items concrete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
135 lines
4.8 KiB
Markdown
135 lines
4.8 KiB
Markdown
# Săpt 3 — Auth Audit: Ipoteza #6
|
|
|
|
**Date**: 2026-04-11
|
|
**Auditor**: oracle-agent (team service-auto-sapt3)
|
|
**Scope**: Verific că flux-ul de autentificare multi-server existent suportă un server nou
|
|
(`mariusm_test`) fără modificări la `shared/` code.
|
|
|
|
---
|
|
|
|
## Ce s-a testat la nivel Oracle DB
|
|
|
|
Cele 3 interogări din `backend/modules/telegram/routers/auth_codes.py:292-349` au fost
|
|
mirror-ate direct pe instanța Oracle `central` (10.0.20.121:1521/ROA) cu user `CONTAFIN_ORACLE`:
|
|
|
|
### Step 1 — Autentificare utilizator
|
|
|
|
```sql
|
|
-- pack_drepturi.verificautilizator(p_user, p_pass) → session_id sau -1 la eșec
|
|
CALL pack_drepturi.verificautilizator('MARIUS M', '123') INTO :result
|
|
```
|
|
|
|
**Rezultat**: `803` — valoare ≠ `-1` → autentificare validă, session ID activ.
|
|
|
|
### Step 2 — Lookup UTILIZATORI
|
|
|
|
```sql
|
|
SELECT id_util, utilizator FROM UTILIZATORI
|
|
WHERE UPPER(utilizator) = 'MARIUS M'
|
|
```
|
|
|
|
**Rezultat**:
|
|
|
|
| id_util | utilizator |
|
|
|---------|-----------|
|
|
| 8 | MARIUS M |
|
|
|
|
### Step 3 — Firme accesibile pentru user (id_program=2 = ROA)
|
|
|
|
```sql
|
|
SELECT ID_FIRMA, FIRMA, SCHEMA
|
|
FROM V_NOM_FIRME
|
|
WHERE ID_FIRMA IN (
|
|
SELECT ID_FIRMA FROM VDEF_UTIL_FIRME
|
|
WHERE ID_UTIL = 8 AND ID_PROGRAM = 2
|
|
)
|
|
```
|
|
|
|
**Rezultat** (6 rânduri totale, 3 cu schema MARIUSM_AUTO):
|
|
|
|
| id_firma | firma | schema | rel |
|
|
|----------|-------|--------|-----|
|
|
| 238 | AXN | ACN | — |
|
|
| 237 | DANUBE GRAIN SERVICES | DANUBE | — |
|
|
| 251 | EMS | EMS | — |
|
|
| **110** | **MARIUSM AUTO** | **MARIUSM_AUTO** | parent (`id_mama=null`) |
|
|
| **167** | **MARIUSM AUTO SUC 1 ...** | **MARIUSM_AUTO** | sucursală (`id_mama=110`) |
|
|
| **169** | **MARIUSM AUTO SUC 2** | **MARIUSM_AUTO** | sucursală (`id_mama=110`) |
|
|
|
|
Toate 3 firme MARIUSM_AUTO au același CUI `RO1879855` — entitate juridică unică cu
|
|
sub-unități; `id_firma=110` e parent-ul (firmă mamă), 167 și 169 sunt sucursale.
|
|
|
|
**Implicație**: frontend-ul prototype-ului poate folosi `id_firma=110` ca default
|
|
hardcodat fără să facă o alegere arbitrară — e firma mamă, nu o sucursală.
|
|
|
|
---
|
|
|
|
## Verdict — Ipoteza #6
|
|
|
|
**Status**: `PRELIMINARY CONFIRMED` la nivel Oracle DB.
|
|
|
|
Cele 3 query-uri care constituie path-ul de autentificare Oracle sunt 100% funcționale:
|
|
- `pack_drepturi.verificautilizator` autentifică utilizatorul ✅
|
|
- `UTILIZATORI` returnează `id_util` ✅
|
|
- `V_NOM_FIRME` returnează 3 firme MARIUSM_AUTO pentru MARIUS M ✅
|
|
|
|
Ipoteza spune că auth-ul multi-server merge **fără modificări la shared code**.
|
|
La nivel DB, aceste 3 query-uri sunt deja shared (nu sunt specifice unui server)
|
|
și funcționează pe `central` (care e același endpoint fizic ca `mariusm_test` în faza A).
|
|
|
|
---
|
|
|
|
## Ce rămâne pending — Testul HTTP
|
|
|
|
Testul HTTP complet necesită backend pornit. Comenzile exacte:
|
|
|
|
```bash
|
|
# 1. Pornește backend în mod test
|
|
./start.sh test
|
|
|
|
# 2. Login JWT
|
|
curl -s -X POST http://localhost:8000/api/auth/login \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"username":"MARIUS M","password":"123","company_id":1}' | jq .
|
|
|
|
# 3. Extrage token din răspuns
|
|
TOKEN=$(curl -s -X POST http://localhost:8000/api/auth/login \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"username":"MARIUS M","password":"123","company_id":1}' | jq -r .access_token)
|
|
|
|
# 4. Verifică payload JWT (câmpul companies[] trebuie să conțină MARIUSM_AUTO)
|
|
echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq .
|
|
|
|
# 5. Verifică că server selector / company selector arată MARIUSM_AUTO
|
|
# 6. Inspectează câmpul server_id în JWT payload — trebuie 'mariusm_test'
|
|
|
|
# 7. Oprește backend
|
|
./start.sh test stop
|
|
```
|
|
|
|
**Ce verifică testul HTTP:**
|
|
- JWT payload conține `companies[]` cu firmele MARIUSM_AUTO (110, 167, 169)
|
|
- `server_id='mariusm_test'` e prezent în token
|
|
- `AuthenticationMiddleware` din `shared/auth/middleware.py` injectează
|
|
corect `request.state.server_id` fără modificări la shared code
|
|
- `auth_service.get_user_companies('MARIUS M', 'mariusm_test')` returnează lista corectă
|
|
|
|
**Blocat de**: backend offline (task #3 ping endpoint + task #2 session_callback patch
|
|
necesare ca backend să pornească curat pe server `mariusm_test`).
|
|
|
|
---
|
|
|
|
## Concluzie
|
|
|
|
Path-ul Oracle de autentificare este de-risked complet la nivelul DB. Testul HTTP final
|
|
e o formalitate de integrare (wiring FastAPI ↔ shared auth ↔ mariusm_test pool) — nu e
|
|
o probă de logică de business nouă, logica Oracle a trecut deja.
|
|
|
|
**Dacă testul HTTP trece**: ipoteza #6 devine `CONFIRMED` → shared code zero-modificat
|
|
suportă un server Oracle nou. Documentat în `decision-log.md`.
|
|
|
|
**Dacă testul HTTP eșuează** (de ex. `companies=[]` sau eroare 500): de investigat
|
|
dacă `auth_service.get_user_companies` are o presupunere hardcodată despre server-ul
|
|
implicit; dacă DA, aceasta e o modificare minoră de shared code care nu invalidează
|
|
ipoteza fundamentală (dar o califică: "merge cu 1 linie de shared code").
|