loong_kernel/
policy_ext.rs1use std::{collections::BTreeSet, sync::Arc};
2
3use crate::{
4 contracts::{Capability, CapabilityToken},
5 errors::PolicyError,
6 pack::VerticalPackManifest,
7};
8
9pub struct PolicyExtensionContext<'a> {
10 pub pack: &'a VerticalPackManifest,
11 pub token: &'a CapabilityToken,
12 pub now_epoch_s: u64,
13 pub required_capabilities: &'a BTreeSet<Capability>,
14 pub request_parameters: Option<&'a serde_json::Value>,
15}
16
17pub trait PolicyExtension: Send + Sync {
18 fn name(&self) -> &str;
19 fn authorize_extension(&self, context: &PolicyExtensionContext<'_>) -> Result<(), PolicyError>;
20}
21
22#[derive(Default)]
23pub struct PolicyExtensionChain {
24 extensions: Vec<Arc<dyn PolicyExtension>>,
25}
26
27impl PolicyExtensionChain {
28 #[must_use]
29 pub fn new() -> Self {
30 Self {
31 extensions: Vec::new(),
32 }
33 }
34
35 pub fn register<E: PolicyExtension + 'static>(&mut self, extension: E) {
36 self.extensions.push(Arc::new(extension));
37 }
38
39 pub fn authorize(&self, context: &PolicyExtensionContext<'_>) -> Result<(), PolicyError> {
40 for extension in &self.extensions {
41 extension.authorize_extension(context)?;
42 }
43 Ok(())
44 }
45}