|
|
|
@ -11,7 +11,7 @@ use serde_json::Value;
|
|
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
|
api::{self, core::log_event, EmptyResult, JsonResult, JsonUpcase, Notify, PasswordData, UpdateType},
|
|
|
|
|
auth::{ClientIp, Headers},
|
|
|
|
|
auth::Headers,
|
|
|
|
|
crypto,
|
|
|
|
|
db::{models::*, DbConn, DbPool},
|
|
|
|
|
CONFIG,
|
|
|
|
@ -263,10 +263,9 @@ async fn post_ciphers_admin(
|
|
|
|
|
data: JsonUpcase<ShareCipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
post_ciphers_create(data, headers, conn, ip, nt).await
|
|
|
|
|
post_ciphers_create(data, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Called when creating a new org-owned cipher, or cloning a cipher (whether
|
|
|
|
@ -277,7 +276,6 @@ async fn post_ciphers_create(
|
|
|
|
|
data: JsonUpcase<ShareCipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
let mut data: ShareCipherData = data.into_inner().data;
|
|
|
|
@ -305,18 +303,12 @@ async fn post_ciphers_create(
|
|
|
|
|
// or otherwise), we can just ignore this field entirely.
|
|
|
|
|
data.Cipher.LastKnownRevisionDate = None;
|
|
|
|
|
|
|
|
|
|
share_cipher_by_uuid(&cipher.uuid, data, &headers, &mut conn, &ip, &nt).await
|
|
|
|
|
share_cipher_by_uuid(&cipher.uuid, data, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Called when creating a new user-owned cipher.
|
|
|
|
|
#[post("/ciphers", data = "<data>")]
|
|
|
|
|
async fn post_ciphers(
|
|
|
|
|
data: JsonUpcase<CipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
async fn post_ciphers(data: JsonUpcase<CipherData>, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> JsonResult {
|
|
|
|
|
let mut data: CipherData = data.into_inner().data;
|
|
|
|
|
|
|
|
|
|
// The web/browser clients set this field to null as expected, but the
|
|
|
|
@ -326,8 +318,7 @@ async fn post_ciphers(
|
|
|
|
|
data.LastKnownRevisionDate = None;
|
|
|
|
|
|
|
|
|
|
let mut cipher = Cipher::new(data.Type, data.Name.clone());
|
|
|
|
|
update_cipher_from_data(&mut cipher, data, &headers, false, &mut conn, &ip, &nt, UpdateType::SyncCipherCreate)
|
|
|
|
|
.await?;
|
|
|
|
|
update_cipher_from_data(&mut cipher, data, &headers, false, &mut conn, &nt, UpdateType::SyncCipherCreate).await?;
|
|
|
|
|
|
|
|
|
|
Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await))
|
|
|
|
|
}
|
|
|
|
@ -354,14 +345,12 @@ async fn enforce_personal_ownership_policy(
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(clippy::too_many_arguments)]
|
|
|
|
|
pub async fn update_cipher_from_data(
|
|
|
|
|
cipher: &mut Cipher,
|
|
|
|
|
data: CipherData,
|
|
|
|
|
headers: &Headers,
|
|
|
|
|
shared_to_collection: bool,
|
|
|
|
|
conn: &mut DbConn,
|
|
|
|
|
ip: &ClientIp,
|
|
|
|
|
nt: &Notify<'_>,
|
|
|
|
|
ut: UpdateType,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
@ -517,7 +506,7 @@ pub async fn update_cipher_from_data(
|
|
|
|
|
String::from(org_uuid),
|
|
|
|
|
headers.user.uuid.clone(),
|
|
|
|
|
headers.device.atype,
|
|
|
|
|
&ip.ip,
|
|
|
|
|
&headers.ip.ip,
|
|
|
|
|
conn,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
@ -551,7 +540,6 @@ async fn post_ciphers_import(
|
|
|
|
|
data: JsonUpcase<ImportData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
enforce_personal_ownership_policy(None, &headers, &mut conn).await?;
|
|
|
|
@ -586,8 +574,7 @@ async fn post_ciphers_import(
|
|
|
|
|
cipher_data.FolderId = folder_uuid;
|
|
|
|
|
|
|
|
|
|
let mut cipher = Cipher::new(cipher_data.Type, cipher_data.Name.clone());
|
|
|
|
|
update_cipher_from_data(&mut cipher, cipher_data, &headers, false, &mut conn, &ip, &nt, UpdateType::None)
|
|
|
|
|
.await?;
|
|
|
|
|
update_cipher_from_data(&mut cipher, cipher_data, &headers, false, &mut conn, &nt, UpdateType::None).await?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut user = headers.user;
|
|
|
|
@ -603,10 +590,9 @@ async fn put_cipher_admin(
|
|
|
|
|
data: JsonUpcase<CipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
put_cipher(uuid, data, headers, conn, ip, nt).await
|
|
|
|
|
put_cipher(uuid, data, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/admin", data = "<data>")]
|
|
|
|
@ -615,10 +601,9 @@ async fn post_cipher_admin(
|
|
|
|
|
data: JsonUpcase<CipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
post_cipher(uuid, data, headers, conn, ip, nt).await
|
|
|
|
|
post_cipher(uuid, data, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>", data = "<data>")]
|
|
|
|
@ -627,10 +612,9 @@ async fn post_cipher(
|
|
|
|
|
data: JsonUpcase<CipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
put_cipher(uuid, data, headers, conn, ip, nt).await
|
|
|
|
|
put_cipher(uuid, data, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/<uuid>", data = "<data>")]
|
|
|
|
@ -639,7 +623,6 @@ async fn put_cipher(
|
|
|
|
|
data: JsonUpcase<CipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
let data: CipherData = data.into_inner().data;
|
|
|
|
@ -658,8 +641,7 @@ async fn put_cipher(
|
|
|
|
|
err!("Cipher is not write accessible")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update_cipher_from_data(&mut cipher, data, &headers, false, &mut conn, &ip, &nt, UpdateType::SyncCipherUpdate)
|
|
|
|
|
.await?;
|
|
|
|
|
update_cipher_from_data(&mut cipher, data, &headers, false, &mut conn, &nt, UpdateType::SyncCipherUpdate).await?;
|
|
|
|
|
|
|
|
|
|
Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await))
|
|
|
|
|
}
|
|
|
|
@ -720,9 +702,8 @@ async fn put_collections_update(
|
|
|
|
|
data: JsonUpcase<CollectionsAdminData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
post_collections_admin(uuid, data, headers, conn, ip).await
|
|
|
|
|
post_collections_admin(uuid, data, headers, conn).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/collections", data = "<data>")]
|
|
|
|
@ -731,9 +712,8 @@ async fn post_collections_update(
|
|
|
|
|
data: JsonUpcase<CollectionsAdminData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
post_collections_admin(uuid, data, headers, conn, ip).await
|
|
|
|
|
post_collections_admin(uuid, data, headers, conn).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/<uuid>/collections-admin", data = "<data>")]
|
|
|
|
@ -742,9 +722,8 @@ async fn put_collections_admin(
|
|
|
|
|
data: JsonUpcase<CollectionsAdminData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
post_collections_admin(uuid, data, headers, conn, ip).await
|
|
|
|
|
post_collections_admin(uuid, data, headers, conn).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/collections-admin", data = "<data>")]
|
|
|
|
@ -753,7 +732,6 @@ async fn post_collections_admin(
|
|
|
|
|
data: JsonUpcase<CollectionsAdminData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
let data: CollectionsAdminData = data.into_inner().data;
|
|
|
|
|
|
|
|
|
@ -795,7 +773,7 @@ async fn post_collections_admin(
|
|
|
|
|
cipher.organization_uuid.unwrap(),
|
|
|
|
|
headers.user.uuid.clone(),
|
|
|
|
|
headers.device.atype,
|
|
|
|
|
&ip.ip,
|
|
|
|
|
&headers.ip.ip,
|
|
|
|
|
&mut conn,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
@ -816,12 +794,11 @@ async fn post_cipher_share(
|
|
|
|
|
data: JsonUpcase<ShareCipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
let data: ShareCipherData = data.into_inner().data;
|
|
|
|
|
|
|
|
|
|
share_cipher_by_uuid(&uuid, data, &headers, &mut conn, &ip, &nt).await
|
|
|
|
|
share_cipher_by_uuid(&uuid, data, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/<uuid>/share", data = "<data>")]
|
|
|
|
@ -830,12 +807,11 @@ async fn put_cipher_share(
|
|
|
|
|
data: JsonUpcase<ShareCipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
let data: ShareCipherData = data.into_inner().data;
|
|
|
|
|
|
|
|
|
|
share_cipher_by_uuid(&uuid, data, &headers, &mut conn, &ip, &nt).await
|
|
|
|
|
share_cipher_by_uuid(&uuid, data, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
@ -850,7 +826,6 @@ async fn put_cipher_share_selected(
|
|
|
|
|
data: JsonUpcase<ShareSelectedCipherData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
let mut data: ShareSelectedCipherData = data.into_inner().data;
|
|
|
|
@ -878,7 +853,7 @@ async fn put_cipher_share_selected(
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
match shared_cipher_data.Cipher.Id.take() {
|
|
|
|
|
Some(id) => share_cipher_by_uuid(&id, shared_cipher_data, &headers, &mut conn, &ip, &nt).await?,
|
|
|
|
|
Some(id) => share_cipher_by_uuid(&id, shared_cipher_data, &headers, &mut conn, &nt).await?,
|
|
|
|
|
None => err!("Request missing ids field"),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
@ -891,7 +866,6 @@ async fn share_cipher_by_uuid(
|
|
|
|
|
data: ShareCipherData,
|
|
|
|
|
headers: &Headers,
|
|
|
|
|
conn: &mut DbConn,
|
|
|
|
|
ip: &ClientIp,
|
|
|
|
|
nt: &Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
let mut cipher = match Cipher::find_by_uuid(uuid, conn).await {
|
|
|
|
@ -930,7 +904,7 @@ async fn share_cipher_by_uuid(
|
|
|
|
|
UpdateType::SyncCipherCreate
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
update_cipher_from_data(&mut cipher, data.Cipher, headers, shared_to_collection, conn, ip, nt, ut).await?;
|
|
|
|
|
update_cipher_from_data(&mut cipher, data.Cipher, headers, shared_to_collection, conn, nt, ut).await?;
|
|
|
|
|
|
|
|
|
|
Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, conn).await))
|
|
|
|
|
}
|
|
|
|
@ -1025,7 +999,6 @@ async fn save_attachment(
|
|
|
|
|
data: Form<UploadData<'_>>,
|
|
|
|
|
headers: &Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> Result<(Cipher, DbConn), crate::error::Error> {
|
|
|
|
|
let cipher = match Cipher::find_by_uuid(&cipher_uuid, &mut conn).await {
|
|
|
|
@ -1144,7 +1117,7 @@ async fn save_attachment(
|
|
|
|
|
String::from(org_uuid),
|
|
|
|
|
headers.user.uuid.clone(),
|
|
|
|
|
headers.device.atype,
|
|
|
|
|
&ip.ip,
|
|
|
|
|
&headers.ip.ip,
|
|
|
|
|
&mut conn,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
@ -1164,7 +1137,6 @@ async fn post_attachment_v2_data(
|
|
|
|
|
data: Form<UploadData<'_>>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
let attachment = match Attachment::find_by_id(&attachment_id, &mut conn).await {
|
|
|
|
@ -1173,7 +1145,7 @@ async fn post_attachment_v2_data(
|
|
|
|
|
None => err!("Attachment doesn't exist"),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
save_attachment(attachment, uuid, data, &headers, conn, ip, nt).await?;
|
|
|
|
|
save_attachment(attachment, uuid, data, &headers, conn, nt).await?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
@ -1185,14 +1157,13 @@ async fn post_attachment(
|
|
|
|
|
data: Form<UploadData<'_>>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
// Setting this as None signifies to save_attachment() that it should create
|
|
|
|
|
// the attachment database record as well as saving the data to disk.
|
|
|
|
|
let attachment = None;
|
|
|
|
|
|
|
|
|
|
let (cipher, mut conn) = save_attachment(attachment, uuid, data, &headers, conn, ip, nt).await?;
|
|
|
|
|
let (cipher, mut conn) = save_attachment(attachment, uuid, data, &headers, conn, nt).await?;
|
|
|
|
|
|
|
|
|
|
Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, None, CipherSyncType::User, &mut conn).await))
|
|
|
|
|
}
|
|
|
|
@ -1203,10 +1174,9 @@ async fn post_attachment_admin(
|
|
|
|
|
data: Form<UploadData<'_>>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
post_attachment(uuid, data, headers, conn, ip, nt).await
|
|
|
|
|
post_attachment(uuid, data, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/attachment/<attachment_id>/share", format = "multipart/form-data", data = "<data>")]
|
|
|
|
@ -1216,11 +1186,10 @@ async fn post_attachment_share(
|
|
|
|
|
data: Form<UploadData<'_>>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
_delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &mut conn, &ip, &nt).await?;
|
|
|
|
|
post_attachment(uuid, data, headers, conn, ip, nt).await
|
|
|
|
|
_delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &mut conn, &nt).await?;
|
|
|
|
|
post_attachment(uuid, data, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/attachment/<attachment_id>/delete-admin")]
|
|
|
|
@ -1229,10 +1198,9 @@ async fn delete_attachment_post_admin(
|
|
|
|
|
attachment_id: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
delete_attachment(uuid, attachment_id, headers, conn, ip, nt).await
|
|
|
|
|
delete_attachment(uuid, attachment_id, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/attachment/<attachment_id>/delete")]
|
|
|
|
@ -1241,10 +1209,9 @@ async fn delete_attachment_post(
|
|
|
|
|
attachment_id: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
delete_attachment(uuid, attachment_id, headers, conn, ip, nt).await
|
|
|
|
|
delete_attachment(uuid, attachment_id, headers, conn, nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[delete("/ciphers/<uuid>/attachment/<attachment_id>")]
|
|
|
|
@ -1253,10 +1220,9 @@ async fn delete_attachment(
|
|
|
|
|
attachment_id: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &mut conn, &ip, &nt).await
|
|
|
|
|
_delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[delete("/ciphers/<uuid>/attachment/<attachment_id>/admin")]
|
|
|
|
@ -1265,70 +1231,44 @@ async fn delete_attachment_admin(
|
|
|
|
|
attachment_id: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &mut conn, &ip, &nt).await
|
|
|
|
|
_delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/delete")]
|
|
|
|
|
async fn delete_cipher_post(
|
|
|
|
|
uuid: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &ip, &nt).await // permanent delete
|
|
|
|
|
async fn delete_cipher_post(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &nt).await
|
|
|
|
|
// permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/<uuid>/delete-admin")]
|
|
|
|
|
async fn delete_cipher_post_admin(
|
|
|
|
|
uuid: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &ip, &nt).await // permanent delete
|
|
|
|
|
async fn delete_cipher_post_admin(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &nt).await
|
|
|
|
|
// permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/<uuid>/delete")]
|
|
|
|
|
async fn delete_cipher_put(
|
|
|
|
|
uuid: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, true, &ip, &nt).await // soft delete
|
|
|
|
|
async fn delete_cipher_put(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, true, &nt).await
|
|
|
|
|
// soft delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/<uuid>/delete-admin")]
|
|
|
|
|
async fn delete_cipher_put_admin(
|
|
|
|
|
uuid: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, true, &ip, &nt).await
|
|
|
|
|
async fn delete_cipher_put_admin(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, true, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[delete("/ciphers/<uuid>")]
|
|
|
|
|
async fn delete_cipher(uuid: String, headers: Headers, mut conn: DbConn, ip: ClientIp, nt: Notify<'_>) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &ip, &nt).await // permanent delete
|
|
|
|
|
async fn delete_cipher(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &nt).await
|
|
|
|
|
// permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[delete("/ciphers/<uuid>/admin")]
|
|
|
|
|
async fn delete_cipher_admin(
|
|
|
|
|
uuid: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &ip, &nt).await // permanent delete
|
|
|
|
|
async fn delete_cipher_admin(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
|
|
|
|
_delete_cipher_by_uuid(&uuid, &headers, &mut conn, false, &nt).await
|
|
|
|
|
// permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[delete("/ciphers", data = "<data>")]
|
|
|
|
@ -1336,10 +1276,9 @@ async fn delete_cipher_selected(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, ip, nt).await // permanent delete
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, nt).await // permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/delete", data = "<data>")]
|
|
|
|
@ -1347,10 +1286,9 @@ async fn delete_cipher_selected_post(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, ip, nt).await // permanent delete
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, nt).await // permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/delete", data = "<data>")]
|
|
|
|
@ -1358,10 +1296,9 @@ async fn delete_cipher_selected_put(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, true, ip, nt).await // soft delete
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, true, nt).await // soft delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[delete("/ciphers/admin", data = "<data>")]
|
|
|
|
@ -1369,10 +1306,9 @@ async fn delete_cipher_selected_admin(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, ip, nt).await // permanent delete
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, nt).await // permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/ciphers/delete-admin", data = "<data>")]
|
|
|
|
@ -1380,10 +1316,9 @@ async fn delete_cipher_selected_post_admin(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, ip, nt).await // permanent delete
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, false, nt).await // permanent delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/delete-admin", data = "<data>")]
|
|
|
|
@ -1391,32 +1326,19 @@ async fn delete_cipher_selected_put_admin(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, true, ip, nt).await // soft delete
|
|
|
|
|
_delete_multiple_ciphers(data, headers, conn, true, nt).await // soft delete
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/<uuid>/restore")]
|
|
|
|
|
async fn restore_cipher_put(
|
|
|
|
|
uuid: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
_restore_cipher_by_uuid(&uuid, &headers, &mut conn, &ip, &nt).await
|
|
|
|
|
async fn restore_cipher_put(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> JsonResult {
|
|
|
|
|
_restore_cipher_by_uuid(&uuid, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/<uuid>/restore-admin")]
|
|
|
|
|
async fn restore_cipher_put_admin(
|
|
|
|
|
uuid: String,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
_restore_cipher_by_uuid(&uuid, &headers, &mut conn, &ip, &nt).await
|
|
|
|
|
async fn restore_cipher_put_admin(uuid: String, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> JsonResult {
|
|
|
|
|
_restore_cipher_by_uuid(&uuid, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[put("/ciphers/restore", data = "<data>")]
|
|
|
|
@ -1424,10 +1346,9 @@ async fn restore_cipher_selected(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
_restore_multiple_ciphers(data, &headers, &mut conn, ip, &nt).await
|
|
|
|
|
_restore_multiple_ciphers(data, &headers, &mut conn, &nt).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
@ -1499,7 +1420,6 @@ async fn delete_all(
|
|
|
|
|
data: JsonUpcase<PasswordData>,
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
let data: PasswordData = data.into_inner().data;
|
|
|
|
@ -1527,7 +1447,7 @@ async fn delete_all(
|
|
|
|
|
org_data.org_id.clone(),
|
|
|
|
|
user.uuid,
|
|
|
|
|
headers.device.atype,
|
|
|
|
|
&ip.ip,
|
|
|
|
|
&headers.ip.ip,
|
|
|
|
|
&mut conn,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
@ -1563,7 +1483,6 @@ async fn _delete_cipher_by_uuid(
|
|
|
|
|
headers: &Headers,
|
|
|
|
|
conn: &mut DbConn,
|
|
|
|
|
soft_delete: bool,
|
|
|
|
|
ip: &ClientIp,
|
|
|
|
|
nt: &Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
let mut cipher = match Cipher::find_by_uuid(uuid, conn).await {
|
|
|
|
@ -1602,8 +1521,16 @@ async fn _delete_cipher_by_uuid(
|
|
|
|
|
false => EventType::CipherDeleted as i32,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
log_event(event_type, &cipher.uuid, org_uuid, headers.user.uuid.clone(), headers.device.atype, &ip.ip, conn)
|
|
|
|
|
.await;
|
|
|
|
|
log_event(
|
|
|
|
|
event_type,
|
|
|
|
|
&cipher.uuid,
|
|
|
|
|
org_uuid,
|
|
|
|
|
headers.user.uuid.clone(),
|
|
|
|
|
headers.device.atype,
|
|
|
|
|
&headers.ip.ip,
|
|
|
|
|
conn,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
@ -1614,7 +1541,6 @@ async fn _delete_multiple_ciphers(
|
|
|
|
|
headers: Headers,
|
|
|
|
|
mut conn: DbConn,
|
|
|
|
|
soft_delete: bool,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
let data: Value = data.into_inner().data;
|
|
|
|
@ -1628,7 +1554,7 @@ async fn _delete_multiple_ciphers(
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for uuid in uuids {
|
|
|
|
|
if let error @ Err(_) = _delete_cipher_by_uuid(uuid, &headers, &mut conn, soft_delete, &ip, &nt).await {
|
|
|
|
|
if let error @ Err(_) = _delete_cipher_by_uuid(uuid, &headers, &mut conn, soft_delete, &nt).await {
|
|
|
|
|
return error;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
@ -1636,13 +1562,7 @@ async fn _delete_multiple_ciphers(
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn _restore_cipher_by_uuid(
|
|
|
|
|
uuid: &str,
|
|
|
|
|
headers: &Headers,
|
|
|
|
|
conn: &mut DbConn,
|
|
|
|
|
ip: &ClientIp,
|
|
|
|
|
nt: &Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
async fn _restore_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &mut DbConn, nt: &Notify<'_>) -> JsonResult {
|
|
|
|
|
let mut cipher = match Cipher::find_by_uuid(uuid, conn).await {
|
|
|
|
|
Some(cipher) => cipher,
|
|
|
|
|
None => err!("Cipher doesn't exist"),
|
|
|
|
@ -1669,7 +1589,7 @@ async fn _restore_cipher_by_uuid(
|
|
|
|
|
String::from(org_uuid),
|
|
|
|
|
headers.user.uuid.clone(),
|
|
|
|
|
headers.device.atype,
|
|
|
|
|
&ip.ip,
|
|
|
|
|
&headers.ip.ip,
|
|
|
|
|
conn,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
@ -1682,7 +1602,6 @@ async fn _restore_multiple_ciphers(
|
|
|
|
|
data: JsonUpcase<Value>,
|
|
|
|
|
headers: &Headers,
|
|
|
|
|
conn: &mut DbConn,
|
|
|
|
|
ip: ClientIp,
|
|
|
|
|
nt: &Notify<'_>,
|
|
|
|
|
) -> JsonResult {
|
|
|
|
|
let data: Value = data.into_inner().data;
|
|
|
|
@ -1697,7 +1616,7 @@ async fn _restore_multiple_ciphers(
|
|
|
|
|
|
|
|
|
|
let mut ciphers: Vec<Value> = Vec::new();
|
|
|
|
|
for uuid in uuids {
|
|
|
|
|
match _restore_cipher_by_uuid(uuid, headers, conn, &ip, nt).await {
|
|
|
|
|
match _restore_cipher_by_uuid(uuid, headers, conn, nt).await {
|
|
|
|
|
Ok(json) => ciphers.push(json.into_inner()),
|
|
|
|
|
err => return err,
|
|
|
|
|
}
|
|
|
|
@ -1715,7 +1634,6 @@ async fn _delete_cipher_attachment_by_id(
|
|
|
|
|
attachment_id: &str,
|
|
|
|
|
headers: &Headers,
|
|
|
|
|
conn: &mut DbConn,
|
|
|
|
|
ip: &ClientIp,
|
|
|
|
|
nt: &Notify<'_>,
|
|
|
|
|
) -> EmptyResult {
|
|
|
|
|
let attachment = match Attachment::find_by_id(attachment_id, conn).await {
|
|
|
|
@ -1752,7 +1670,7 @@ async fn _delete_cipher_attachment_by_id(
|
|
|
|
|
org_uuid,
|
|
|
|
|
headers.user.uuid.clone(),
|
|
|
|
|
headers.device.atype,
|
|
|
|
|
&ip.ip,
|
|
|
|
|
&headers.ip.ip,
|
|
|
|
|
conn,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
|