refactor(authz): route users_service through the shared authz-verdict mapper
`users_service::require` open-coded the `AuthzDenied → {Forbidden, Backend}`
match that `authz::script_gate` centralizes for every other stateful service —
the one straggler. Extract the mapping into `authz::require_mapped` (used now by
both `script_gate` variants and `users_service::require`), so the verdict→error
mapping lives in exactly one place. Also refresh the stale `to_app_user` comment
(it referenced an unshipped "commit 8" stub; roles are resolved via
`fetch_roles` and passed in). No behavior change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ use crate::app_user_verification_repo::{AppUserVerificationRepo, AppUserVerifica
|
||||
use crate::auth::{
|
||||
generate_session_token, hash_password, hash_token, verify_password, TIMING_FLAT_DUMMY_HASH,
|
||||
};
|
||||
use crate::authz::{self, AuthzDenied, AuthzRepo, Capability};
|
||||
use crate::authz::{self, AuthzRepo, Capability};
|
||||
|
||||
/// Runtime configuration. Defaults match the v1.1.8 brief — overridable
|
||||
/// via env vars wired in the picloud binary.
|
||||
@@ -268,17 +268,18 @@ impl UsersServiceImpl {
|
||||
// Public HTTP execution — script-as-gate; not denied here.
|
||||
return Ok(());
|
||||
};
|
||||
match authz::require(&*self.authz, p, cap).await {
|
||||
Ok(()) => Ok(()),
|
||||
Err(AuthzDenied::Denied) => Err(UsersError::Forbidden),
|
||||
Err(AuthzDenied::Repo(e)) => Err(UsersError::Backend(e.to_string())),
|
||||
}
|
||||
authz::require_mapped(
|
||||
&*self.authz,
|
||||
p,
|
||||
cap,
|
||||
|| UsersError::Forbidden,
|
||||
UsersError::Backend,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Compose the public `AppUser` shape from a `AppUserRow`. Roles
|
||||
/// are always empty in commit 4 of v1.1.8; commit 8 (per-app
|
||||
/// roles) replaces this stub with an actual `app_user_roles`
|
||||
/// query.
|
||||
/// Compose the public `AppUser` shape from an `AppUserRow`, with the caller's
|
||||
/// already-resolved per-app `roles` (see [`Self::fetch_roles`]).
|
||||
fn to_app_user(row: AppUserRow, roles: Vec<String>) -> AppUser {
|
||||
AppUser {
|
||||
id: row.id,
|
||||
|
||||
Reference in New Issue
Block a user