1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#[cfg(doc)]
use crate::Authenticator;

/// Pluggable trait for the [`Authenticator`] to do user interaction and verification.
#[async_trait::async_trait]
#[cfg_attr(any(test, feature = "testable"), mockall::automock)]
#[cfg_attr(any(test, feature = "testable"), allow(clippy::unused_async))] // Generated by the `mockall` macro.
pub trait UserValidationMethod {
    /// Check for user verification user a user gesture and confirmation if this operation passes
    /// both the user presence and user verification flags will be enabled
    async fn check_user_verification(&self) -> bool;

    /// Used when only the user's presence is required, not their verification. For that see
    /// `check_user_verification`. This will capture the user's consent to the operation.
    async fn check_user_presence(&self) -> bool;

    /// Indicates whether this type is capable of testing user presence.
    fn is_presence_enabled(&self) -> bool;

    /// Indicates that this type is capable of verifying the user within itself.
    /// For example, devices with UI, biometrics fall into this category.
    ///
    /// If `Some(true)`, it indicates that the device is capable of user verification
    /// within itself and has been configured.
    ///
    /// If Some(false), it indicates that the device is capable of user verification
    /// within itself and has not been yet configured. For example, a biometric device that has not
    /// yet been configured will return this parameter set to false.
    ///
    /// If `None`, it indicates that the device is not capable of user verification within itself.
    ///
    /// A device that can only do Client PIN will set this to `None`.
    ///
    /// If a device is capable of verifying the user within itself as well as able to do Client PIN,
    ///  it will return both `Some` and the Client PIN option.
    fn is_verification_enabled(&self) -> Option<bool>;
}

#[cfg(any(test, feature = "testable"))]
impl MockUserValidationMethod {
    /// Sets up the mock for returning true for the verification.
    pub fn verified_user(times: usize) -> Self {
        let mut user_mock = MockUserValidationMethod::new();
        user_mock
            .expect_is_verification_enabled()
            .returning(|| Some(true))
            .times(times);
        user_mock
            .expect_check_user_verification()
            .returning(|| Box::pin(async { true }))
            .times(times);
        user_mock
    }
}