1
0
Fork 0
mirror of https://github.com/dani-garcia/vaultwarden.git synced 2025-09-06 09:42:41 +00: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:
Daniel García 2018-12-19 21:52:53 +01:00
commit 6a99849a1e
No known key found for this signature in database
GPG key ID: FC8A7D14C3CD543A
22 changed files with 472 additions and 487 deletions

View file

@ -12,7 +12,7 @@ pub struct Attachment {
pub cipher_uuid: String,
pub file_name: String,
pub file_size: i32,
pub key: Option<String>
pub key: Option<String>,
}
/// Local methods
@ -23,7 +23,7 @@ impl Attachment {
cipher_uuid,
file_name,
file_size,
key: None
key: None,
}
}
@ -54,29 +54,31 @@ use diesel::prelude::*;
use crate::db::DbConn;
use crate::db::schema::attachments;
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl Attachment {
pub fn save(&self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&self, conn: &DbConn) -> EmptyResult {
diesel::replace_into(attachments::table)
.values(self)
.execute(&**conn)
.and(Ok(()))
.map_res("Error saving attachment")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
crate::util::retry(
|| {
diesel::delete(attachments::table.filter(attachments::id.eq(&self.id)))
.execute(&**conn)
},
|| diesel::delete(attachments::table.filter(attachments::id.eq(&self.id)))
.execute(&**conn),
10,
)?;
)
.map_res("Error deleting attachment")?;
crate::util::delete_file(&self.get_file_path());
Ok(())
}
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> EmptyResult {
for attachment in Attachment::find_by_cipher(&cipher_uuid, &conn) {
attachment.delete(&conn)?;
}
@ -84,20 +86,20 @@ impl Attachment {
}
pub fn find_by_id(id: &str, conn: &DbConn) -> Option<Self> {
attachments::table
.filter(attachments::id.eq(id))
.first::<Self>(&**conn).ok()
attachments::table.filter(attachments::id.eq(id)).first::<Self>(&**conn).ok()
}
pub fn find_by_cipher(cipher_uuid: &str, conn: &DbConn) -> Vec<Self> {
attachments::table
.filter(attachments::cipher_uuid.eq(cipher_uuid))
.load::<Self>(&**conn).expect("Error loading attachments")
.load::<Self>(&**conn)
.expect("Error loading attachments")
}
pub fn find_by_ciphers(cipher_uuids: Vec<String>, conn: &DbConn) -> Vec<Self> {
attachments::table
.filter(attachments::cipher_uuid.eq_any(cipher_uuids))
.load::<Self>(&**conn).expect("Error loading attachments")
.load::<Self>(&**conn)
.expect("Error loading attachments")
}
}

View file

