use crate::{
Cades, ISSUER,
basic::SignerBinding,
counters::Paths,
credential::Complete,
source::{DocumentId, Node},
};
use structured_ltv::{
pki::{self, ParticipantError, ParticipantRequirements},
source::{Query, Source},
timestamp::TimestampPaths,
};
#[derive(Debug)]
pub enum Error {
Participants(ParticipantError<Node>),
Preservation {
property: Node,
kind: crate::preservation::Kind,
},
PreservationSource {
source: Node,
},
}
pub fn participants<'view, 'path, 'm, 'd, E, Q>(
signer: &'view SignerBinding<'_, 'm, 'd, 'path>,
counters: &'view Paths<'_, 'm, 'd, 'path>,
credentials: &'view Complete<'_, 'm, 'd, 'path, E>,
timestamps: &'view TimestampPaths<'view, '_, 'd, Node, DocumentId<'m, 'd>, (), Cades>,
query: &Q,
) -> Result<ParticipantRequirements<'view, 'd, Node, DocumentId<'m, 'd>, (), Cades>, Error>
where
Q: Query<Id = Node, Document = DocumentId<'m, 'd>, Generation = ()>,
'path: 'view,
'd: 'path,
{
let prepared = signer.prepared();
let selected = prepared.document().signer(prepared.signer()).map_err(|_| {
Error::Participants(ParticipantError::Foreign {
signature: Node::of(prepared.signer().span()),
})
})?;
if prepared.document().snapshot() != query.snapshot() {
return Err(Error::Participants(ParticipantError::Foreign {
signature: selected.node,
}));
}
query
.admit(selected.node, 1)
.map_err(|cause| Error::Participants(ParticipantError::Scope(cause)))?;
for required in prepared.preservation() {
query
.admit(required.property, 1)
.map_err(|cause| Error::Participants(ParticipantError::Scope(cause)))?;
if !required.kind.is_archive() && !required.kind.is_reference_timestamp() {
return Err(Error::Preservation {
property: required.property,
kind: required.kind,
});
}
}
if !prepared.preservation().is_empty() {
for finding in prepared.preservation_findings() {
query
.admit(finding.location.node, 1)
.map_err(|cause| Error::Participants(ParticipantError::Scope(cause)))?;
if finding.severity == crate::prepare::Severity::Required {
return Err(Error::PreservationSource {
source: finding.location.node,
});
}
}
}
pki::participants(ISSUER, signer, counters, credentials, timestamps, query)
.map_err(Error::Participants)
}