Skip to main content

bitwarden_importers/
import.rs

1//! Routing: maps each importer's public entry to its parser + the generic submit pipeline.
2
3use bitwarden_core::Client;
4
5use crate::{
6    Credentials, ImportError, ImportOptions, ImportSummary, OnePasswordImportSummary,
7    OnePasswordSignInMethods, OnePasswordSsoCredentials, OnePasswordSsoUi, OnePasswordTwoFactorUi,
8    SignInAddress,
9    importers::{
10        self,
11        onepassword::{access, convert},
12    },
13    pipeline,
14};
15
16/// See [crate::ImporterClient::import_kdbx] for more documentation.
17pub(crate) async fn import_kdbx(
18    client: &Client,
19    file: Vec<u8>,
20    password: Option<String>,
21    key_file: Option<Vec<u8>>,
22    options: ImportOptions,
23) -> Result<ImportSummary, ImportError> {
24    let parsed = importers::kdbx::parse(file, password, key_file)?;
25    pipeline::submit_import(client, parsed, options).await
26}
27
28/// See [crate::ImporterClient::import_onepassword] for more documentation.
29pub(crate) async fn import_onepassword(
30    client: &Client,
31    credentials: Credentials,
32    two_factor: &dyn OnePasswordTwoFactorUi,
33    options: ImportOptions,
34) -> Result<OnePasswordImportSummary, ImportError> {
35    let onepassword = access_client(client);
36    let account = onepassword.open_account(credentials, two_factor).await?;
37    submit_onepassword(client, account, options).await
38}
39
40/// See [crate::ImporterClient::import_onepassword_sso] for more documentation.
41pub(crate) async fn import_onepassword_sso(
42    client: &Client,
43    credentials: OnePasswordSsoCredentials,
44    ui: &dyn OnePasswordSsoUi,
45    options: ImportOptions,
46) -> Result<OnePasswordImportSummary, ImportError> {
47    let onepassword = access_client(client);
48    let account = onepassword.open_account_sso(credentials, ui).await?;
49    submit_onepassword(client, account, options).await
50}
51
52/// See [crate::ImporterClient::onepassword_sign_in_methods] for more documentation.
53pub(crate) async fn onepassword_sign_in_methods(
54    client: &Client,
55    username: String,
56    sign_in_address: SignInAddress,
57) -> Result<OnePasswordSignInMethods, ImportError> {
58    Ok(access_client(client)
59        .sign_in_methods(&username, sign_in_address)
60        .await?)
61}
62
63/// 1Password is a third-party host, so this goes through the client's external transport rather
64/// than the one configured for the Bitwarden API.
65fn access_client(client: &Client) -> access::Client {
66    access::Client::new(client.internal.get_http_client().clone())
67}
68
69/// Converts a downloaded account and submits it, collecting what could not be imported.
70async fn submit_onepassword(
71    client: &Client,
72    mut account: access::model::DownloadedAccount,
73    options: ImportOptions,
74) -> Result<OnePasswordImportSummary, ImportError> {
75    let skipped_items = account
76        .vaults
77        .iter_mut()
78        .flat_map(|vault| std::mem::take(&mut vault.skipped_items))
79        .collect();
80    let imported =
81        pipeline::submit_import(client, convert::convert(account.vaults), options).await?;
82
83    Ok(OnePasswordImportSummary {
84        imported,
85        skipped_vaults: account.skipped_vaults,
86        skipped_items,
87    })
88}