bitwarden_importers/importers/onepassword/access/
credentials.rs1use zeroize::Zeroize;
4
5use super::{error::OnePasswordError, sign_in::SignInAddress};
6
7#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
11#[cfg_attr(feature = "wasm", derive(serde::Deserialize))]
12#[bitwarden_ffi::wasm_record(input)]
13#[derive(Clone)]
14pub struct Credentials {
15 pub username: String,
17 pub password: String,
19 pub account_key: String,
21 pub sign_in_address: SignInAddress,
23}
24
25impl Zeroize for Credentials {
26 fn zeroize(&mut self) {
27 self.password.zeroize();
28 self.account_key.zeroize();
29 }
30}
31
32#[cfg(not(feature = "uniffi"))]
35impl Drop for Credentials {
36 fn drop(&mut self) {
37 self.zeroize();
38 }
39}
40
41#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
46#[cfg_attr(feature = "wasm", derive(serde::Deserialize))]
47#[bitwarden_ffi::wasm_record(input)]
48#[derive(Debug, Clone)]
49pub struct SsoCredentials {
50 pub username: String,
52 pub sign_in_address: SignInAddress,
54}
55
56impl SsoCredentials {
57 pub(super) fn validate(&mut self) -> Result<(), OnePasswordError> {
59 if self.username.trim().is_empty() {
60 return Err(OnePasswordError::Internal(
61 "username (email) is required".into(),
62 ));
63 }
64 self.sign_in_address.normalize()
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::{super::sign_in::SignInDomain, *};
71
72 fn credentials() -> SsoCredentials {
73 SsoCredentials {
74 username: "[email protected]".into(),
75 sign_in_address: SignInAddress {
76 subdomain: " ACME ".into(),
77 domain: SignInDomain::Global,
78 },
79 }
80 }
81
82 #[test]
83 fn validation_normalizes_the_sign_in_address() {
84 let mut credentials = credentials();
85
86 credentials.validate().expect("valid credentials");
87
88 assert_eq!(
89 credentials.sign_in_address.to_string(),
90 "acme.1password.com"
91 );
92 assert_eq!(credentials.username, "[email protected]");
93 }
94
95 #[test]
96 fn validation_rejects_a_blank_username() {
97 for username in ["", " \t"] {
98 let mut credentials = credentials();
99 credentials.username = username.into();
100
101 assert!(matches!(
102 credentials.validate(),
103 Err(OnePasswordError::Internal(_))
104 ));
105 }
106 }
107
108 #[test]
109 fn validation_rejects_a_bad_sign_in_address() {
110 let mut credentials = credentials();
111 credentials.sign_in_address.subdomain = "evil.com/x".into();
112
113 assert!(matches!(
114 credentials.validate(),
115 Err(OnePasswordError::InvalidSignInAddress(_))
116 ));
117 }
118}