use crate::{AdmissionResult, EffectResult, OperationAction};
use bcx_core::{CapabilityRef, CheckpointId, PolicyId, StatementId, SubjectId, ValidationError};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum StatementKind {
Intent,
Admission,
Effect,
Delegation,
Revocation,
Checkpoint,
Contradiction,
}
#[derive(Debug, Eq, PartialEq)]
pub struct Intent {
statement_id: StatementId,
subject: SubjectId,
action: OperationAction,
}
impl Intent {
#[must_use]
pub const fn new(
statement_id: StatementId,
subject: SubjectId,
action: OperationAction,
) -> Self {
Self {
statement_id,
subject,
action,
}
}
#[must_use]
pub const fn kind(&self) -> StatementKind {
StatementKind::Intent
}
#[must_use]
pub const fn statement_id(&self) -> &StatementId {
&self.statement_id
}
#[must_use]
pub const fn subject(&self) -> &SubjectId {
&self.subject
}
#[must_use]
pub const fn action(&self) -> OperationAction {
self.action
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Admission {
statement_id: StatementId,
intent_id: StatementId,
policy_id: PolicyId,
result: AdmissionResult,
}
impl Admission {
pub fn new(
statement_id: StatementId,
intent_id: StatementId,
policy_id: PolicyId,
result: AdmissionResult,
) -> Result<Self, ValidationError> {
ensure_distinct(&statement_id, &intent_id)?;
Ok(Self {
statement_id,
intent_id,
policy_id,
result,
})
}
#[must_use]
pub const fn kind(&self) -> StatementKind {
StatementKind::Admission
}
#[must_use]
pub const fn statement_id(&self) -> &StatementId {
&self.statement_id
}
#[must_use]
pub const fn intent_id(&self) -> &StatementId {
&self.intent_id
}
#[must_use]
pub const fn policy_id(&self) -> &PolicyId {
&self.policy_id
}
#[must_use]
pub const fn result(&self) -> AdmissionResult {
self.result
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Effect {
statement_id: StatementId,
intent_id: StatementId,
result: EffectResult,
}
impl Effect {
pub fn new(
statement_id: StatementId,
intent_id: StatementId,
result: EffectResult,
) -> Result<Self, ValidationError> {
ensure_distinct(&statement_id, &intent_id)?;
Ok(Self {
statement_id,
intent_id,
result,
})
}
#[must_use]
pub const fn kind(&self) -> StatementKind {
StatementKind::Effect
}
#[must_use]
pub const fn statement_id(&self) -> &StatementId {
&self.statement_id
}
#[must_use]
pub const fn intent_id(&self) -> &StatementId {
&self.intent_id
}
#[must_use]
pub const fn result(&self) -> EffectResult {
self.result
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Delegation {
statement_id: StatementId,
from_subject: SubjectId,
to_subject: SubjectId,
capability: CapabilityRef,
}
impl Delegation {
pub fn new(
statement_id: StatementId,
from_subject: SubjectId,
to_subject: SubjectId,
capability: CapabilityRef,
) -> Result<Self, ValidationError> {
if from_subject == to_subject {
return Err(ValidationError::Malformed);
}
Ok(Self {
statement_id,
from_subject,
to_subject,
capability,
})
}
#[must_use]
pub const fn kind(&self) -> StatementKind {
StatementKind::Delegation
}
#[must_use]
pub const fn statement_id(&self) -> &StatementId {
&self.statement_id
}
#[must_use]
pub const fn from_subject(&self) -> &SubjectId {
&self.from_subject
}
#[must_use]
pub const fn to_subject(&self) -> &SubjectId {
&self.to_subject
}
#[must_use]
pub const fn capability(&self) -> CapabilityRef {
self.capability
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Revocation {
statement_id: StatementId,
target_id: StatementId,
authority: CapabilityRef,
}
impl Revocation {
pub fn new(
statement_id: StatementId,
target_id: StatementId,
authority: CapabilityRef,
) -> Result<Self, ValidationError> {
ensure_distinct(&statement_id, &target_id)?;
Ok(Self {
statement_id,
target_id,
authority,
})
}
#[must_use]
pub const fn kind(&self) -> StatementKind {
StatementKind::Revocation
}
#[must_use]
pub const fn statement_id(&self) -> &StatementId {
&self.statement_id
}
#[must_use]
pub const fn target_id(&self) -> &StatementId {
&self.target_id
}
#[must_use]
pub const fn authority(&self) -> CapabilityRef {
self.authority
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Checkpoint {
statement_id: StatementId,
checkpoint_id: CheckpointId,
subject: SubjectId,
}
impl Checkpoint {
#[must_use]
pub const fn new(
statement_id: StatementId,
checkpoint_id: CheckpointId,
subject: SubjectId,
) -> Self {
Self {
statement_id,
checkpoint_id,
subject,
}
}
#[must_use]
pub const fn kind(&self) -> StatementKind {
StatementKind::Checkpoint
}
#[must_use]
pub const fn statement_id(&self) -> &StatementId {
&self.statement_id
}
#[must_use]
pub const fn checkpoint_id(&self) -> &CheckpointId {
&self.checkpoint_id
}
#[must_use]
pub const fn subject(&self) -> &SubjectId {
&self.subject
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Contradiction {
statement_id: StatementId,
disputed_id: StatementId,
contradicts_id: StatementId,
}
impl Contradiction {
pub fn new(
statement_id: StatementId,
disputed_id: StatementId,
contradicts_id: StatementId,
) -> Result<Self, ValidationError> {
ensure_distinct(&statement_id, &disputed_id)?;
ensure_distinct(&statement_id, &contradicts_id)?;
ensure_distinct(&disputed_id, &contradicts_id)?;
Ok(Self {
statement_id,
disputed_id,
contradicts_id,
})
}
#[must_use]
pub const fn kind(&self) -> StatementKind {
StatementKind::Contradiction
}
#[must_use]
pub const fn statement_id(&self) -> &StatementId {
&self.statement_id
}
#[must_use]
pub const fn disputed_id(&self) -> &StatementId {
&self.disputed_id
}
#[must_use]
pub const fn contradicts_id(&self) -> &StatementId {
&self.contradicts_id
}
}
fn ensure_distinct(left: &StatementId, right: &StatementId) -> Result<(), ValidationError> {
if left == right {
Err(ValidationError::Malformed)
} else {
Ok(())
}
}