mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-06-12 21:27:37 +02:00
Implemented proper error handling, now we can do user.save($conn)?;
and it works.
In the future, maybe we can do the same with the `find_by_id` methods that return an Option.
This commit is contained in:
@ -65,9 +65,7 @@ fn register(data: JsonUpcase<RegisterData>, conn: DbConn) -> EmptyResult {
|
||||
if CONFIG.mail.is_none() {
|
||||
for mut user_org in UserOrganization::find_invited_by_user(&user.uuid, &conn).iter_mut() {
|
||||
user_org.status = UserOrgStatus::Accepted as i32;
|
||||
if user_org.save(&conn).is_err() {
|
||||
err!("Failed to accept user to organization")
|
||||
}
|
||||
user_org.save(&conn)?;
|
||||
}
|
||||
if !Invitation::take(&data.Email, &conn) {
|
||||
err!("Error accepting invitation")
|
||||
@ -128,10 +126,7 @@ fn register(data: JsonUpcase<RegisterData>, conn: DbConn) -> EmptyResult {
|
||||
user.public_key = Some(keys.PublicKey);
|
||||
}
|
||||
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to save user"),
|
||||
}
|
||||
user.save(&conn)
|
||||
}
|
||||
|
||||
#[get("/accounts/profile")]
|
||||
@ -164,10 +159,8 @@ fn post_profile(data: JsonUpcase<ProfileData>, headers: Headers, conn: DbConn) -
|
||||
Some(ref h) if h.is_empty() => None,
|
||||
_ => data.MasterPasswordHint,
|
||||
};
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(Json(user.to_json(&conn))),
|
||||
Err(_) => err!("Failed to save user profile"),
|
||||
}
|
||||
user.save(&conn)?;
|
||||
Ok(Json(user.to_json(&conn)))
|
||||
}
|
||||
|
||||
#[get("/users/<uuid>/public-key")]
|
||||
@ -193,10 +186,8 @@ fn post_keys(data: JsonUpcase<KeysData>, headers: Headers, conn: DbConn) -> Json
|
||||
user.private_key = Some(data.EncryptedPrivateKey);
|
||||
user.public_key = Some(data.PublicKey);
|
||||
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(Json(user.to_json(&conn))),
|
||||
Err(_) => err!("Failed to save the user's keys"),
|
||||
}
|
||||
user.save(&conn)?;
|
||||
Ok(Json(user.to_json(&conn)))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -218,10 +209,7 @@ fn post_password(data: JsonUpcase<ChangePassData>, headers: Headers, conn: DbCon
|
||||
|
||||
user.set_password(&data.NewMasterPasswordHash);
|
||||
user.key = data.Key;
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to save password"),
|
||||
}
|
||||
user.save(&conn)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -248,10 +236,7 @@ fn post_kdf(data: JsonUpcase<ChangeKdfData>, headers: Headers, conn: DbConn) ->
|
||||
user.client_kdf_type = data.Kdf;
|
||||
user.set_password(&data.NewMasterPasswordHash);
|
||||
user.key = data.Key;
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to save password settings"),
|
||||
}
|
||||
user.save(&conn)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -295,9 +280,7 @@ fn post_rotatekey(data: JsonUpcase<KeyData>, headers: Headers, conn: DbConn, ws:
|
||||
}
|
||||
|
||||
saved_folder.name = folder_data.Name;
|
||||
if saved_folder.save(&conn).is_err() {
|
||||
err!("Failed to save folder")
|
||||
}
|
||||
saved_folder.save(&conn)?
|
||||
}
|
||||
|
||||
// Update cipher data
|
||||
@ -323,11 +306,7 @@ fn post_rotatekey(data: JsonUpcase<KeyData>, headers: Headers, conn: DbConn, ws:
|
||||
user.private_key = Some(data.PrivateKey);
|
||||
user.reset_security_stamp();
|
||||
|
||||
if user.save(&conn).is_err() {
|
||||
err!("Failed modify user key");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
user.save(&conn)
|
||||
}
|
||||
|
||||
#[post("/accounts/security-stamp", data = "<data>")]
|
||||
@ -340,10 +319,7 @@ fn post_sstamp(data: JsonUpcase<PasswordData>, headers: Headers, conn: DbConn) -
|
||||
}
|
||||
|
||||
user.reset_security_stamp();
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to reset security stamp"),
|
||||
}
|
||||
user.save(&conn)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -398,10 +374,7 @@ fn post_email(data: JsonUpcase<ChangeEmailData>, headers: Headers, conn: DbConn)
|
||||
user.set_password(&data.NewMasterPasswordHash);
|
||||
user.key = data.Key;
|
||||
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to save email address"),
|
||||
}
|
||||
user.save(&conn)
|
||||
}
|
||||
|
||||
#[post("/accounts/delete", data = "<data>")]
|
||||
@ -418,10 +391,7 @@ fn delete_account(data: JsonUpcase<PasswordData>, headers: Headers, conn: DbConn
|
||||
err!("Invalid password")
|
||||
}
|
||||
|
||||
match user.delete(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed deleting user account, are you the only owner of some organization?"),
|
||||
}
|
||||
user.delete(&conn)
|
||||
}
|
||||
|
||||
#[get("/accounts/revision-date")]
|
||||
@ -446,9 +416,7 @@ fn password_hint(data: JsonUpcase<PasswordHintData>, conn: DbConn) -> EmptyResul
|
||||
};
|
||||
|
||||
if let Some(ref mail_config) = CONFIG.mail {
|
||||
if let Err(e) = mail::send_password_hint(&data.Email, hint, mail_config) {
|
||||
err!(format!("There have been a problem sending the email: {}", e));
|
||||
}
|
||||
mail::send_password_hint(&data.Email, hint, mail_config)?;
|
||||
} else if CONFIG.show_password_hint {
|
||||
if let Some(hint) = hint {
|
||||
err!(format!("Your password hint is: {}", &hint));
|
||||
|
@ -182,10 +182,7 @@ fn post_ciphers_admin(data: JsonUpcase<ShareCipherData>, headers: Headers, conn:
|
||||
|
||||
let mut cipher = Cipher::new(data.Cipher.Type, data.Cipher.Name.clone());
|
||||
cipher.user_uuid = Some(headers.user.uuid.clone());
|
||||
match cipher.save(&conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed saving cipher")
|
||||
};
|
||||
cipher.save(&conn)?;
|
||||
|
||||
share_cipher_by_uuid(&cipher.uuid, data, &headers, &conn, &ws)
|
||||
}
|
||||
@ -248,10 +245,7 @@ pub fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &
|
||||
saved_att.key = Some(attachment.Key);
|
||||
saved_att.file_name = attachment.FileName;
|
||||
|
||||
match saved_att.save(&conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed to save attachment")
|
||||
};
|
||||
saved_att.save(&conn)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,17 +278,11 @@ pub fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &
|
||||
cipher.data = type_data.to_string();
|
||||
cipher.password_history = data.PasswordHistory.map(|f| f.to_string());
|
||||
|
||||
match cipher.save(&conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed to save cipher")
|
||||
};
|
||||
cipher.save(&conn)?;
|
||||
|
||||
ws.send_cipher_update(ut, &cipher, &cipher.update_users_revision(&conn));
|
||||
|
||||
if cipher.move_to_folder(data.FolderId, &headers.user.uuid, &conn).is_err() {
|
||||
err!("Error saving the folder information")
|
||||
}
|
||||
|
||||
Ok(())
|
||||
cipher.move_to_folder(data.FolderId, &headers.user.uuid, &conn)
|
||||
}
|
||||
|
||||
use super::folders::FolderData;
|
||||
@ -325,11 +313,9 @@ fn post_ciphers_import(data: JsonUpcase<ImportData>, headers: Headers, conn: DbC
|
||||
let mut folders: Vec<_> = Vec::new();
|
||||
for folder in data.Folders.into_iter() {
|
||||
let mut new_folder = Folder::new(headers.user.uuid.clone(), folder.Name);
|
||||
if new_folder.save(&conn).is_err() {
|
||||
err!("Failed importing folders")
|
||||
} else {
|
||||
folders.push(new_folder);
|
||||
}
|
||||
new_folder.save(&conn)?;
|
||||
|
||||
folders.push(new_folder);
|
||||
}
|
||||
|
||||
// Read the relations between folders and ciphers
|
||||
@ -351,10 +337,7 @@ fn post_ciphers_import(data: JsonUpcase<ImportData>, headers: Headers, conn: DbC
|
||||
}
|
||||
|
||||
let mut user = headers.user;
|
||||
match user.update_revision(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to update the revision, please log out and log back in to finish import.")
|
||||
}
|
||||
user.update_revision(&conn)
|
||||
}
|
||||
|
||||
|
||||
@ -429,15 +412,9 @@ fn post_collections_admin(uuid: String, data: JsonUpcase<CollectionsAdminData>,
|
||||
Some(collection) => {
|
||||
if collection.is_writable_by_user(&headers.user.uuid, &conn) {
|
||||
if posted_collections.contains(&collection.uuid) { // Add to collection
|
||||
match CollectionCipher::save(&cipher.uuid, &collection.uuid, &conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed to add cipher to collection")
|
||||
};
|
||||
CollectionCipher::save(&cipher.uuid, &collection.uuid, &conn)?;
|
||||
} else { // Remove from collection
|
||||
match CollectionCipher::delete(&cipher.uuid, &collection.uuid, &conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed to remove cipher from collection")
|
||||
};
|
||||
CollectionCipher::delete(&cipher.uuid, &collection.uuid, &conn)?;
|
||||
}
|
||||
} else {
|
||||
err!("No rights to modify the collection")
|
||||
@ -540,10 +517,7 @@ fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, co
|
||||
None => err!("Invalid collection ID provided"),
|
||||
Some(collection) => {
|
||||
if collection.is_writable_by_user(&headers.user.uuid, &conn) {
|
||||
match CollectionCipher::save(&cipher.uuid.clone(), &collection.uuid, &conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed to add cipher to collection")
|
||||
};
|
||||
CollectionCipher::save(&cipher.uuid.clone(), &collection.uuid, &conn)?;
|
||||
shared_to_collection = true;
|
||||
} else {
|
||||
err!("No rights to modify the collection")
|
||||
@ -614,10 +588,7 @@ fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers
|
||||
|
||||
let mut attachment = Attachment::new(file_name, cipher.uuid.clone(), name, size);
|
||||
attachment.key = attachment_key.clone();
|
||||
match attachment.save(&conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => error!("Failed to save attachment")
|
||||
};
|
||||
attachment.save(&conn).expect("Error saving attachment");
|
||||
},
|
||||
_ => error!("Invalid multipart name")
|
||||
}
|
||||
@ -746,13 +717,9 @@ fn move_cipher_selected(data: JsonUpcase<Value>, headers: Headers, conn: DbConn,
|
||||
}
|
||||
|
||||
// Move cipher
|
||||
if cipher.move_to_folder(folder_id.clone(), &headers.user.uuid, &conn).is_err() {
|
||||
err!("Error saving the folder information")
|
||||
}
|
||||
match cipher.save(&conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed to save cipher")
|
||||
};
|
||||
cipher.move_to_folder(folder_id.clone(), &headers.user.uuid, &conn)?;
|
||||
cipher.save(&conn)?;
|
||||
|
||||
ws.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &cipher.update_users_revision(&conn));
|
||||
}
|
||||
|
||||
@ -777,21 +744,14 @@ fn delete_all(data: JsonUpcase<PasswordData>, headers: Headers, conn: DbConn, ws
|
||||
|
||||
// Delete ciphers and their attachments
|
||||
for cipher in Cipher::find_owned_by_user(&user.uuid, &conn) {
|
||||
if cipher.delete(&conn).is_err() {
|
||||
err!("Failed deleting cipher")
|
||||
}
|
||||
else {
|
||||
ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn));
|
||||
}
|
||||
cipher.delete(&conn)?;
|
||||
ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn));
|
||||
}
|
||||
|
||||
// Delete folders
|
||||
for f in Folder::find_by_user(&user.uuid, &conn) {
|
||||
if f.delete(&conn).is_err() {
|
||||
err!("Failed deleting folder")
|
||||
} else {
|
||||
ws.send_folder_update(UpdateType::SyncFolderCreate, &f);
|
||||
}
|
||||
f.delete(&conn)?;
|
||||
ws.send_folder_update(UpdateType::SyncFolderCreate, &f);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -807,13 +767,9 @@ fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn, ws: &Sta
|
||||
err!("Cipher can't be deleted by user")
|
||||
}
|
||||
|
||||
match cipher.delete(&conn) {
|
||||
Ok(()) => {
|
||||
ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn));
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => err!("Failed deleting cipher")
|
||||
}
|
||||
cipher.delete(&conn)?;
|
||||
ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn _delete_cipher_attachment_by_id(uuid: &str, attachment_id: &str, headers: &Headers, conn: &DbConn, ws: &State<WebSocketUsers>) -> EmptyResult {
|
||||
@ -836,11 +792,7 @@ fn _delete_cipher_attachment_by_id(uuid: &str, attachment_id: &str, headers: &He
|
||||
}
|
||||
|
||||
// Delete attachment
|
||||
match attachment.delete(&conn) {
|
||||
Ok(()) => {
|
||||
ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn));
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => err!("Deleting attachment failed")
|
||||
}
|
||||
attachment.delete(&conn)?;
|
||||
ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -62,9 +62,7 @@ fn post_folders(data: JsonUpcase<FolderData>, headers: Headers, conn: DbConn, ws
|
||||
|
||||
let mut folder = Folder::new(headers.user.uuid.clone(), data.Name);
|
||||
|
||||
if folder.save(&conn).is_err() {
|
||||
err!("Failed to save folder")
|
||||
}
|
||||
folder.save(&conn)?;
|
||||
ws.send_folder_update(UpdateType::SyncFolderCreate, &folder);
|
||||
|
||||
Ok(Json(folder.to_json()))
|
||||
@ -90,9 +88,7 @@ fn put_folder(uuid: String, data: JsonUpcase<FolderData>, headers: Headers, conn
|
||||
|
||||
folder.name = data.Name;
|
||||
|
||||
if folder.save(&conn).is_err() {
|
||||
err!("Failed to save folder")
|
||||
}
|
||||
folder.save(&conn)?;
|
||||
ws.send_folder_update(UpdateType::SyncFolderUpdate, &folder);
|
||||
|
||||
Ok(Json(folder.to_json()))
|
||||
@ -115,11 +111,8 @@ fn delete_folder(uuid: String, headers: Headers, conn: DbConn, ws: State<WebSock
|
||||
}
|
||||
|
||||
// Delete the actual folder entry
|
||||
match folder.delete(&conn) {
|
||||
Ok(()) => {
|
||||
ws.send_folder_update(UpdateType::SyncFolderDelete, &folder);
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => err!("Failed deleting folder")
|
||||
}
|
||||
folder.delete(&conn)?;
|
||||
|
||||
ws.send_folder_update(UpdateType::SyncFolderDelete, &folder);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -120,10 +120,9 @@ fn post_eq_domains(data: JsonUpcase<EquivDomainData>, headers: Headers, conn: Db
|
||||
user.excluded_globals = to_string(&excluded_globals).unwrap_or("[]".to_string());
|
||||
user.equivalent_domains = to_string(&equivalent_domains).unwrap_or("[]".to_string());
|
||||
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(Json(json!({}))),
|
||||
Err(_) => err!("Failed to save user"),
|
||||
}
|
||||
user.save(&conn)?;
|
||||
|
||||
Ok(Json(json!({})))
|
||||
}
|
||||
|
||||
#[put("/settings/domains", data = "<data>")]
|
||||
|
@ -93,16 +93,9 @@ fn create_organization(headers: Headers, data: JsonUpcase<OrgData>, conn: DbConn
|
||||
user_org.type_ = UserOrgType::Owner as i32;
|
||||
user_org.status = UserOrgStatus::Confirmed as i32;
|
||||
|
||||
if org.save(&conn).is_err() {
|
||||
err!("Failed creating organization")
|
||||
}
|
||||
if user_org.save(&conn).is_err() {
|
||||
err!("Failed to add user to organization")
|
||||
}
|
||||
|
||||
if collection.save(&conn).is_err() {
|
||||
err!("Failed creating Collection");
|
||||
}
|
||||
org.save(&conn)?;
|
||||
user_org.save(&conn)?;
|
||||
collection.save(&conn)?;
|
||||
|
||||
Ok(Json(org.to_json()))
|
||||
}
|
||||
@ -118,10 +111,7 @@ fn delete_organization(org_id: String, data: JsonUpcase<PasswordData>, headers:
|
||||
|
||||
match Organization::find_by_uuid(&org_id, &conn) {
|
||||
None => err!("Organization not found"),
|
||||
Some(org) => match org.delete(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed deleting the organization")
|
||||
}
|
||||
Some(org) => org.delete(&conn)
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,10 +135,7 @@ fn leave_organization(org_id: String, headers: Headers, conn: DbConn) -> EmptyRe
|
||||
}
|
||||
}
|
||||
|
||||
match user_org.delete(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed leaving the organization")
|
||||
}
|
||||
user_org.delete(&conn)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,10 +165,8 @@ fn post_organization(org_id: String, _headers: OwnerHeaders, data: JsonUpcase<Or
|
||||
org.name = data.Name;
|
||||
org.billing_email = data.BillingEmail;
|
||||
|
||||
match org.save(&conn) {
|
||||
Ok(()) => Ok(Json(org.to_json())),
|
||||
Err(_) => err!("Failed to modify organization")
|
||||
}
|
||||
org.save(&conn)?;
|
||||
Ok(Json(org.to_json()))
|
||||
}
|
||||
|
||||
// GET /api/collections?writeOnly=false
|
||||
@ -222,10 +207,7 @@ fn post_organization_collections(org_id: String, _headers: AdminHeaders, data: J
|
||||
};
|
||||
|
||||
let mut collection = Collection::new(org.uuid.clone(), data.Name);
|
||||
|
||||
if collection.save(&conn).is_err() {
|
||||
err!("Failed saving Collection");
|
||||
}
|
||||
collection.save(&conn)?;
|
||||
|
||||
Ok(Json(collection.to_json()))
|
||||
}
|
||||
@ -254,9 +236,7 @@ fn post_organization_collection_update(org_id: String, col_id: String, _headers:
|
||||
}
|
||||
|
||||
collection.name = data.Name.clone();
|
||||
if collection.save(&conn).is_err() {
|
||||
err!("Failed updating Collection");
|
||||
}
|
||||
collection.save(&conn)?;
|
||||
|
||||
Ok(Json(collection.to_json()))
|
||||
}
|
||||
@ -279,10 +259,7 @@ fn delete_organization_collection_user(org_id: String, col_id: String, org_user_
|
||||
match CollectionUser::find_by_collection_and_user(&collection.uuid, &user_org.user_uuid, &conn) {
|
||||
None => err!("User not assigned to collection"),
|
||||
Some(col_user) => {
|
||||
match col_user.delete(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed removing user from collection")
|
||||
}
|
||||
col_user.delete(&conn)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -299,10 +276,7 @@ fn delete_organization_collection(org_id: String, col_id: String, _headers: Admi
|
||||
match Collection::find_by_uuid(&col_id, &conn) {
|
||||
None => err!("Collection not found"),
|
||||
Some(collection) => if collection.org_uuid == org_id {
|
||||
match collection.delete(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed deleting collection")
|
||||
}
|
||||
collection.delete(&conn)
|
||||
} else {
|
||||
err!("Collection and Organization id do not match")
|
||||
}
|
||||
@ -435,18 +409,11 @@ fn send_invite(org_id: String, data: JsonUpcase<InviteData>, headers: AdminHeade
|
||||
let user = match User::find_by_mail(&email, &conn) {
|
||||
None => if CONFIG.invitations_allowed { // Invite user if that's enabled
|
||||
let mut invitation = Invitation::new(email.clone());
|
||||
match invitation.save(&conn) {
|
||||
Ok(()) => {
|
||||
let mut user = User::new(email.clone());
|
||||
if user.save(&conn).is_err() {
|
||||
err!("Failed to create placeholder for invited user")
|
||||
} else {
|
||||
user_org_status = UserOrgStatus::Invited as i32;
|
||||
user
|
||||
}
|
||||
}
|
||||
Err(_) => err!(format!("Failed to invite: {}", email))
|
||||
}
|
||||
invitation.save(&conn)?;
|
||||
let mut user = User::new(email.clone());
|
||||
user.save(&conn)?;
|
||||
user_org_status = UserOrgStatus::Invited as i32;
|
||||
user
|
||||
|
||||
} else {
|
||||
err!(format!("User email does not exist: {}", email))
|
||||
@ -474,17 +441,13 @@ fn send_invite(org_id: String, data: JsonUpcase<InviteData>, headers: AdminHeade
|
||||
match Collection::find_by_uuid_and_org(&col.Id, &org_id, &conn) {
|
||||
None => err!("Collection not found in Organization"),
|
||||
Some(collection) => {
|
||||
if CollectionUser::save(&user.uuid, &collection.uuid, col.ReadOnly, &conn).is_err() {
|
||||
err!("Failed saving collection access for user")
|
||||
}
|
||||
CollectionUser::save(&user.uuid, &collection.uuid, col.ReadOnly, &conn)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if new_user.save(&conn).is_err() {
|
||||
err!("Failed to add user to organization")
|
||||
}
|
||||
new_user.save(&conn)?;
|
||||
org_user_id = Some(new_user.uuid.clone());
|
||||
}
|
||||
|
||||
@ -627,10 +590,7 @@ fn confirm_invite(org_id: String, org_user_id: String, data: JsonUpcase<Value>,
|
||||
None => err!("Invalid key provided")
|
||||
};
|
||||
|
||||
match user_to_confirm.save(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to add user to organization")
|
||||
}
|
||||
user_to_confirm.save(&conn)
|
||||
}
|
||||
|
||||
#[get("/organizations/<org_id>/users/<org_user_id>")]
|
||||
@ -702,9 +662,7 @@ fn edit_user(org_id: String, org_user_id: String, data: JsonUpcase<EditUserData>
|
||||
|
||||
// Delete all the odd collections
|
||||
for c in CollectionUser::find_by_organization_and_user_uuid(&org_id, &user_to_edit.user_uuid, &conn) {
|
||||
if c.delete(&conn).is_err() {
|
||||
err!("Failed deleting old collection assignment")
|
||||
}
|
||||
c.delete(&conn)?;
|
||||
}
|
||||
|
||||
// If no accessAll, add the collections received
|
||||
@ -713,18 +671,13 @@ fn edit_user(org_id: String, org_user_id: String, data: JsonUpcase<EditUserData>
|
||||
match Collection::find_by_uuid_and_org(&col.Id, &org_id, &conn) {
|
||||
None => err!("Collection not found in Organization"),
|
||||
Some(collection) => {
|
||||
if CollectionUser::save(&user_to_edit.user_uuid, &collection.uuid, col.ReadOnly, &conn).is_err() {
|
||||
err!("Failed saving collection access for user")
|
||||
}
|
||||
CollectionUser::save(&user_to_edit.user_uuid, &collection.uuid, col.ReadOnly, &conn)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match user_to_edit.save(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to save user data")
|
||||
}
|
||||
user_to_edit.save(&conn)
|
||||
}
|
||||
|
||||
#[delete("/organizations/<org_id>/users/<org_user_id>")]
|
||||
@ -736,10 +689,7 @@ fn delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn:
|
||||
if user_to_delete.uuid == headers.user.uuid {
|
||||
err!("Delete your account in the account settings")
|
||||
} else {
|
||||
match user_to_delete.delete(&conn) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(_) => err!("Failed to delete user - likely because it's the only owner of organization")
|
||||
}
|
||||
user_to_delete.delete(&conn)?;
|
||||
}
|
||||
},
|
||||
None => err!("User not found")
|
||||
@ -767,10 +717,7 @@ fn delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn:
|
||||
}
|
||||
}
|
||||
|
||||
match user_to_delete.delete(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed deleting user from organization")
|
||||
}
|
||||
user_to_delete.delete(&conn)
|
||||
}
|
||||
|
||||
#[post("/organizations/<org_id>/users/<org_user_id>/delete")]
|
||||
@ -844,15 +791,9 @@ fn post_org_import(query: Form<OrgIdData>, data: JsonUpcase<ImportData>, headers
|
||||
Err(_) => err!("Failed to assign to collection")
|
||||
};
|
||||
|
||||
match CollectionCipher::save(cipher_id, coll_id, &conn) {
|
||||
Ok(()) => (),
|
||||
Err(_) => err!("Failed to add cipher to collection")
|
||||
};
|
||||
CollectionCipher::save(cipher_id, coll_id, &conn)?;
|
||||
}
|
||||
|
||||
let mut user = headers.user;
|
||||
match user.update_revision(&conn) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_) => err!("Failed to update the revision, please log out and log back in to finish import.")
|
||||
}
|
||||
user.update_revision(&conn)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use crate::db::{
|
||||
|
||||
use crate::crypto;
|
||||
|
||||
use crate::api::{ApiResult, JsonResult, JsonUpcase, NumberOrString, PasswordData};
|
||||
use crate::api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData};
|
||||
use crate::auth::Headers;
|
||||
|
||||
use rocket::Route;
|
||||
@ -99,10 +99,8 @@ fn recover(data: JsonUpcase<RecoverTwoFactor>, conn: DbConn) -> JsonResult {
|
||||
|
||||
// Remove the recovery code, not needed without twofactors
|
||||
user.totp_recover = None;
|
||||
match user.save(&conn) {
|
||||
Ok(()) => Ok(Json(json!({}))),
|
||||
Err(_) => err!("Failed to remove the user's two factor recovery code")
|
||||
}
|
||||
user.save(&conn)?;
|
||||
Ok(Json(json!({})))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -242,9 +240,7 @@ fn _generate_recover_code(user: &mut User, conn: &DbConn) {
|
||||
if user.totp_recover.is_none() {
|
||||
let totp_recover = BASE32.encode(&crypto::get_random(vec![0u8; 20]));
|
||||
user.totp_recover = Some(totp_recover);
|
||||
if user.save(conn).is_err() {
|
||||
error!("Failed to save the user's two factor recovery code")
|
||||
}
|
||||
user.save(conn).ok();
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,15 +345,11 @@ fn activate_u2f(data: JsonUpcase<EnableU2FData>, headers: Headers, conn: DbConn)
|
||||
);
|
||||
|
||||
if let Some(tf_challenge) = tf_challenge {
|
||||
let challenge: Challenge = serde_json::from_str(&tf_challenge.data)
|
||||
.expect("Can't parse U2fRegisterChallenge data");
|
||||
let challenge: Challenge = serde_json::from_str(&tf_challenge.data)?;
|
||||
|
||||
tf_challenge
|
||||
.delete(&conn)
|
||||
.expect("Error deleting U2F register challenge");
|
||||
tf_challenge.delete(&conn)?;
|
||||
|
||||
let response_copy: RegisterResponseCopy =
|
||||
serde_json::from_str(&data.DeviceResponse).expect("Can't parse RegisterResponse data");
|
||||
let response_copy: RegisterResponseCopy = serde_json::from_str(&data.DeviceResponse)?;
|
||||
|
||||
let error_code = response_copy
|
||||
.error_code
|
||||
@ -370,40 +362,31 @@ fn activate_u2f(data: JsonUpcase<EnableU2FData>, headers: Headers, conn: DbConn)
|
||||
|
||||
let response = response_copy.into_response(challenge.challenge.clone());
|
||||
|
||||
match U2F.register_response(challenge.clone(), response) {
|
||||
Ok(registration) => {
|
||||
// TODO: Allow more than one U2F device
|
||||
let mut registrations = Vec::new();
|
||||
registrations.push(registration);
|
||||
let registration = U2F.register_response(challenge.clone(), response)?;
|
||||
// TODO: Allow more than one U2F device
|
||||
let mut registrations = Vec::new();
|
||||
registrations.push(registration);
|
||||
|
||||
let tf_registration = TwoFactor::new(
|
||||
headers.user.uuid.clone(),
|
||||
TwoFactorType::U2f,
|
||||
serde_json::to_string(®istrations).unwrap(),
|
||||
);
|
||||
tf_registration
|
||||
.save(&conn)
|
||||
.expect("Error saving U2F registration");
|
||||
let tf_registration = TwoFactor::new(
|
||||
headers.user.uuid.clone(),
|
||||
TwoFactorType::U2f,
|
||||
serde_json::to_string(®istrations).unwrap(),
|
||||
);
|
||||
tf_registration.save(&conn)?;
|
||||
|
||||
let mut user = headers.user;
|
||||
_generate_recover_code(&mut user, &conn);
|
||||
let mut user = headers.user;
|
||||
_generate_recover_code(&mut user, &conn);
|
||||
|
||||
Ok(Json(json!({
|
||||
"Enabled": true,
|
||||
"Challenge": {
|
||||
"UserId": user.uuid,
|
||||
"AppId": APP_ID.to_string(),
|
||||
"Challenge": challenge,
|
||||
"Version": U2F_VERSION,
|
||||
},
|
||||
"Object": "twoFactorU2f"
|
||||
})))
|
||||
}
|
||||
Err(e) => {
|
||||
error!("{:#?}", e);
|
||||
err!("Error activating u2f")
|
||||
}
|
||||
}
|
||||
Ok(Json(json!({
|
||||
"Enabled": true,
|
||||
"Challenge": {
|
||||
"UserId": user.uuid,
|
||||
"AppId": APP_ID.to_string(),
|
||||
"Challenge": challenge,
|
||||
"Version": U2F_VERSION,
|
||||
},
|
||||
"Object": "twoFactorU2f"
|
||||
})))
|
||||
} else {
|
||||
err!("Can't recover challenge")
|
||||
}
|
||||
@ -469,7 +452,7 @@ pub fn generate_u2f_login(user_uuid: &str, conn: &DbConn) -> ApiResult<U2fSignRe
|
||||
Ok(signed_request)
|
||||
}
|
||||
|
||||
pub fn validate_u2f_login(user_uuid: &str, response: &str, conn: &DbConn) -> ApiResult<()> {
|
||||
pub fn validate_u2f_login(user_uuid: &str, response: &str, conn: &DbConn) -> EmptyResult {
|
||||
let challenge_type = TwoFactorType::U2fLoginChallenge as i32;
|
||||
let u2f_type = TwoFactorType::U2f as i32;
|
||||
|
||||
@ -477,11 +460,8 @@ pub fn validate_u2f_login(user_uuid: &str, response: &str, conn: &DbConn) -> Api
|
||||
|
||||
let challenge = match tf_challenge {
|
||||
Some(tf_challenge) => {
|
||||
let challenge: Challenge = serde_json::from_str(&tf_challenge.data)
|
||||
.expect("Can't parse U2fLoginChallenge data");
|
||||
tf_challenge
|
||||
.delete(&conn)
|
||||
.expect("Error deleting U2F login challenge");
|
||||
let challenge: Challenge = serde_json::from_str(&tf_challenge.data)?;
|
||||
tf_challenge.delete(&conn)?;
|
||||
challenge
|
||||
}
|
||||
None => err!("Can't recover login challenge"),
|
||||
@ -494,8 +474,7 @@ pub fn validate_u2f_login(user_uuid: &str, response: &str, conn: &DbConn) -> Api
|
||||
|
||||
let registrations = _parse_registrations(&twofactor.data);
|
||||
|
||||
let response: SignResponse =
|
||||
serde_json::from_str(response).expect("Can't parse SignResponse data");
|
||||
let response: SignResponse = serde_json::from_str(response)?;
|
||||
|
||||
let mut _counter: u32 = 0;
|
||||
for registration in registrations {
|
||||
@ -614,8 +593,7 @@ fn generate_yubikey(data: JsonUpcase<PasswordData>, headers: Headers, conn: DbCo
|
||||
let r = TwoFactor::find_by_user_and_type(user_uuid, yubikey_type, &conn);
|
||||
|
||||
if let Some(r) = r {
|
||||
let yubikey_metadata: YubikeyMetadata =
|
||||
serde_json::from_str(&r.data).expect("Can't parse YubikeyMetadata data");
|
||||
let yubikey_metadata: YubikeyMetadata = serde_json::from_str(&r.data)?;
|
||||
|
||||
let mut result = jsonify_yubikeys(yubikey_metadata.Keys);
|
||||
|
||||
@ -648,7 +626,7 @@ fn activate_yubikey(data: JsonUpcase<EnableYubikeyData>, headers: Headers, conn:
|
||||
);
|
||||
|
||||
if let Some(yubikey_data) = yubikey_data {
|
||||
yubikey_data.delete(&conn).expect("Error deleting current Yubikeys");
|
||||
yubikey_data.delete(&conn)?;
|
||||
}
|
||||
|
||||
let yubikeys = parse_yubikeys(&data);
|
||||
@ -686,8 +664,7 @@ fn activate_yubikey(data: JsonUpcase<EnableYubikeyData>, headers: Headers, conn:
|
||||
TwoFactorType::YubiKey,
|
||||
serde_json::to_string(&yubikey_metadata).unwrap(),
|
||||
);
|
||||
yubikey_registration
|
||||
.save(&conn).expect("Failed to save Yubikey info");
|
||||
yubikey_registration.save(&conn)?;
|
||||
|
||||
let mut result = jsonify_yubikeys(yubikey_metadata.Keys);
|
||||
|
||||
@ -703,7 +680,7 @@ fn activate_yubikey_put(data: JsonUpcase<EnableYubikeyData>, headers: Headers, c
|
||||
activate_yubikey(data, headers, conn)
|
||||
}
|
||||
|
||||
pub fn validate_yubikey_login(user_uuid: &str, response: &str, conn: &DbConn) -> ApiResult<()> {
|
||||
pub fn validate_yubikey_login(user_uuid: &str, response: &str, conn: &DbConn) -> EmptyResult {
|
||||
if response.len() != 44 {
|
||||
err!("Invalid Yubikey OTP length");
|
||||
}
|
||||
|
Reference in New Issue
Block a user