From fa1ddf64b4e20f16c9d08e16dbda0445087f70db Mon Sep 17 00:00:00 2001 From: igor04091968 Date: Mon, 15 Jun 2026 00:03:44 +0300 Subject: [PATCH] refactor(portal): wire role access module --- adk-rust/crates/detmir-portal/src/main.rs | 41 ++--------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/adk-rust/crates/detmir-portal/src/main.rs b/adk-rust/crates/detmir-portal/src/main.rs index 5bd96d0..376cc18 100644 --- a/adk-rust/crates/detmir-portal/src/main.rs +++ b/adk-rust/crates/detmir-portal/src/main.rs @@ -31,6 +31,7 @@ mod portal_roles; mod production; mod readiness_api; mod risk_narrative; +mod role_access; mod workforce_kpi_explain; use api_contracts::api_contract_summary; @@ -52,6 +53,7 @@ use readiness_api::{readiness_bundle, readiness_latest, readiness_verify}; use risk_narrative::{ RiskNarrativeInputs, RiskNarrativeQuery, build_risk_narrative, build_risk_narrative_from_report, }; +use role_access::{portal_role_from_request, respond_forbidden, role_envelope}; use workforce_kpi_explain::{KpiExplainQuery, build_workforce_kpi_explain}; const INDEX_HTML: &str = include_str!("static/index.html"); @@ -1663,45 +1665,6 @@ fn handle_evidence_only_request(request: Request, args: &Cli) -> Result<()> { ) } -fn portal_role_from_request(request: &Request, url: &str) -> PortalRole { - query_param(url, "role") - .as_deref() - .and_then(PortalRole::parse) - .or_else(|| { - request - .headers() - .iter() - .find(|header| header.field.equiv("X-AWatch-Role")) - .and_then(|header| PortalRole::parse(header.value.as_str())) - }) - .unwrap_or(PortalRole::Executive) -} - -fn role_envelope(role: PortalRole, scope: &str) -> Value { - json!({ - "role": role.as_str(), - "role_label": role.label_ru(), - "scope": scope, - "allowed_scopes": role.allowed_scopes(), - "server_enforced": true, - }) -} - -fn respond_forbidden(request: Request, role: PortalRole, scope: &str) -> Result<()> { - respond_json_status( - request, - StatusCode(403), - &json!({ - "ok": false, - "error": "forbidden", - "message": format!("Роль {} не имеет доступа к контуру {scope}", role.label_ru()), - "role": role.as_str(), - "scope": scope, - "server_enforced": true, - }), - ) -} - fn cached_snapshot(args: &Cli, cache: &SnapshotCache) -> Snapshot { let mut guard = cache.lock().expect("snapshot cache mutex poisoned"); if let Some(cached) = guard.as_ref() {