mirror of
https://github.com/dani-garcia/vaultwarden.wiki.git
synced 2026-10-29 11:36:47 +02:00
Align cipher org checks & attachment notification with upstream (#7906)
This commit is contained in:
1 parent
a96912bf21
commit
64ae55ceb2
1 file changed
+42
-10
+42
-10
@@ -666,6 +666,9 @@ async fn post_ciphers_import(data: Json<ImportData>, headers: Headers, conn: DbC
|
|||||||
for (index, mut cipher_data) in data.ciphers.into_iter().enumerate() {
|
for (index, mut cipher_data) in data.ciphers.into_iter().enumerate() {
|
||||||
let folder_id = relations_map.get(&index).and_then(|i| folders.get(*i).cloned());
|
let folder_id = relations_map.get(&index).and_then(|i| folders.get(*i).cloned());
|
||||||
cipher_data.folder_id = folder_id;
|
cipher_data.folder_id = folder_id;
|
||||||
|
// A personal import always creates personal ciphers, the organization ID is ignored instead of rejected
|
||||||
|
// Upstream: https://github.com/bitwarden/server/blob/b06b81c1fb33ce9c9872b96397ba2b4d879b66af/src/Api/Tools/Controllers/ImportCiphersController.cs#L58
|
||||||
|
cipher_data.organization_id = None;
|
||||||
|
|
||||||
let mut cipher = Cipher::new(cipher_data.r#type, cipher_data.name.clone());
|
let mut cipher = Cipher::new(cipher_data.r#type, cipher_data.name.clone());
|
||||||
update_cipher_from_data(&mut cipher, cipher_data, &headers, None, &conn, &nt, UpdateType::None).await?;
|
update_cipher_from_data(&mut cipher, cipher_data, &headers, None, &conn, &nt, UpdateType::None).await?;
|
||||||
@@ -687,6 +690,11 @@ async fn put_cipher_admin(
|
|||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
nt: Notify<'_>,
|
nt: Notify<'_>,
|
||||||
) -> JsonResult {
|
) -> JsonResult {
|
||||||
|
// Only organization ciphers can be edited here, put_cipher() rejects an organization ID that isn't the cipher's
|
||||||
|
if data.organization_id.is_none() {
|
||||||
|
err_code!("Resource not found.", "Cipher is not an organization cipher", Status::NotFound.code);
|
||||||
|
}
|
||||||
|
|
||||||
put_cipher(cipher_id, data, headers, conn, nt).await
|
put_cipher(cipher_id, data, headers, conn, nt).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -698,7 +706,7 @@ async fn post_cipher_admin(
|
|||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
nt: Notify<'_>,
|
nt: Notify<'_>,
|
||||||
) -> JsonResult {
|
) -> JsonResult {
|
||||||
post_cipher(cipher_id, data, headers, conn, nt).await
|
put_cipher_admin(cipher_id, data, headers, conn, nt).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/ciphers/<cipher_id>", data = "<data>")]
|
#[post("/ciphers/<cipher_id>", data = "<data>")]
|
||||||
@@ -735,6 +743,11 @@ async fn put_cipher(
|
|||||||
err!("Cipher is not write accessible")
|
err!("Cipher is not write accessible")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Moving a cipher into an organization is only possible through the share endpoints
|
||||||
|
if cipher.organization_uuid != data.organization_id {
|
||||||
|
err!("Organization mismatch. Please resync the client before updating the cipher")
|
||||||
|
}
|
||||||
|
|
||||||
update_cipher_from_data(&mut cipher, data, &headers, None, &conn, &nt, UpdateType::SyncCipherUpdate).await?;
|
update_cipher_from_data(&mut cipher, data, &headers, None, &conn, &nt, UpdateType::SyncCipherUpdate).await?;
|
||||||
|
|
||||||
Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &conn).await?))
|
Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &conn).await?))
|
||||||
@@ -993,9 +1006,7 @@ async fn post_cipher_share(
|
|||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
nt: Notify<'_>,
|
nt: Notify<'_>,
|
||||||
) -> JsonResult {
|
) -> JsonResult {
|
||||||
let data: ShareCipherData = data.into_inner();
|
put_cipher_share(cipher_id, data, headers, conn, nt).await
|
||||||
|
|
||||||
share_cipher_by_uuid(&cipher_id, data, &headers, &conn, &nt, None).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/ciphers/<cipher_id>/share", data = "<data>")]
|
#[put("/ciphers/<cipher_id>/share", data = "<data>")]
|
||||||
@@ -1008,6 +1019,14 @@ async fn put_cipher_share(
|
|||||||
) -> JsonResult {
|
) -> JsonResult {
|
||||||
let data: ShareCipherData = data.into_inner();
|
let data: ShareCipherData = data.into_inner();
|
||||||
|
|
||||||
|
if data.cipher.organization_id.is_none() {
|
||||||
|
err!("Cipher OrganizationId is required.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.collection_ids.is_empty() {
|
||||||
|
err!("You must select at least one collection.")
|
||||||
|
}
|
||||||
|
|
||||||
share_cipher_by_uuid(&cipher_id, data, &headers, &conn, &nt, None).await
|
share_cipher_by_uuid(&cipher_id, data, &headers, &conn, &nt, None).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,6 +1097,9 @@ async fn put_cipher_share_selected(
|
|||||||
if cipher.id.is_none() {
|
if cipher.id.is_none() {
|
||||||
err!("Request missing ids field")
|
err!("Request missing ids field")
|
||||||
}
|
}
|
||||||
|
if cipher.organization_id.is_none() {
|
||||||
|
err!("Cipher OrganizationId is required.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut responses = Vec::with_capacity(data.ciphers.len());
|
let mut responses = Vec::with_capacity(data.ciphers.len());
|
||||||
@@ -1258,6 +1280,7 @@ async fn post_attachment_v2(
|
|||||||
data: Json<AttachmentRequestData>,
|
data: Json<AttachmentRequestData>,
|
||||||
headers: Headers,
|
headers: Headers,
|
||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
|
nt: Notify<'_>,
|
||||||
) -> JsonResult {
|
) -> JsonResult {
|
||||||
let Some(cipher) = Cipher::find_by_uuid(&cipher_id, &conn).await else {
|
let Some(cipher) = Cipher::find_by_uuid(&cipher_id, &conn).await else {
|
||||||
err!("Cipher doesn't exist")
|
err!("Cipher doesn't exist")
|
||||||
@@ -1288,6 +1311,7 @@ async fn post_attachment_v2(
|
|||||||
let attachment =
|
let attachment =
|
||||||
Attachment::new(attachment_id.clone(), cipher.uuid.clone(), data.file_name, file_size, Some(data.key));
|
Attachment::new(attachment_id.clone(), cipher.uuid.clone(), data.file_name, file_size, Some(data.key));
|
||||||
attachment.save(&conn).await.expect("Error saving attachment");
|
attachment.save(&conn).await.expect("Error saving attachment");
|
||||||
|
notify_attachment_created(&cipher, &headers, &conn, &nt).await;
|
||||||
|
|
||||||
let url = format!("/ciphers/{}/attachment/{attachment_id}", cipher.uuid);
|
let url = format!("/ciphers/{}/attachment/{attachment_id}", cipher.uuid);
|
||||||
let response_key = match data.admin_request {
|
let response_key = match data.admin_request {
|
||||||
@@ -1407,13 +1431,23 @@ async fn save_attachment(
|
|||||||
|
|
||||||
save_temp_file(&PathType::Attachments, &format!("{cipher_id}/{file_id}"), data.data, true).await?;
|
save_temp_file(&PathType::Attachments, &format!("{cipher_id}/{file_id}"), data.data, true).await?;
|
||||||
|
|
||||||
|
// With the v2 API, post_attachment_v2() already did this when it created the attachment record
|
||||||
|
if attachment.is_none() {
|
||||||
|
notify_attachment_created(&cipher, headers, &conn, &nt).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((cipher, conn))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends the cipher update to the clients and logs the attachment event
|
||||||
|
async fn notify_attachment_created(cipher: &Cipher, headers: &Headers, conn: &DbConn, nt: &Notify<'_>) {
|
||||||
nt.send_cipher_update(
|
nt.send_cipher_update(
|
||||||
UpdateType::SyncCipherUpdate,
|
UpdateType::SyncCipherUpdate,
|
||||||
&cipher,
|
cipher,
|
||||||
&cipher.update_users_revision(&conn).await,
|
&cipher.update_users_revision(conn).await,
|
||||||
&headers.device,
|
&headers.device,
|
||||||
None,
|
None,
|
||||||
&conn,
|
conn,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -1425,12 +1459,10 @@ async fn save_attachment(
|
|||||||
&headers.user.uuid,
|
&headers.user.uuid,
|
||||||
headers.device.atype,
|
headers.device.atype,
|
||||||
&headers.ip.ip,
|
&headers.ip.ip,
|
||||||
&conn,
|
conn,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((cipher, conn))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// v2 API for uploading the actual data content of an attachment.
|
/// v2 API for uploading the actual data content of an attachment.
|
||||||
|
|||||||
Reference in new issue
Block a user