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:
Michael Netshipise 2026-07-17 03:48:22 +02:00
parent 369d4d5580
commit b29beec9e9
3 changed files with 53 additions and 1 deletions

View File

@ -30,6 +30,10 @@ service AuthAdminService {
rpc GetRoleScopes (GetRoleScopesRequest) returns (GetRoleScopesResponse);
rpc GetUserWithRoles (GetUserWithRolesRequest) returns (GetUserWithRolesResponse);
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 GetScopeAncestors (GetScopeAncestorsRequest) returns (GetScopeAncestorsResponse);
rpc GetScopeDescendants (GetScopeDescendantsRequest) returns (GetScopeDescendantsResponse);
@ -554,3 +558,22 @@ message ClearUserSessionsResponse {
string message = 3;
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;
}

View File

@ -1,6 +1,6 @@
[package]
name = "st-peter-client"
version = "0.2.3"
version = "0.2.4"
edition = "2021"
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"

View File

@ -427,6 +427,35 @@ impl AdminClient {
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
/// multi-tenancy device: e.g. `cms-content-editor` for one organization),
/// optionally time-bound via `expires_at`.