use serde::{Deserialize, Serialize};
use crate::membership::{CONTRACT_VERSION, GrantLog, Refused, Subject, Verdict, check};
use crate::rights::Resource;
pub const NO_CURRENT_GRANT: &str = "membership_no_current_grant";
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema), schema(as = MembershipAdmissionRequest))]
pub struct AdmissionRequest {
pub contract: u32,
pub log: GrantLog,
pub workspace: Resource,
pub subject: Subject,
pub at_least: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema), schema(as = MembershipAdmissionDecision))]
pub struct AdmissionDecision {
pub contract: u32,
pub log: GrantLog,
pub request: AdmissionRequest,
pub revision: Option<u64>,
pub verdict: Verdict,
}
pub fn validate(request: &AdmissionRequest, served: &GrantLog) -> Result<(), Refused> {
check(
request.contract,
&request.log,
served,
&[
("workspace kind", request.workspace.kind.as_str()),
("workspace id", request.workspace.id.as_str()),
("subject id", request.subject.id.as_str()),
("subject kind", request.subject.kind.as_str()),
],
)
}
#[must_use]
pub fn refused_before_lookup(
request: &AdmissionRequest,
served: &GrantLog,
name: &str,
reason: &str,
) -> AdmissionDecision {
AdmissionDecision {
contract: CONTRACT_VERSION,
log: served.clone(),
request: request.clone(),
revision: None,
verdict: Verdict::Refused {
refusal: name.to_owned(),
reason: reason.to_owned(),
},
}
}