use serde::{Deserialize, Serialize};
use crate::wac::conditions::{ConditionOutcome, RequestContext};
use crate::wac::document::{get_ids, IdOrIds};
use crate::wac::evaluator::GroupMembership;
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct ClientConditionBody {
#[serde(rename = "acl:client", default, skip_serializing_if = "Option::is_none")]
pub client: Option<IdOrIds>,
#[serde(
rename = "acl:clientGroup",
default,
skip_serializing_if = "Option::is_none"
)]
pub client_group: Option<IdOrIds>,
#[serde(
rename = "acl:clientClass",
default,
skip_serializing_if = "Option::is_none"
)]
pub client_class: Option<IdOrIds>,
}
#[derive(Debug, Default, Clone, Copy)]
pub struct ClientConditionEvaluator;
impl ClientConditionEvaluator {
pub fn evaluate(
&self,
body: &ClientConditionBody,
ctx: &RequestContext<'_>,
groups: &dyn GroupMembership,
) -> ConditionOutcome {
for cls in get_ids(&body.client_class) {
if cls == "foaf:Agent" || cls == "http://xmlns.com/foaf/0.1/Agent" {
return ConditionOutcome::Satisfied;
}
}
if let Some(cid) = ctx.client_id {
for c in get_ids(&body.client) {
if c == cid {
return ConditionOutcome::Satisfied;
}
}
for g in get_ids(&body.client_group) {
if groups.is_member(g, cid) {
return ConditionOutcome::Satisfied;
}
}
}
ConditionOutcome::Denied
}
}