use super::helpers::TrustTaskOutcome;
use serde_json::{Value, json};
use trust_tasks_rs::specs::auth::step_up::policy::v0_2 as policy;
use trust_tasks_rs::{RejectReason, TrustTask};
use vti_common::auth::AuthClaims;
use crate::operations::step_up_policy::{
SetPolicyError, effective_response, policy_from_payload, set_step_up_policy,
};
use crate::server::AppState;
use super::helpers::{reject_with, success_response};
fn policy_failure(code: &str, details: Option<Value>) -> RejectReason {
RejectReason::TaskFailed {
reason: code.to_string(),
details,
}
}
pub(super) async fn handle_set_step_up_policy(
state: &AppState,
auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
if !auth.is_super_admin() {
return reject_with(
&doc,
policy_failure("auth/step-up/policy:not_authorized", None),
);
}
let payload: policy::Payload = match serde_json::from_value(doc.payload.clone()) {
Ok(p) => p,
Err(e) => {
return reject_with(
&doc,
RejectReason::MalformedRequest {
reason: format!("payload parse: {e}"),
},
);
}
};
let requested = policy_from_payload(&payload);
match set_step_up_policy(&state.config, &state.acl_ks, requested).await {
Ok(effective) => success_response(&doc, effective_response(&effective)),
Err(SetPolicyError::UnknownOperation(op)) => reject_with(
&doc,
policy_failure(
"auth/step-up/policy:unknown_operation",
Some(json!({ "operation": op })),
),
),
Err(SetPolicyError::LockoutRefused(msg)) => reject_with(
&doc,
policy_failure(
"auth/step-up/policy:lockout_refused",
Some(json!({ "message": msg })),
),
),
Err(e @ (SetPolicyError::Store(_) | SetPolicyError::Persistence(_))) => reject_with(
&doc,
RejectReason::InternalError {
reason: e.to_string(),
},
),
}
}