Skip to main content

liminal_server/services/site/
executor_run.rs

1//! The approved-draft executor: approvals are checked, then committed once.
2
3use super::{AtomicDraftStore, SiteDraftStore, storage_error};
4use crate::auth_lys::live::drafts::{ApprovalTransition, DraftError};
5use lys_pass::drafts::{ApprovedDraft, Execution, Executor};
6use std::collections::BTreeSet;
7
8impl Executor for SiteDraftStore {
9    type Error = DraftError;
10    fn receipt(&self, draft: &str) -> Result<Option<Execution>, DraftError> {
11        AtomicDraftStore::receipt(self, draft)
12    }
13    fn execute_and_record(&mut self, draft: &ApprovedDraft) -> Result<Execution, DraftError> {
14        let evidence = self.approval(draft)?;
15        let needed = match evidence.mode {
16            crate::auth_lys::GrantMode::ByDraft => 1,
17            crate::auth_lys::GrantMode::ByTwo => 2,
18            crate::auth_lys::GrantMode::Outright => return Err(DraftError::ApprovalUnavailable),
19        };
20        let bound = self
21            .lifecycle
22            .site_bindings()
23            .map_err(storage_error)?
24            .limits
25            .text_bytes
26            .get();
27        let mut people = BTreeSet::new();
28        if evidence.draft != draft.id
29            || evidence.digest != draft.request_digest
30            || evidence.approved_by.len() != needed
31            || evidence.approved_by.iter().any(|person| {
32                person.is_empty()
33                    || person.len() > bound
34                    || person.chars().any(char::is_control)
35                    || !people.insert(person)
36            })
37        {
38            return Err(DraftError::ApprovalUnavailable);
39        }
40        self.commit(
41            draft,
42            &ApprovalTransition {
43                draft: draft.id.clone(),
44                digest: draft.request_digest.clone(),
45                approved_by: evidence.approved_by,
46                executed_at_ms: self.at_ms,
47            },
48        )
49    }
50}