use crate::model::{
artifacts::ArtifactChecksumRecord,
inventory::InventoryRecord,
membership::{MembershipObservation, MembershipObservationRequest},
};
use thiserror::Error;
#[derive(Clone, Debug)]
pub struct MembershipView<'a> {
observation: &'a MembershipObservation,
selected_targets: &'a [String],
}
impl MembershipView<'_> {
#[must_use]
pub const fn request(&self) -> &ArtifactChecksumRecord {
&self.observation.request
}
#[must_use]
pub const fn inventory(&self) -> &InventoryRecord {
&self.observation.inventory
}
#[must_use]
pub const fn selected_targets(&self) -> &[String] {
self.selected_targets
}
#[must_use]
pub const fn revision(&self) -> Option<&ArtifactChecksumRecord> {
self.observation.revision.as_ref()
}
#[must_use]
pub const fn evidence(&self) -> &ArtifactChecksumRecord {
&self.observation.evidence
}
#[must_use]
pub const fn remote_observations(&self) -> u32 {
self.observation.remote_observations
}
}
pub fn validate<'a>(
request: &'a MembershipObservationRequest<'_>,
observation: &'a MembershipObservation,
) -> Result<MembershipView<'a>, MembershipError> {
let digest = request.digest();
let binding = request.binding();
super::observed_context::admit_request_context(
&digest,
&observation.request,
binding,
&observation.context,
MembershipError::RequestMismatch,
MembershipError::ContextMismatch,
)?;
if observation.inventory != *request.inventory() {
return Err(MembershipError::InventoryMismatch);
}
super::observed_context::admit_limit(
request.max_remote_observations(),
observation.remote_observations,
|limit, reported| MembershipError::ObservationLimitExceeded { limit, reported },
)?;
Ok(MembershipView {
observation,
selected_targets: request.selected_targets(),
})
}
#[derive(Debug, Eq, Error, PartialEq)]
pub enum MembershipError {
#[error("membership request identity mismatch")]
RequestMismatch,
#[error("membership observed {0} mismatch")]
ContextMismatch(&'static str),
#[error("membership inventory mismatch")]
InventoryMismatch,
#[error("membership reports {reported} observations above ceiling {limit}")]
ObservationLimitExceeded {
limit: u32,
reported: u32,
},
}
#[cfg(test)]
mod tests;