diff options
author | Daniel GarcĂa <[email protected]> | 2023-02-28 23:45:59 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2023-02-28 23:45:59 +0100 |
commit | 0426051541a34f0d2dccd4fba0f55b0e23d48511 (patch) | |
tree | 2a68f6284aaab053133ad746c6917193d1d4a4c9 /src/api/core/ciphers.rs | |
parent | 4556f668de64dc45176d8bd6f55a92c6acbb6ea8 (diff) | |
parent | 7ec00d3850f0c058314b4bc4a3c5d1094882c434 (diff) | |
download | vaultwarden-0426051541a34f0d2dccd4fba0f55b0e23d48511.tar.gz vaultwarden-0426051541a34f0d2dccd4fba0f55b0e23d48511.zip |
Merge pull request #3281 from BlackDex/fix-web-vault-issues
Fix the web-vault v2023.2.0 API calls
Diffstat (limited to 'src/api/core/ciphers.rs')
-rw-r--r-- | src/api/core/ciphers.rs | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 0b0f1080..14d44597 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -56,7 +56,9 @@ pub fn routes() -> Vec<Route> { put_cipher_share, put_cipher_share_selected, post_cipher, + post_cipher_partial, put_cipher, + put_cipher_partial, delete_cipher_post, delete_cipher_post_admin, delete_cipher_put, @@ -109,7 +111,10 @@ async fn sync(data: SyncData, headers: Headers, mut conn: DbConn) -> Json<Value> // Lets generate the ciphers_json using all the gathered info let mut ciphers_json = Vec::with_capacity(ciphers.len()); for c in ciphers { - ciphers_json.push(c.to_json(&headers.host, &headers.user.uuid, Some(&cipher_sync_data), &mut conn).await); + ciphers_json.push( + c.to_json(&headers.host, &headers.user.uuid, Some(&cipher_sync_data), CipherSyncType::User, &mut conn) + .await, + ); } let collections = Collection::find_by_user_uuid(headers.user.uuid.clone(), &mut conn).await; @@ -153,7 +158,10 @@ async fn get_ciphers(headers: Headers, mut conn: DbConn) -> Json<Value> { let mut ciphers_json = Vec::with_capacity(ciphers.len()); for c in ciphers { - ciphers_json.push(c.to_json(&headers.host, &headers.user.uuid, Some(&cipher_sync_data), &mut conn).await); + ciphers_json.push( + c.to_json(&headers.host, &headers.user.uuid, Some(&cipher_sync_data), CipherSyncType::User, &mut conn) + .await, + ); } Json(json!({ @@ -174,7 +182,7 @@ async fn get_cipher(uuid: String, headers: Headers, mut conn: DbConn) -> JsonRes err!("Cipher is not owned by user") } - Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, &mut conn).await)) + Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await)) } #[get("/ciphers/<uuid>/admin")] @@ -237,6 +245,13 @@ pub struct CipherData { #[derive(Deserialize, Debug)] #[allow(non_snake_case)] +pub struct PartialCipherData { + FolderId: Option<String>, + Favorite: bool, +} + +#[derive(Deserialize, Debug)] +#[allow(non_snake_case)] pub struct Attachments2Data { FileName: String, Key: String, @@ -314,7 +329,7 @@ async fn post_ciphers( update_cipher_from_data(&mut cipher, data, &headers, false, &mut conn, &ip, &nt, UpdateType::SyncCipherCreate) .await?; - Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, &mut conn).await)) + Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await)) } /// Enforces the personal ownership policy on user-owned ciphers, if applicable. @@ -646,7 +661,51 @@ async fn put_cipher( update_cipher_from_data(&mut cipher, data, &headers, false, &mut conn, &ip, &nt, UpdateType::SyncCipherUpdate) .await?; - Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, &mut conn).await)) + Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await)) +} + +#[post("/ciphers/<uuid>/partial", data = "<data>")] +async fn post_cipher_partial( + uuid: String, + data: JsonUpcase<PartialCipherData>, + headers: Headers, + conn: DbConn, +) -> JsonResult { + put_cipher_partial(uuid, data, headers, conn).await +} + +// Only update the folder and favorite for the user, since this cipher is read-only +#[put("/ciphers/<uuid>/partial", data = "<data>")] +async fn put_cipher_partial( + uuid: String, + data: JsonUpcase<PartialCipherData>, + headers: Headers, + mut conn: DbConn, +) -> JsonResult { + let data: PartialCipherData = data.into_inner().data; + + let cipher = match Cipher::find_by_uuid(&uuid, &mut conn).await { + Some(cipher) => cipher, + None => err!("Cipher doesn't exist"), + }; + + if let Some(ref folder_id) = data.FolderId { + match Folder::find_by_uuid(folder_id, &mut conn).await { + Some(folder) => { + if folder.user_uuid != headers.user.uuid { + err!("Folder is not owned by user") + } + } + None => err!("Folder doesn't exist"), + } + } + + // Move cipher + cipher.move_to_folder(data.FolderId.clone(), &headers.user.uuid, &mut conn).await?; + // Update favorite + cipher.set_favorite(Some(data.Favorite), &headers.user.uuid, &mut conn).await?; + + Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await)) } #[derive(Deserialize)] @@ -873,7 +932,7 @@ async fn share_cipher_by_uuid( update_cipher_from_data(&mut cipher, data.Cipher, headers, shared_to_collection, conn, ip, nt, ut).await?; - Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, conn).await)) + Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, conn).await)) } /// v2 API for downloading an attachment. This just redirects the client to @@ -942,7 +1001,7 @@ async fn post_attachment_v2( "AttachmentId": attachment_id, "Url": url, "FileUploadType": FileUploadType::Direct as i32, - response_key: cipher.to_json(&headers.host, &headers.user.uuid, None, &mut conn).await, + response_key: cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await, }))) } @@ -1135,7 +1194,7 @@ async fn post_attachment( let (cipher, mut conn) = save_attachment(attachment, uuid, data, &headers, conn, ip, nt).await?; - Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, &mut conn).await)) + Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await)) } #[post("/ciphers/<uuid>/attachment-admin", format = "multipart/form-data", data = "<data>")] @@ -1616,7 +1675,7 @@ async fn _restore_cipher_by_uuid( .await; } - Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, conn).await)) + Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, conn).await)) } async fn _restore_multiple_ciphers( @@ -1716,6 +1775,7 @@ pub struct CipherSyncData { pub user_group_full_access_for_organizations: HashSet<String>, } +#[derive(Eq, PartialEq)] pub enum CipherSyncType { User, Organization, |