@ -1,7 +1,7 @@
use chrono::{NaiveDateTime, Utc};
use serde_json::Value;
use super::{User, Organization, Attachment, FolderCipher, CollectionCipher, UserOrganization, UserOrgType, UserOrgStatus};
use super::{Attachment, CollectionCipher, FolderCipher, Organization, User, UserOrgStatus, UserOrgType, UserOrganization};
#[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
#[table_name = "ciphers"]
@ -59,17 +59,20 @@ impl Cipher {
}
}
use crate::db::schema::*;
use crate::db::DbConn;
use diesel;
use diesel::prelude::*;
use crate::db::DbConn;
use crate::db::schema::*;
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl Cipher {
pub fn to_json(&self, host: &str, user_uuid: &str, conn: &DbConn) -> Value {
use serde_json;
use crate::util::format_date;
use super::Attachment;
use crate::util::format_date;
use serde_json;
let attachments = Attachment::find_by_cipher(&self.uuid, conn);
let attachments_json: Vec<Value> = attachments.iter().map(|c| c.to_json(host)).collect();
@ -149,56 +152,54 @@ impl Cipher {
user_uuids
}
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
self.update_users_revision(conn);
self.updated_at = Utc::now().naive_utc();
diesel::replace_into(ciphers::table)
.values(&*self)
.execute(&**conn)
.and(Ok(()))
.map_res("Error saving cipher")
}
pub fn delete(&self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(&self, conn: &DbConn) -> EmptyResult {
self.update_users_revision(conn);
FolderCipher::delete_all_by_cipher(&self.uuid, &conn)?;
CollectionCipher::delete_all_by_cipher(&self.uuid, &conn)?;
Attachment::delete_all_by_cipher(&self.uuid, &conn)?;
diesel::delete(
ciphers::table.filter(
ciphers::uuid.eq(&self.uuid)
)
).execute(&**conn).and(Ok(()))
diesel::delete(ciphers::table.filter(ciphers::uuid.eq(&self.uuid)))
.execute(&**conn)
.map_res("Error deleting cipher")
}
pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> EmptyResult {
for cipher in Self::find_by_org(org_uuid, &conn) {
cipher.delete(&conn)?;
}
Ok(())
}
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult {
for cipher in Self::find_owned_by_user(user_uuid, &conn) {
cipher.delete(&conn)?;
}
Ok(())
}
pub fn move_to_folder(&self, folder_uuid: Option<String>, user_uuid: &str, conn: &DbConn) -> Result<(), &str> {
match self.get_folder_uuid(&user_uuid, &conn) {
pub fn move_to_folder(&self, folder_uuid: Option<String>, user_uuid: &str, conn: &DbConn) -> EmptyResult {
match self.get_folder_uuid(&user_uuid, &conn) {
None => {
match folder_uuid {
Some(new_folder) => {
self.update_users_revision(conn);
let folder_cipher = FolderCipher::new(&new_folder, &self.uuid);
folder_cipher.save(&conn).or(Err("Couldn't save folder setting"))
},
None => Ok(()) //nothing to do
folder_cipher.save(&conn)
}
None => Ok(()), //nothing to do
}
},
}
Some(current_folder) => {
match folder_uuid {
Some(new_folder) => {
@ -206,24 +207,17 @@ impl Cipher {
Ok(()) //nothing to do
} else {
self.update_users_revision(conn);
match FolderCipher::find_by_folder_and_cipher(&current_folder, &self.uuid, &conn) {
Some(current_folder) => {
current_folder.delete(&conn).or(Err("Failed removing old folder mapping"))
},
None => Ok(()) // Weird, but nothing to do
}.and_then(
|()| FolderCipher::new(&new_folder, &self.uuid)
.save(&conn).or(Err("Couldn't save folder setting"))
)
if let Some(current_folder) = FolderCipher::find_by_folder_and_cipher(&current_folder, &self.uuid, &conn) {
current_folder.delete(&conn)?;
}
FolderCipher::new(&new_folder, &self.uuid).save(&conn)
}
},
}
None => {
self.update_users_revision(conn);
match FolderCipher::find_by_folder_and_cipher(&current_folder, &self.uuid, &conn) {
Some(current_folder) => {
current_folder.delete(&conn).or(Err("Failed removing old folder mapping"))
},
None => Err("Couldn't move from previous folder")
Some(current_folder) => current_folder.delete(&conn),
None => err!("Couldn't move from previous folder"),
}
}
}

View file

@ -38,9 +38,12 @@ use diesel::prelude::*;
use crate::db::DbConn;
use crate::db::schema::*;
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl Collection {
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
// Update affected users revision
UserOrganization::find_by_collection_and_org(&self.uuid, &self.org_uuid, conn)
.iter()
@ -51,10 +54,10 @@ impl Collection {
diesel::replace_into(collections::table)
.values(&*self)
.execute(&**conn)
.and(Ok(()))
.map_res("Error saving collection")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
CollectionCipher::delete_all_by_collection(&self.uuid, &conn)?;
CollectionUser::delete_all_by_collection(&self.uuid, &conn)?;
@ -62,10 +65,11 @@ impl Collection {
collections::table.filter(
collections::uuid.eq(self.uuid)
)
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error deleting collection")
}
pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> EmptyResult {
for collection in Self::find_by_organization(org_uuid, &conn) {
collection.delete(&conn)?;
}
@ -185,7 +189,7 @@ impl CollectionUser {
.load::<Self>(&**conn).expect("Error loading users_collections")
}
pub fn save(user_uuid: &str, collection_uuid: &str, read_only:bool, conn: &DbConn) -> QueryResult<()> {
pub fn save(user_uuid: &str, collection_uuid: &str, read_only:bool, conn: &DbConn) -> EmptyResult {
User::update_uuid_revision(&user_uuid, conn);
diesel::replace_into(users_collections::table)
@ -193,16 +197,18 @@ impl CollectionUser {
users_collections::user_uuid.eq(user_uuid),
users_collections::collection_uuid.eq(collection_uuid),
users_collections::read_only.eq(read_only),
)).execute(&**conn).and(Ok(()))
)).execute(&**conn)
.map_res("Error adding user to collection")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
User::update_uuid_revision(&self.user_uuid, conn);
diesel::delete(users_collections::table
.filter(users_collections::user_uuid.eq(&self.user_uuid))
.filter(users_collections::collection_uuid.eq(&self.collection_uuid)))
.execute(&**conn).and(Ok(()))
.execute(&**conn)
.map_res("Error removing user from collection")
}
pub fn find_by_collection(collection_uuid: &str, conn: &DbConn) -> Vec<Self> {
@ -220,7 +226,7 @@ impl CollectionUser {
.first::<Self>(&**conn).ok()
}
pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> EmptyResult {
CollectionUser::find_by_collection(&collection_uuid, conn)
.iter()
.for_each(|collection| {
@ -229,15 +235,17 @@ impl CollectionUser {
diesel::delete(users_collections::table
.filter(users_collections::collection_uuid.eq(collection_uuid))
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error deleting users from collection")
}
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult {
User::update_uuid_revision(&user_uuid, conn);
diesel::delete(users_collections::table
.filter(users_collections::user_uuid.eq(user_uuid))
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error removing user from collections")
}
}
@ -255,30 +263,34 @@ pub struct CollectionCipher {
/// Database methods
impl CollectionCipher {
pub fn save(cipher_uuid: &str, collection_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn save(cipher_uuid: &str, collection_uuid: &str, conn: &DbConn) -> EmptyResult {
diesel::replace_into(ciphers_collections::table)
.values((
ciphers_collections::cipher_uuid.eq(cipher_uuid),
ciphers_collections::collection_uuid.eq(collection_uuid),
)).execute(&**conn).and(Ok(()))
)).execute(&**conn)
.map_res("Error adding cipher to collection")
}
pub fn delete(cipher_uuid: &str, collection_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete(cipher_uuid: &str, collection_uuid: &str, conn: &DbConn) -> EmptyResult {
diesel::delete(ciphers_collections::table
.filter(ciphers_collections::cipher_uuid.eq(cipher_uuid))
.filter(ciphers_collections::collection_uuid.eq(collection_uuid)))
.execute(&**conn).and(Ok(()))
.execute(&**conn)
.map_res("Error deleting cipher from collection")
}
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> EmptyResult {
diesel::delete(ciphers_collections::table
.filter(ciphers_collections::cipher_uuid.eq(cipher_uuid))
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error removing cipher from collections")
}
pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> EmptyResult {
diesel::delete(ciphers_collections::table
.filter(ciphers_collections::collection_uuid.eq(collection_uuid))
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error removing ciphers from collection")
}
}

View file

@ -110,9 +110,12 @@ use diesel::prelude::*;
use crate::db::DbConn;
use crate::db::schema::devices;
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl Device {
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
self.updated_at = Utc::now().naive_utc();
crate::util::retry(
@ -123,16 +126,17 @@ impl Device {
},
10,
)
.and(Ok(()))
.map_res("Error saving device")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
diesel::delete(devices::table.filter(
devices::uuid.eq(self.uuid)
)).execute(&**conn).and(Ok(()))
)).execute(&**conn)
.map_res("Error removing device")
}
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult {
for device in Self::find_by_user(user_uuid, &conn) {
device.delete(&conn)?;
}

View file

@ -66,17 +66,21 @@ use diesel::prelude::*;
use crate::db::DbConn;
use crate::db::schema::{folders, folders_ciphers};
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl Folder {
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
User::update_uuid_revision(&self.user_uuid, conn);
self.updated_at = Utc::now().naive_utc();
diesel::replace_into(folders::table)
.values(&*self).execute(&**conn).and(Ok(()))
.values(&*self).execute(&**conn)
.map_res("Error saving folder")
}
pub fn delete(&self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(&self, conn: &DbConn) -> EmptyResult {
User::update_uuid_revision(&self.user_uuid, conn);
FolderCipher::delete_all_by_folder(&self.uuid, &conn)?;
@ -84,10 +88,11 @@ impl Folder {
folders::table.filter(
folders::uuid.eq(&self.uuid)
)
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error deleting folder")
}
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult {
for folder in Self::find_by_user(user_uuid, &conn) {
folder.delete(&conn)?;
}
@ -108,29 +113,33 @@ impl Folder {
}
impl FolderCipher {
pub fn save(&self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&self, conn: &DbConn) -> EmptyResult {
diesel::replace_into(folders_ciphers::table)
.values(&*self)
.execute(&**conn).and(Ok(()))
.execute(&**conn)
.map_res("Error adding cipher to folder")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
diesel::delete(folders_ciphers::table
.filter(folders_ciphers::cipher_uuid.eq(self.cipher_uuid))
.filter(folders_ciphers::folder_uuid.eq(self.folder_uuid))
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error removing cipher from folder")
}
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> EmptyResult {
diesel::delete(folders_ciphers::table
.filter(folders_ciphers::cipher_uuid.eq(cipher_uuid))
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error removing cipher from folders")
}
pub fn delete_all_by_folder(folder_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_folder(folder_uuid: &str, conn: &DbConn) -> EmptyResult {
diesel::delete(folders_ciphers::table
.filter(folders_ciphers::folder_uuid.eq(folder_uuid))
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error removing ciphers from folder")
}
pub fn find_by_folder_and_cipher(folder_uuid: &str, cipher_uuid: &str, conn: &DbConn) -> Option<Self> {

View file

@ -238,11 +238,14 @@ use diesel::prelude::*;
use crate::db::DbConn;
use crate::db::schema::{organizations, users_organizations, users_collections, ciphers_collections};
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl Organization {
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
if self.uuid == Organization::VIRTUAL_ID {
return Err(diesel::result::Error::NotFound)
err!("diesel::result::Error::NotFound")
}
UserOrganization::find_by_org(&self.uuid, conn)
@ -252,14 +255,15 @@ impl Organization {
});
diesel::replace_into(organizations::table)
.values(&*self).execute(&**conn).and(Ok(()))
.values(&*self).execute(&**conn)
.map_res("Error saving organization")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
use super::{Cipher, Collection};
if self.uuid == Organization::VIRTUAL_ID {
return Err(diesel::result::Error::NotFound)
err!("diesel::result::Error::NotFound")
}
Cipher::delete_all_by_organization(&self.uuid, &conn)?;
@ -270,7 +274,8 @@ impl Organization {
organizations::table.filter(
organizations::uuid.eq(self.uuid)
)
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error saving organization")
}
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
@ -365,19 +370,20 @@ impl UserOrganization {
})
}
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
if self.org_uuid == Organization::VIRTUAL_ID {
return Err(diesel::result::Error::NotFound)
err!("diesel::result::Error::NotFound")
}
User::update_uuid_revision(&self.user_uuid, conn);
diesel::replace_into(users_organizations::table)
.values(&*self).execute(&**conn).and(Ok(()))
.values(&*self).execute(&**conn)
.map_res("Error adding user to organization")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
if self.org_uuid == Organization::VIRTUAL_ID {
return Err(diesel::result::Error::NotFound)
err!("diesel::result::Error::NotFound")
}
User::update_uuid_revision(&self.user_uuid, conn);
@ -387,17 +393,18 @@ impl UserOrganization {
users_organizations::table.filter(
users_organizations::uuid.eq(self.uuid)
)
).execute(&**conn).and(Ok(()))
).execute(&**conn)
.map_res("Error removing user from organization")
}
pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_organization(org_uuid: &str, conn: &DbConn) -> EmptyResult {
for user_org in Self::find_by_org(&org_uuid, &conn) {
user_org.delete(&conn)?;
}
Ok(())
}
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<()> {
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult {
for user_org in Self::find_any_state_by_user(&user_uuid, &conn) {
user_org.delete(&conn)?;
}

View file

@ -79,20 +79,25 @@ use diesel::prelude::*;
use crate::db::DbConn;
use crate::db::schema::twofactor;
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl TwoFactor {
pub fn save(&self, conn: &DbConn) -> QueryResult<usize> {
pub fn save(&self, conn: &DbConn) -> EmptyResult {
diesel::replace_into(twofactor::table)
.values(self)
.execute(&**conn)
.map_res("Error saving twofactor")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<usize> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
diesel::delete(
twofactor::table.filter(
twofactor::uuid.eq(self.uuid)
)
).execute(&**conn)
.map_res("Error deleting twofactor")
}
pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec<Self> {
@ -108,11 +113,12 @@ impl TwoFactor {
.first::<Self>(&**conn).ok()
}
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<usize> {
pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult {
diesel::delete(
twofactor::table.filter(
twofactor::user_uuid.eq(user_uuid)
)
).execute(&**conn)
.map_res("Error deleting twofactors")
}
}

View file

@ -115,6 +115,9 @@ use crate::db::DbConn;
use crate::db::schema::{users, invitations};
use super::{Cipher, Folder, Device, UserOrganization, UserOrgType, TwoFactor};
use crate::api::EmptyResult;
use crate::error::MapResult;
/// Database methods
impl User {
pub fn to_json(&self, conn: &DbConn) -> Value {
@ -145,21 +148,22 @@ impl User {
}
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
self.updated_at = Utc::now().naive_utc();
diesel::replace_into(users::table) // Insert or update
.values(&*self).execute(&**conn).and(Ok(()))
.values(&*self).execute(&**conn)
.map_res("Error saving user")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
for user_org in UserOrganization::find_by_user(&self.uuid, &*conn) {
if user_org.type_ == UserOrgType::Owner {
if UserOrganization::find_by_org_and_type(
&user_org.org_uuid,
UserOrgType::Owner as i32, &conn
).len() <= 1 {
return Err(diesel::result::Error::NotFound);
err!("Can't delete last owner")
}
}
}
@ -168,12 +172,13 @@ impl User {
Cipher::delete_all_by_user(&self.uuid, &*conn)?;
Folder::delete_all_by_user(&self.uuid, &*conn)?;
Device::delete_all_by_user(&self.uuid, &*conn)?;
TwoFactor::delete_all_by_user(&self.uuid, &*conn)?;
//TwoFactor::delete_all_by_user(&self.uuid, &*conn)?;
Invitation::take(&self.email, &*conn); // Delete invitation if any
diesel::delete(users::table.filter(
users::uuid.eq(self.uuid)))
.execute(&**conn).and(Ok(()))
.execute(&**conn)
.map_res("Error deleting user")
}
pub fn update_uuid_revision(uuid: &str, conn: &DbConn) {
@ -184,7 +189,7 @@ impl User {
};
}
pub fn update_revision(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn update_revision(&mut self, conn: &DbConn) -> EmptyResult {
self.updated_at = Utc::now().naive_utc();
diesel::update(
users::table.filter(
@ -192,7 +197,8 @@ impl User {
)
)
.set(users::updated_at.eq(&self.updated_at))
.execute(&**conn).and(Ok(()))
.execute(&**conn)
.map_res("Error updating user revision")
}
pub fn find_by_mail(mail: &str, conn: &DbConn) -> Option<Self> {
@ -228,18 +234,18 @@ impl Invitation {
}
}
pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
diesel::replace_into(invitations::table)
.values(&*self)
.execute(&**conn)
.and(Ok(()))
.map_res("Error saving invitation")
}
pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
pub fn delete(self, conn: &DbConn) -> EmptyResult {
diesel::delete(invitations::table.filter(
invitations::email.eq(self.email)))
.execute(&**conn)
.and(Ok(()))
.map_res("Error deleting invitation")
}
pub fn find_by_mail(mail: &str, conn: &DbConn) -> Option<Self> {