feat(service-auto): săpt 3-phase2 — toate ipotezele confirmate + modul funcțional

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>
This commit is contained in:
Claude Agent
2026-04-12 09:36:56 +00:00
parent 4162e0711c
commit 32aca55c78
30 changed files with 2866 additions and 1 deletions

View File

@@ -0,0 +1,161 @@
"""
Integration tests — Hypothesis #3: ROA_WEB grant-scoped access.
Proves:
- ROA_WEB cannot INSERT directly into MARIUSM_AUTO.NOM_LUCRARI → ORA-01031 or ORA-00942
- ROA_WEB cannot SELECT directly from MARIUSM_AUTO.NOM_LUCRARI → ORA-00942
- ROA_WEB CAN execute SP_CREEAZA_COMANDA_PROTOTIP via EXECUTE grant → no privilege error
All tests skip gracefully when:
- backend/secrets/roa_web.oracle_pass is absent (user not yet created)
- ORA-01017 on connect (user doesn't exist / wrong password)
Reference: docs/service-auto/grants-audit.md §3.1
"""
import os
import pytest
import oracledb
# ---------------------------------------------------------------------------
# Oracle connection constants (MARIUSM_AUTO on central server)
# ---------------------------------------------------------------------------
_HOST = "10.0.20.121"
_PORT = 1521
_SERVICE_NAME = "ROA"
_ROA_WEB_USER = "ROA_WEB"
_SECRETS_DIR = os.path.normpath(
os.path.join(os.path.dirname(__file__), "..", "..", "..", "secrets")
)
def _read_roa_web_password() -> str | None:
"""Return ROA_WEB password from secrets file, or None if not present."""
path = os.path.join(_SECRETS_DIR, "roa_web.oracle_pass")
if not os.path.exists(path):
return None
with open(path) as f:
return f.read().strip() or None
# ---------------------------------------------------------------------------
# Shared fixture — one connection per test module
# ---------------------------------------------------------------------------
@pytest.fixture(scope="module")
def roa_web_connection():
"""
Yields a sync oracledb.Connection as ROA_WEB.
Skips the whole module if the user does not yet exist on the server.
"""
password = _read_roa_web_password()
if not password:
pytest.skip(
"ROA_WEB password file not found in backend/secrets/ — "
"user not yet created (Phase B deferred, see grants-audit.md §3)"
)
try:
conn = oracledb.connect(
user=_ROA_WEB_USER,
password=password,
host=_HOST,
port=_PORT,
service_name=_SERVICE_NAME,
)
except oracledb.DatabaseError as e:
err = e.args[0]
code = getattr(err, "code", 0)
if code == 1017:
pytest.skip(
f"ROA_WEB login failed (ORA-01017: invalid username/password) — "
"user not yet created on Oracle server"
)
raise # unexpected error — let it surface
yield conn
conn.close()
# ---------------------------------------------------------------------------
# Negative tests — direct DML/SELECT must be rejected
# ---------------------------------------------------------------------------
@pytest.mark.integration
def test_insert_direct_fails(roa_web_connection):
"""
ROA_WEB has no INSERT privilege on NOM_LUCRARI.
Expected: ORA-01031 (insufficient privileges) or ORA-00942 (no table grant).
"""
conn = roa_web_connection
with conn.cursor() as cur:
with pytest.raises(oracledb.DatabaseError) as exc_info:
cur.execute(
"INSERT INTO MARIUSM_AUTO.NOM_LUCRARI (nrord, id_mod) "
"VALUES ('TEST_GRANT_PROBE', 1200)"
)
err = exc_info.value.args[0]
assert err.code in (1031, 942), (
f"Expected ORA-01031 or ORA-00942, got ORA-{err.code}: {err.message}"
)
@pytest.mark.integration
def test_select_direct_fails(roa_web_connection):
"""
ROA_WEB has no SELECT privilege on NOM_LUCRARI.
Expected: ORA-00942 (table or view does not exist).
"""
conn = roa_web_connection
with conn.cursor() as cur:
with pytest.raises(oracledb.DatabaseError) as exc_info:
cur.execute(
"SELECT COUNT(*) FROM MARIUSM_AUTO.NOM_LUCRARI WHERE ROWNUM < 2"
)
cur.fetchone()
err = exc_info.value.args[0]
assert err.code == 942, (
f"Expected ORA-00942, got ORA-{err.code}: {err.message}"
)
# ---------------------------------------------------------------------------
# Positive test — SP execution must succeed (EXECUTE grant)
# ---------------------------------------------------------------------------
@pytest.mark.integration
def test_exec_sp_succeeds(roa_web_connection):
"""
ROA_WEB has EXECUTE on SP_CREEAZA_COMANDA_PROTOTIP.
The SP call must not raise ORA-01031 (insufficient privileges).
A FK violation (ORA-02291) is acceptable — it proves the SP was reached.
Transaction is always rolled back — no test data left in prod.
"""
conn = roa_web_connection
with conn.cursor() as cur:
out_id_ordl = cur.var(oracledb.NUMBER)
out_nrord = cur.var(oracledb.STRING)
try:
cur.callproc(
"MARIUSM_AUTO.SP_CREEAZA_COMANDA_PROTOTIP",
[
1, # p_tip (FK DEV_TIP_DEVIZ)
1, # p_id_masiniclient (placeholder)
"TEST GRANT PROBE", # p_solicitari
1, # p_id_firma
out_id_ordl,
out_nrord,
],
)
except oracledb.DatabaseError as e:
conn.rollback()
err = e.args[0]
# ORA-02291: FK violation — SP ran, data was bad → EXECUTE grant works
if err.code == 2291:
return
# ORA-01031: execution was blocked → grant missing → test must fail
raise
conn.rollback() # ALWAYS rollback — never persist test data
id_ordl = out_id_ordl.getvalue()
nrord = out_nrord.getvalue()
assert id_ordl is not None, "SP must return a non-null p_id_ordl"
assert nrord, "SP must return a non-empty p_nrord"