summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathijs van Veluw <[email protected]>2024-07-04 19:57:32 +0200
committerGitHub <[email protected]>2024-07-04 19:57:32 +0200
commitbd9196417050c154526c1b8b82c997b4a582a8d2 (patch)
treee518e14516fa70138fb8cb7dbc6e495a8124d1bb
parentd42b264a93eace528dc20f0cd363742d4fbce448 (diff)
downloadvaultwarden-bd9196417050c154526c1b8b82c997b4a582a8d2.tar.gz
vaultwarden-bd9196417050c154526c1b8b82c997b4a582a8d2.zip
Fix duplicate folder creations during import (#4702)
During import you are able to select an existing folder, or with Bitwarden exports it can contain existing folders already. In either case it didn't matter, we always created new folders. Bitwarden uses the same UUID of the selected or existing folders if they are already there. This PR fixes this by using the same behaviour. Fixes #4700
-rw-r--r--src/api/core/ciphers.rs19
-rw-r--r--src/api/core/folders.rs1
2 files changed, 14 insertions, 6 deletions
diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs
index 4a6bc8b4..956f4891 100644
--- a/src/api/core/ciphers.rs
+++ b/src/api/core/ciphers.rs
@@ -562,16 +562,23 @@ async fn post_ciphers_import(
Cipher::validate_notes(&data.ciphers)?;
// Read and create the folders
- let mut folders: Vec<_> = Vec::new();
+ let existing_folders: Vec<String> =
+ Folder::find_by_user(&headers.user.uuid, &mut conn).await.into_iter().map(|f| f.uuid).collect();
+ let mut folders: Vec<String> = Vec::with_capacity(data.folders.len());
for folder in data.folders.into_iter() {
- let mut new_folder = Folder::new(headers.user.uuid.clone(), folder.name);
- new_folder.save(&mut conn).await?;
+ let folder_uuid = if folder.id.is_some() && existing_folders.contains(folder.id.as_ref().unwrap()) {
+ folder.id.unwrap()
+ } else {
+ let mut new_folder = Folder::new(headers.user.uuid.clone(), folder.name);
+ new_folder.save(&mut conn).await?;
+ new_folder.uuid
+ };
- folders.push(new_folder);
+ folders.push(folder_uuid);
}
// Read the relations between folders and ciphers
- let mut relations_map = HashMap::new();
+ let mut relations_map = HashMap::with_capacity(data.folder_relationships.len());
for relation in data.folder_relationships {
relations_map.insert(relation.key, relation.value);
@@ -579,7 +586,7 @@ async fn post_ciphers_import(
// Read and create the ciphers
for (index, mut cipher_data) in data.ciphers.into_iter().enumerate() {
- let folder_uuid = relations_map.get(&index).map(|i| folders[*i].uuid.clone());
+ let folder_uuid = relations_map.get(&index).map(|i| folders[*i].clone());
cipher_data.folder_id = folder_uuid;
let mut cipher = Cipher::new(cipher_data.r#type, cipher_data.name.clone());
diff --git a/src/api/core/folders.rs b/src/api/core/folders.rs
index fd9ce6a0..9766d7a1 100644
--- a/src/api/core/folders.rs
+++ b/src/api/core/folders.rs
@@ -41,6 +41,7 @@ async fn get_folder(uuid: &str, headers: Headers, mut conn: DbConn) -> JsonResul
#[serde(rename_all = "camelCase")]
pub struct FolderData {
pub name: String,
+ pub id: Option<String>,
}
#[post("/folders", data = "<data>")]