Skip to main content

bitwarden_importers/importers/onepassword/
mod.rs

1//! 1Password importer.
2//!
3//! [`access`] is the Bitwarden-agnostic client that logs in and downloads the vaults.
4//! [`convert`] maps what it returns onto the importer's parsed shape.
5
6pub(crate) mod access;
7pub(crate) mod convert;
8
9use access::OnePasswordError;
10
11use crate::ImportError;
12
13impl From<OnePasswordError> for ImportError {
14    fn from(error: OnePasswordError) -> Self {
15        match error {
16            OnePasswordError::BadCredentials => ImportError::OnePasswordBadCredentials,
17            OnePasswordError::InvalidEmail => ImportError::OnePasswordInvalidEmail,
18            OnePasswordError::InvalidSignInAddress(_) => {
19                ImportError::OnePasswordInvalidSignInAddress
20            }
21            OnePasswordError::InvalidAccountKey(_) => ImportError::OnePasswordInvalidSecretKey,
22            OnePasswordError::TwoFactorRequired => ImportError::OnePasswordTwoFactorRequired,
23            OnePasswordError::TwoFactorFailed => ImportError::OnePasswordTwoFactorFailed,
24            OnePasswordError::Canceled => ImportError::OnePasswordCanceled,
25            OnePasswordError::Denied => ImportError::OnePasswordDenied,
26            OnePasswordError::VerificationCodeFailed => {
27                ImportError::OnePasswordVerificationCodeFailed
28            }
29            OnePasswordError::Unsupported(what) => ImportError::OnePasswordUnsupported(what),
30            OnePasswordError::Network(what) => ImportError::OnePasswordNetwork(what),
31            // A payload that will not decrypt or parse is the same story to a user: the account
32            // came back unreadable.
33            OnePasswordError::Decryption | OnePasswordError::Parse => {
34                ImportError::OnePasswordDecryption
35            }
36            // Nothing a user can act on, and not the network either. The detail is for the logs.
37            OnePasswordError::NotFound => {
38                ImportError::OnePasswordInternal("the account or vault was not found".to_string())
39            }
40            OnePasswordError::Internal(what) => ImportError::OnePasswordInternal(what),
41            error @ OnePasswordError::UnexpectedStatus { .. } => {
42                ImportError::OnePasswordInternal(error.to_string())
43            }
44        }
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn only_a_transport_failure_is_a_network_error() {
54        assert!(matches!(
55            ImportError::from(OnePasswordError::Network("connection reset".into())),
56            ImportError::OnePasswordNetwork(what) if what == "connection reset"
57        ));
58        assert!(matches!(
59            ImportError::from(OnePasswordError::Internal("device enrollment timed out".into())),
60            ImportError::OnePasswordInternal(what) if what == "device enrollment timed out"
61        ));
62        for error in [
63            OnePasswordError::NotFound,
64            OnePasswordError::UnexpectedStatus {
65                endpoint: "v3/auth/start".into(),
66                status: 500,
67            },
68        ] {
69            assert!(matches!(
70                ImportError::from(error),
71                ImportError::OnePasswordInternal(_)
72            ));
73        }
74    }
75}