mls_rs/identity/
basic.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// Copyright by contributors to this project.
3// SPDX-License-Identifier: (Apache-2.0 OR MIT)
4
5use crate::{identity::CredentialType, identity::SigningIdentity, time::MlsTime};
6use alloc::vec;
7use alloc::vec::Vec;
8pub use mls_rs_core::identity::BasicCredential;
9use mls_rs_core::{
10    error::IntoAnyError,
11    extension::ExtensionList,
12    identity::{IdentityProvider, MemberValidationContext},
13};
14
15#[derive(Debug)]
16#[cfg_attr(feature = "std", derive(thiserror::Error))]
17#[cfg_attr(feature = "std", error("unsupported credential type found: {0:?}"))]
18/// Error returned in the event that a non-basic
19/// credential is passed to a [`BasicIdentityProvider`].
20pub struct BasicIdentityProviderError(CredentialType);
21
22impl IntoAnyError for BasicIdentityProviderError {
23    #[cfg(feature = "std")]
24    fn into_dyn_error(self) -> Result<Box<dyn std::error::Error + Send + Sync>, Self> {
25        Ok(self.into())
26    }
27}
28
29impl BasicIdentityProviderError {
30    pub fn credential_type(&self) -> CredentialType {
31        self.0
32    }
33}
34
35#[derive(Clone, Debug, Default)]
36/// An always-valid identity provider that works with [`BasicCredential`].
37///
38/// # Warning
39///
40/// This provider always returns `true` for `validate` as long as the
41/// [`SigningIdentity`] used contains a [`BasicCredential`]. It is only
42/// recommended to use this provider for testing purposes.
43pub struct BasicIdentityProvider;
44
45impl BasicIdentityProvider {
46    pub fn new() -> Self {
47        Self
48    }
49}
50
51fn resolve_basic_identity(
52    signing_id: &SigningIdentity,
53) -> Result<&BasicCredential, BasicIdentityProviderError> {
54    signing_id
55        .credential
56        .as_basic()
57        .ok_or_else(|| BasicIdentityProviderError(signing_id.credential.credential_type()))
58}
59
60#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
61#[cfg_attr(mls_build_async, maybe_async::must_be_async)]
62impl IdentityProvider for BasicIdentityProvider {
63    type Error = BasicIdentityProviderError;
64
65    async fn validate_member(
66        &self,
67        signing_identity: &SigningIdentity,
68        _timestamp: Option<MlsTime>,
69        _context: MemberValidationContext<'_>,
70    ) -> Result<(), Self::Error> {
71        resolve_basic_identity(signing_identity).map(|_| ())
72    }
73
74    async fn validate_external_sender(
75        &self,
76        signing_identity: &SigningIdentity,
77        _timestamp: Option<MlsTime>,
78        _extensions: Option<&ExtensionList>,
79    ) -> Result<(), Self::Error> {
80        resolve_basic_identity(signing_identity).map(|_| ())
81    }
82
83    async fn identity(
84        &self,
85        signing_identity: &SigningIdentity,
86        _extensions: &ExtensionList,
87    ) -> Result<Vec<u8>, Self::Error> {
88        resolve_basic_identity(signing_identity).map(|b| b.identifier.to_vec())
89    }
90
91    async fn valid_successor(
92        &self,
93        predecessor: &SigningIdentity,
94        successor: &SigningIdentity,
95        _extensions: &ExtensionList,
96    ) -> Result<bool, Self::Error> {
97        Ok(resolve_basic_identity(predecessor)? == resolve_basic_identity(successor)?)
98    }
99
100    fn supported_types(&self) -> Vec<CredentialType> {
101        vec![BasicCredential::credential_type()]
102    }
103}