admin: get_role_grant_history wrapper — v0.2.4
Capture-audit directory: every user who EVER held one of role_names for a target, revoked grants included (include_deleted); actor-gated server-side (untargeted = all targets, or targeted at target_id). PII-free (user_id + display_name). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE3r42YdE8tt7vV5zPdJdE
This commit is contained in:
parent
369d4d5580
commit
b29beec9e9
|
|
@ -30,6 +30,10 @@ service AuthAdminService {
|
||||||
rpc GetRoleScopes (GetRoleScopesRequest) returns (GetRoleScopesResponse);
|
rpc GetRoleScopes (GetRoleScopesRequest) returns (GetRoleScopesResponse);
|
||||||
rpc GetUserWithRoles (GetUserWithRolesRequest) returns (GetUserWithRolesResponse);
|
rpc GetUserWithRoles (GetUserWithRolesRequest) returns (GetUserWithRolesResponse);
|
||||||
rpc GetAssignableRoles (GetAssignableRolesRequest) returns (GetAssignableRolesResponse);
|
rpc GetAssignableRoles (GetAssignableRolesRequest) returns (GetAssignableRolesResponse);
|
||||||
|
// §role-grant-history — everyone who EVER held one of role_names for
|
||||||
|
// target_id (revoked grants included when include_deleted). Actor-gated:
|
||||||
|
// requested roles untargeted (all targets) or targeted at target_id.
|
||||||
|
rpc GetRoleGrantHistory (GetRoleGrantHistoryRequest) returns (GetRoleGrantHistoryResponse);
|
||||||
rpc UpdateUserInfo (UpdateUserInfoRequest) returns (UpdateUserInfoResponse);
|
rpc UpdateUserInfo (UpdateUserInfoRequest) returns (UpdateUserInfoResponse);
|
||||||
rpc GetScopeAncestors (GetScopeAncestorsRequest) returns (GetScopeAncestorsResponse);
|
rpc GetScopeAncestors (GetScopeAncestorsRequest) returns (GetScopeAncestorsResponse);
|
||||||
rpc GetScopeDescendants (GetScopeDescendantsRequest) returns (GetScopeDescendantsResponse);
|
rpc GetScopeDescendants (GetScopeDescendantsRequest) returns (GetScopeDescendantsResponse);
|
||||||
|
|
@ -554,3 +558,22 @@ message ClearUserSessionsResponse {
|
||||||
string message = 3;
|
string message = 3;
|
||||||
int32 cleared_count = 4;
|
int32 cleared_count = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetRoleGrantHistoryRequest {
|
||||||
|
string actor_token = 1;
|
||||||
|
repeated string role_names = 2;
|
||||||
|
string target_id = 3; // uuid of the entity (e.g. an advertiser)
|
||||||
|
bool include_deleted = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RoleGrantUser {
|
||||||
|
string user_id = 1;
|
||||||
|
string display_name = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetRoleGrantHistoryResponse {
|
||||||
|
bool success = 1;
|
||||||
|
ResultCode result_code = 2;
|
||||||
|
string message = 3;
|
||||||
|
repeated RoleGrantUser users = 4;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "st-peter-client"
|
name = "st-peter-client"
|
||||||
version = "0.2.3"
|
version = "0.2.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Official Rust client for st-peter (aura-users) — authentication over gRPC with a token-verify cache"
|
description = "Official Rust client for st-peter (aura-users) — authentication over gRPC with a token-verify cache"
|
||||||
repository = "https://git.awesomike.com/pub/st-peter-client"
|
repository = "https://git.awesomike.com/pub/st-peter-client"
|
||||||
|
|
|
||||||
|
|
@ -427,6 +427,35 @@ impl AdminClient {
|
||||||
Ok(resp.users)
|
Ok(resp.users)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// §role-grant-history — everyone who EVER held one of `role_names` for
|
||||||
|
/// `target_id` (revoked grants included when `include_deleted`). Gated by
|
||||||
|
/// the ACTOR's own token: any requested role untargeted (all targets) or
|
||||||
|
/// targeted at `target_id`; otherwise the server returns FORBIDDEN in the
|
||||||
|
/// response envelope. Returns (user_id, display_name), PII-free.
|
||||||
|
pub async fn get_role_grant_history(
|
||||||
|
&self,
|
||||||
|
actor_token: &str,
|
||||||
|
role_names: Vec<String>,
|
||||||
|
target_id: &str,
|
||||||
|
include_deleted: bool,
|
||||||
|
) -> Result<Vec<adminpb::RoleGrantUser>> {
|
||||||
|
let resp = self
|
||||||
|
.inner
|
||||||
|
.clone()
|
||||||
|
.get_role_grant_history(adminpb::GetRoleGrantHistoryRequest {
|
||||||
|
actor_token: actor_token.to_string(),
|
||||||
|
role_names,
|
||||||
|
target_id: target_id.to_string(),
|
||||||
|
include_deleted,
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
.into_inner();
|
||||||
|
if !resp.success {
|
||||||
|
return Err(Error::Rejected { code: resp.result_code, message: resp.message });
|
||||||
|
}
|
||||||
|
Ok(resp.users)
|
||||||
|
}
|
||||||
|
|
||||||
/// Assign a role to a user — targeted when `target_id` is set (the
|
/// Assign a role to a user — targeted when `target_id` is set (the
|
||||||
/// multi-tenancy device: e.g. `cms-content-editor` for one organization),
|
/// multi-tenancy device: e.g. `cms-content-editor` for one organization),
|
||||||
/// optionally time-bound via `expires_at`.
|
/// optionally time-bound via `expires_at`.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue