bitwarden_core/auth/
auth_client.rs

1#[cfg(feature = "internal")]
2use bitwarden_crypto::{
3    CryptoError, DeviceKey, EncString, Kdf, TrustDeviceResponse, UnsignedSharedKey,
4};
5
6#[cfg(feature = "secrets")]
7use crate::auth::login::{login_access_token, AccessTokenLoginRequest, AccessTokenLoginResponse};
8#[cfg(feature = "internal")]
9use crate::{
10    auth::{
11        auth_request::{approve_auth_request, new_auth_request, ApproveAuthRequestError},
12        key_connector::{make_key_connector_keys, KeyConnectorResponse},
13        login::{
14            login_api_key, login_password, send_two_factor_email, ApiKeyLoginRequest,
15            ApiKeyLoginResponse, NewAuthRequestResponse, PasswordLoginRequest,
16            PasswordLoginResponse, PreloginError, TwoFactorEmailError, TwoFactorEmailRequest,
17        },
18        password::{
19            password_strength, satisfies_policy, validate_password, validate_password_user_key,
20            MasterPasswordPolicyOptions,
21        },
22        pin::validate_pin,
23        register::{make_register_keys, register},
24        tde::{make_register_tde_keys, RegisterTdeKeyResponse},
25        AuthRequestResponse, AuthValidateError, RegisterError, RegisterKeyResponse,
26        RegisterRequest,
27    },
28    client::encryption_settings::EncryptionSettingsError,
29};
30use crate::{
31    auth::{login::LoginError, renew::renew_token},
32    Client,
33};
34
35pub struct AuthClient {
36    pub(crate) client: crate::Client,
37}
38
39impl AuthClient {
40    pub async fn renew_token(&self) -> Result<(), LoginError> {
41        renew_token(&self.client.internal).await
42    }
43
44    #[cfg(feature = "secrets")]
45    pub async fn login_access_token(
46        &self,
47        input: &AccessTokenLoginRequest,
48    ) -> Result<AccessTokenLoginResponse, LoginError> {
49        login_access_token(&self.client, input).await
50    }
51}
52
53#[cfg(feature = "internal")]
54impl AuthClient {
55    pub fn password_strength(
56        &self,
57        password: String,
58        email: String,
59        additional_inputs: Vec<String>,
60    ) -> u8 {
61        password_strength(password, email, additional_inputs)
62    }
63
64    pub fn satisfies_policy(
65        &self,
66        password: String,
67        strength: u8,
68        policy: &MasterPasswordPolicyOptions,
69    ) -> bool {
70        satisfies_policy(password, strength, policy)
71    }
72
73    pub fn make_register_keys(
74        &self,
75        email: String,
76        password: String,
77        kdf: Kdf,
78    ) -> Result<RegisterKeyResponse, CryptoError> {
79        make_register_keys(email, password, kdf)
80    }
81
82    pub fn make_register_tde_keys(
83        &self,
84        email: String,
85        org_public_key: String,
86        remember_device: bool,
87    ) -> Result<RegisterTdeKeyResponse, EncryptionSettingsError> {
88        make_register_tde_keys(&self.client, email, org_public_key, remember_device)
89    }
90
91    pub fn make_key_connector_keys(&self) -> Result<KeyConnectorResponse, CryptoError> {
92        let mut rng = rand::thread_rng();
93        make_key_connector_keys(&mut rng)
94    }
95
96    pub async fn register(&self, input: &RegisterRequest) -> Result<(), RegisterError> {
97        register(&self.client, input).await
98    }
99
100    pub async fn prelogin(&self, email: String) -> Result<Kdf, PreloginError> {
101        use crate::auth::login::prelogin;
102
103        prelogin(&self.client, email).await
104    }
105
106    pub async fn login_password(
107        &self,
108        input: &PasswordLoginRequest,
109    ) -> Result<PasswordLoginResponse, LoginError> {
110        login_password(&self.client, input).await
111    }
112
113    pub async fn login_api_key(
114        &self,
115        input: &ApiKeyLoginRequest,
116    ) -> Result<ApiKeyLoginResponse, LoginError> {
117        login_api_key(&self.client, input).await
118    }
119
120    pub async fn send_two_factor_email(
121        &self,
122        tf: &TwoFactorEmailRequest,
123    ) -> Result<(), TwoFactorEmailError> {
124        send_two_factor_email(&self.client, tf).await
125    }
126
127    pub fn validate_password(
128        &self,
129        password: String,
130        password_hash: String,
131    ) -> Result<bool, AuthValidateError> {
132        validate_password(&self.client, password, password_hash)
133    }
134
135    pub fn validate_password_user_key(
136        &self,
137        password: String,
138        encrypted_user_key: String,
139    ) -> Result<String, AuthValidateError> {
140        validate_password_user_key(&self.client, password, encrypted_user_key)
141    }
142
143    pub fn validate_pin(
144        &self,
145        pin: String,
146        pin_protected_user_key: EncString,
147    ) -> Result<bool, AuthValidateError> {
148        validate_pin(&self.client, pin, pin_protected_user_key)
149    }
150
151    pub fn new_auth_request(&self, email: &str) -> Result<AuthRequestResponse, CryptoError> {
152        new_auth_request(email)
153    }
154
155    pub fn approve_auth_request(
156        &self,
157        public_key: String,
158    ) -> Result<UnsignedSharedKey, ApproveAuthRequestError> {
159        approve_auth_request(&self.client, public_key)
160    }
161
162    pub fn trust_device(&self) -> Result<TrustDeviceResponse, TrustDeviceError> {
163        trust_device(&self.client)
164    }
165}
166
167#[cfg(feature = "internal")]
168impl AuthClient {
169    pub async fn login_device(
170        &self,
171        email: String,
172        device_identifier: String,
173    ) -> Result<NewAuthRequestResponse, LoginError> {
174        use crate::auth::login::send_new_auth_request;
175
176        send_new_auth_request(&self.client, email, device_identifier).await
177    }
178
179    pub async fn login_device_complete(
180        &self,
181        auth_req: NewAuthRequestResponse,
182    ) -> Result<(), LoginError> {
183        use crate::auth::login::complete_auth_request;
184
185        complete_auth_request(&self.client, auth_req).await
186    }
187}
188
189#[cfg(feature = "internal")]
190#[derive(Debug, thiserror::Error)]
191pub enum TrustDeviceError {
192    #[error(transparent)]
193    VaultLocked(#[from] crate::VaultLockedError),
194    #[error(transparent)]
195    Crypto(#[from] bitwarden_crypto::CryptoError),
196}
197
198#[cfg(feature = "internal")]
199fn trust_device(client: &Client) -> Result<TrustDeviceResponse, TrustDeviceError> {
200    use crate::key_management::SymmetricKeyId;
201
202    let key_store = client.internal.get_key_store();
203    let ctx = key_store.context();
204    // FIXME: [PM-18099] Once DeviceKey deals with KeyIds, this should be updated
205    #[allow(deprecated)]
206    let user_key = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)?;
207
208    Ok(DeviceKey::trust_device(user_key)?)
209}
210
211impl Client {
212    pub fn auth(&self) -> AuthClient {
213        AuthClient {
214            client: self.clone(),
215        }
216    }
217}