Sync public tree to 4336e3b

This commit is contained in:
Michel Paulissen 2026-07-04 14:11:59 +02:00
parent 009a9619e1
commit d25447e17d
5 changed files with 414 additions and 6 deletions

View file

@ -28,6 +28,11 @@ const DEBUG_CONTROL_READ_BYTES: u64 = 1024;
#[serde(tag = "type", rename_all = "snake_case")]
pub enum CoordinatorRequest {
Ping,
AuthStatus {
tenant: String,
project: String,
actor_user: String,
},
AdminStatus {
tenant: String,
actor_user: String,
@ -489,6 +494,19 @@ pub enum CoordinatorResponse {
Pong {
epoch: u64,
},
AuthStatus {
tenant: TenantId,
project: ProjectId,
actor: UserId,
authenticated: bool,
account_status: String,
suspended: bool,
disabled: bool,
sanitized_reason: Option<String>,
next_actions: Vec<String>,
private_moderation_details_exposed: bool,
signup_failure_details_exposed: bool,
},
AdminStatus {
tenant: TenantId,
actor: UserId,
@ -781,6 +799,40 @@ impl CoordinatorService {
CoordinatorRequest::Ping => Ok(CoordinatorResponse::Pong {
epoch: self.coordinator.coordinator_epoch(),
}),
CoordinatorRequest::AuthStatus {
tenant,
project,
actor_user,
} => {
let tenant = TenantId::new(tenant);
let project = ProjectId::new(project);
let actor = UserId::new(actor_user);
let suspended = self.coordinator.tenant_suspended(&tenant);
let account_status = if suspended { "suspended" } else { "active" }.to_owned();
let sanitized_reason =
suspended.then(|| "account or tenant is suspended by hosted policy".to_owned());
let next_actions = if suspended {
vec![
"disasmer auth status --json".to_owned(),
"contact the hosted operator or use a self-hosted coordinator".to_owned(),
]
} else {
Vec::new()
};
Ok(CoordinatorResponse::AuthStatus {
tenant,
project,
actor,
authenticated: true,
account_status,
suspended,
disabled: false,
sanitized_reason,
next_actions,
private_moderation_details_exposed: false,
signup_failure_details_exposed: false,
})
}
CoordinatorRequest::AdminStatus { tenant, actor_user } => {
let tenant = TenantId::new(tenant);
let actor = UserId::new(actor_user);
@ -2909,6 +2961,39 @@ mod tests {
fn service_reports_and_enforces_public_admin_tenant_suspension() {
let mut service = CoordinatorService::new(7);
let CoordinatorResponse::AuthStatus {
tenant,
project,
actor,
authenticated,
account_status,
suspended,
disabled,
sanitized_reason,
private_moderation_details_exposed,
signup_failure_details_exposed,
..
} = service
.handle_request(CoordinatorRequest::AuthStatus {
tenant: "tenant".to_owned(),
project: "project".to_owned(),
actor_user: "user".to_owned(),
})
.unwrap()
else {
panic!("expected auth status");
};
assert_eq!(tenant, TenantId::from("tenant"));
assert_eq!(project, ProjectId::from("project"));
assert_eq!(actor, UserId::from("user"));
assert!(authenticated);
assert_eq!(account_status, "active");
assert!(!suspended);
assert!(!disabled);
assert!(sanitized_reason.is_none());
assert!(!private_moderation_details_exposed);
assert!(!signup_failure_details_exposed);
let CoordinatorResponse::AdminStatus {
tenant,
actor,
@ -2957,6 +3042,38 @@ mod tests {
};
assert!(suspended);
let CoordinatorResponse::AuthStatus {
account_status,
suspended,
disabled,
sanitized_reason,
next_actions,
private_moderation_details_exposed,
signup_failure_details_exposed,
..
} = service
.handle_request(CoordinatorRequest::AuthStatus {
tenant: "tenant".to_owned(),
project: "project".to_owned(),
actor_user: "user".to_owned(),
})
.unwrap()
else {
panic!("expected suspended auth status");
};
assert_eq!(account_status, "suspended");
assert!(suspended);
assert!(!disabled);
assert_eq!(
sanitized_reason.as_deref(),
Some("account or tenant is suspended by hosted policy")
);
assert!(next_actions
.iter()
.any(|action| action.contains("hosted operator")));
assert!(!private_moderation_details_exposed);
assert!(!signup_failure_details_exposed);
let create = service
.handle_request(CoordinatorRequest::CreateProject {
tenant: "tenant".to_owned(),