Skip to content

Commit 006f090

Browse files
committed
Merge branch 'refactor-builtin-policies'
2 parents 9ea1a46 + 495c5ac commit 006f090

6 files changed

Lines changed: 99 additions & 23 deletions

File tree

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/policy/builtin.rs

Lines changed: 86 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,94 @@
1+
//! Built-in policies for Sigsum.
2+
//!
3+
//! This module contains all the included built-in policies. These can be accessed
4+
//! and used directly as public statics, or looked up at runtime by name via
5+
//! [`Policy::builtin`].
6+
7+
use std::ops::Deref;
8+
use std::sync::LazyLock;
9+
110
use super::Policy;
211

3-
const SIGSUM_TEST1_2025: &str = include_str!("sigsum-test1-2025.builtin-policy");
4-
const SIGSUM_TEST2_2025: &str = include_str!("sigsum-test2-2025.builtin-policy");
5-
const SIGSUM_TEST_2025_3: &str = include_str!("sigsum-test-2025-3.builtin-policy");
6-
const SIGSUM_GENERIC_2025_1: &str = include_str!("sigsum-generic-2025-1.builtin-policy");
7-
8-
impl Policy {
9-
pub fn builtin(name: &str) -> Option<Self> {
10-
match name {
11-
"sigsum-test1-2025" => Some(Policy::parse(SIGSUM_TEST1_2025).unwrap()),
12-
"sigsum-test2-2025" => Some(Policy::parse(SIGSUM_TEST2_2025).unwrap()),
13-
"sigsum-test-2025-3" => Some(Policy::parse(SIGSUM_TEST_2025_3).unwrap()),
14-
"sigsum-generic-2025-1" => Some(Policy::parse(SIGSUM_GENERIC_2025_1).unwrap()),
15-
_ => None,
16-
}
12+
/// A built-in policy with a given name.
13+
///
14+
/// The user facing name of this policy can be accessed via the public `name` field.
15+
/// This struct implements `Deref<Target=Policy>`, so using it as a [`Policy`] becomes
16+
/// transparent.
17+
///
18+
/// This policy is parsed and lazily initialized on first use.
19+
pub struct BuiltInPolicy {
20+
/// The user-friendly name of the built-in policy.
21+
pub name: &'static str,
22+
23+
policy: LazyLock<Policy>,
24+
}
25+
26+
impl BuiltInPolicy {
27+
/// Returns the policy for this built-in policy. Can also be accessed
28+
/// via the `Deref` implementation.
29+
pub fn policy(&self) -> &Policy {
30+
&self.policy
1731
}
1832
}
1933

20-
#[cfg(test)]
21-
mod tests {
22-
use super::*;
34+
impl Deref for BuiltInPolicy {
35+
type Target = Policy;
2336

24-
#[test]
25-
fn parse_builtin_policies() {
26-
assert!(Policy::builtin("sigsum-test1-2025").is_some());
27-
assert!(Policy::builtin("sigsum-test2-2025").is_some());
28-
assert!(Policy::builtin("sigsum-test-2025-3").is_some());
29-
assert!(Policy::builtin("sigsum-generic-2025-1").is_some());
37+
fn deref(&self) -> &Self::Target {
38+
self.policy()
3039
}
3140
}
41+
42+
macro_rules! define_builtin_policies {
43+
($(
44+
$const_name:ident = $policy_name:literal
45+
),* $(,)?) => {
46+
// Define the static constants
47+
$(
48+
pub static $const_name: BuiltInPolicy = BuiltInPolicy {
49+
name: $policy_name,
50+
policy: LazyLock::new(|| {
51+
Policy::parse(include_str!(concat!(
52+
"../../builtin-policies/",
53+
$policy_name,
54+
".builtin-policy"
55+
)))
56+
.expect(concat!("Failed to parse built-in policy: ", $policy_name))
57+
}),
58+
};
59+
)*
60+
61+
/// Returns a built-in policy by name, if one exists.
62+
/// Only intended to be used internally by [`Policy::builtin`].
63+
pub(crate) fn builtin(name: &str) -> Option<&'static Policy> {
64+
match name {
65+
$(
66+
$policy_name => Some(&$const_name.policy()),
67+
)*
68+
_ => None,
69+
}
70+
}
71+
72+
// Auto-generate tests. Asserts that all policies parse without panicking
73+
#[cfg(test)]
74+
mod tests {
75+
use super::*;
76+
77+
#[test]
78+
fn parse_builtin_policies() {
79+
$(
80+
let _policy = $const_name.policy();
81+
)*
82+
}
83+
}
84+
};
85+
}
86+
87+
// All built-in policies defined here in one single place.
88+
// Multiple invocations not possible since this invocation emits the `builtin` lookup function.
89+
define_builtin_policies! {
90+
SIGSUM_TEST1_2025 = "sigsum-test1-2025",
91+
SIGSUM_TEST2_2025 = "sigsum-test2-2025",
92+
SIGSUM_TEST_2025_3 = "sigsum-test-2025-3",
93+
SIGSUM_GENERIC_2025_1 = "sigsum-generic-2025-1",
94+
}

src/policy/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use std::collections::HashMap;
33
use crate::crypto::{Hash, PublicKey};
44

55
mod builtin;
6+
pub use builtin::*;
7+
68
mod parsing;
79

810
pub use parsing::ParsePolicyError;
@@ -11,6 +13,9 @@ pub use parsing::ParsePolicyError;
1113
///
1214
/// The Sigsum policy dictates if a signed tree head is considered valid (and by extension, if a
1315
/// Sigsum signature is valid).
16+
///
17+
/// This library contains a bunch of built-in policies. They can be accessed as statics
18+
/// in this module, or looked up at runtime via [`Policy::builtin`].
1419
#[derive(Debug, Eq, PartialEq)]
1520
pub struct Policy {
1621
// logs keeps the list of log keys and URLs indexed by keyhash.
@@ -57,6 +62,14 @@ impl<'a> Iterator for Logs<'a> {
5762
}
5863

5964
impl Policy {
65+
/// Returns a built-in policy by name, if one exists.
66+
///
67+
/// All built-in policies are also exposed as statics directly in the
68+
/// [`policy`](crate::policy) module.
69+
pub fn builtin(name: &str) -> Option<&'static Self> {
70+
builtin::builtin(name)
71+
}
72+
6073
pub fn logs(&self) -> Logs<'_> {
6174
Logs {
6275
inner: self.logs.iter(),

0 commit comments

Comments
 (0)