Skip to main content

authkestra_devsig/
builder.rs

1use crate::{config::VerifierConfig, jwks::IssuerJwks, replay::ReplayStore};
2use std::sync::Arc;
3/// Marker type for a missing dependency in the builder.
4pub struct Missing;
5
6/// Device-bound signature verifier instance holding required configuration and state.
7#[derive(Clone)]
8pub struct DevSig<R = Missing> {
9    /// Verifier Configuration.
10    pub config: VerifierConfig,
11    /// JWKS of the issuer.
12    pub jwks: Arc<IssuerJwks>,
13    /// Replay store backend.
14    pub replay_store: R,
15}
16
17impl DevSig<Missing> {
18    /// Create a new DevSig builder enforcing typestates for required dependencies.
19    pub fn builder() -> DevSigBuilder<Missing> {
20        DevSigBuilder {
21            config: None,
22            jwks: None,
23            replay_store: Missing,
24        }
25    }
26}
27
28/// A typestate builder for `DevSig`.
29pub struct DevSigBuilder<R> {
30    config: Option<VerifierConfig>,
31    jwks: Option<Arc<IssuerJwks>>,
32    replay_store: R,
33}
34
35impl<R> DevSigBuilder<R> {
36    /// Set the verifier configuration.
37    pub fn config(mut self, config: VerifierConfig) -> Self {
38        self.config = Some(config);
39        self
40    }
41
42    /// Set the issuer JWKS.
43    pub fn jwks(mut self, jwks: Arc<IssuerJwks>) -> Self {
44        self.jwks = Some(jwks);
45        self
46    }
47}
48
49impl DevSigBuilder<Missing> {
50    /// Set the replay store, advancing the typestate.
51    pub fn replay_store(
52        self,
53        replay_store: Arc<dyn ReplayStore>,
54    ) -> DevSigBuilder<Arc<dyn ReplayStore>> {
55        DevSigBuilder {
56            config: self.config,
57            jwks: self.jwks,
58            replay_store,
59        }
60    }
61}
62
63impl DevSigBuilder<Arc<dyn ReplayStore>> {
64    /// Build the `DevSig` instance. Panics if `config` or `jwks` was not provided.
65    pub fn build(self) -> DevSig<Arc<dyn ReplayStore>> {
66        DevSig {
67            config: self.config.expect("config must be set on DevSigBuilder"),
68            jwks: self.jwks.expect("jwks must be set on DevSigBuilder"),
69            replay_store: self.replay_store,
70        }
71    }
72}