ssi_verification_methods_core/
controller.rs

1use iref::Iri;
2use ssi_claims_core::ProofValidationError;
3
4use crate::{ProofPurpose, ProofPurposes};
5
6/// Verification method controller.
7///
8/// A verification method controller stores the proof purposes for its
9/// controlled verification methods.
10/// The [`VerificationMethod::controller`] method returns
11/// an identifier for its controller, which can then be retrieved using a
12/// [`ControllerProvider`].
13///
14/// [`VerificationMethod::controller`]: crate::VerificationMethod::controller
15pub trait Controller {
16    /// Checks that the controller allows using the verification method for the
17    /// given proof purposes.
18    fn allows_verification_method(&self, id: &Iri, proof_purposes: ProofPurposes) -> bool;
19}
20
21impl<'a, T: Controller> Controller for &'a T {
22    fn allows_verification_method(&self, id: &Iri, proof_purposes: ProofPurposes) -> bool {
23        T::allows_verification_method(*self, id, proof_purposes)
24    }
25}
26
27/// Controller provider.
28///
29/// A provider is in charge of retrieving the verification method controllers
30/// from their identifiers.
31pub trait ControllerProvider {
32    /// Controller reference type.
33    type Controller<'a>: Controller
34    where
35        Self: 'a;
36
37    /// Returns the controller with the given identifier, if it can be found.
38    #[allow(async_fn_in_trait)]
39    async fn get_controller<'a>(
40        &'a self,
41        id: &'a Iri,
42    ) -> Result<Option<Self::Controller<'a>>, ControllerError>;
43
44    /// Returns the controller with the given identifier, or fails if it cannot
45    /// be found.
46    #[allow(async_fn_in_trait)]
47    async fn require_controller<'a>(
48        &'a self,
49        id: &'a Iri,
50    ) -> Result<Self::Controller<'a>, ControllerError> {
51        self.get_controller(id)
52            .await?
53            .ok_or_else(|| ControllerError::NotFound(id.to_string()))
54    }
55
56    /// Checks that the controller identified by `controller_id` allows the use
57    /// of the verification method `method_id` with the given proof purposes.
58    #[allow(async_fn_in_trait)]
59    async fn allows_verification_method<'a>(
60        &'a self,
61        controller_id: &'a Iri,
62        method_id: &'a Iri,
63        proof_purposes: ProofPurposes,
64    ) -> Result<bool, ControllerError> {
65        let controller = self.require_controller(controller_id).await?;
66        Ok(controller.allows_verification_method(method_id, proof_purposes))
67    }
68
69    /// Ensures that the controller identified by `controller_id` allows the use
70    /// of the verification method `method_id` with the given proof purposes.
71    ///
72    /// Contrarily to the [`allows_verification_method`] function, this function
73    /// returns an error if one of the input proof purposes is not allowed.
74    ///
75    /// [`allows_verification_method`]: ControllerProvider::allows_verification_method
76    #[allow(async_fn_in_trait)]
77    async fn ensure_allows_verification_method<'a>(
78        &'a self,
79        controller_id: &'a Iri,
80        method_id: &'a Iri,
81        proof_purpose: ProofPurpose,
82    ) -> Result<(), ProofValidationError> {
83        let controller = self.require_controller(controller_id).await?;
84        if controller.allows_verification_method(method_id, proof_purpose.into()) {
85            Ok(())
86        } else {
87            Err(ProofValidationError::InvalidKeyUse)
88        }
89    }
90}
91
92/// Error that can be returned by a controller provider.
93pub enum ControllerError {
94    /// Controller was not found.
95    ///
96    /// The controller identifier is provided as argument.
97    NotFound(String),
98
99    /// Invalid controller.
100    ///
101    /// The controller was found, but could not be interpreted as a valid
102    /// controller.
103    Invalid,
104
105    /// Unsupported controller identifier.
106    Unsupported(String),
107
108    /// Custom error from the controller provider.
109    InternalError(String),
110}
111
112impl From<ControllerError> for ProofValidationError {
113    fn from(value: ControllerError) -> Self {
114        match value {
115            ControllerError::NotFound(id) => Self::KeyControllerNotFound(id),
116            ControllerError::Invalid => Self::InvalidKeyController,
117            ControllerError::Unsupported(s) => Self::UnsupportedKeyController(s),
118            ControllerError::InternalError(e) => Self::Other(e),
119        }
120    }
121}