0
0
Fork 0
mirror of https://github.com/dani-garcia/vaultwarden synced 2024-12-14 17:43:46 +01:00

Update affected users revision on cipher and folder change

This commit is contained in:
Miroslav Prasil 2018-08-21 17:31:01 +01:00
parent 4f58d07c83
commit 2b2401be19
3 changed files with 45 additions and 3 deletions

View file

@ -3,7 +3,7 @@ use serde_json::Value as JsonValue;
use uuid::Uuid; use uuid::Uuid;
use super::{User, Organization, Attachment, FolderCipher, CollectionCipher, UserOrgType, UserOrgStatus}; use super::{User, Organization, Attachment, FolderCipher, CollectionCipher, UserOrganization, UserOrgType, UserOrgStatus};
#[derive(Debug, Identifiable, Queryable, Insertable, Associations)] #[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
#[table_name = "ciphers"] #[table_name = "ciphers"]
@ -122,7 +122,23 @@ impl Cipher {
json_object json_object
} }
pub fn update_users_revision(&self, conn: &DbConn) {
match self.user_uuid {
Some(ref user_uuid) => User::update_uuid_revision(&user_uuid, conn),
None => { // Belongs to Organization, need to update affected users
if let Some(ref org_uuid) = self.organization_uuid {
UserOrganization::find_by_cipher_and_org(&self.uuid, &org_uuid, conn)
.iter()
.for_each(|user_org| {
User::update_uuid_revision(&user_org.user_uuid, conn)
});
}
}
};
}
pub fn save(&mut self, conn: &DbConn) -> bool { pub fn save(&mut self, conn: &DbConn) -> bool {
self.update_users_revision(conn);
self.updated_at = Utc::now().naive_utc(); self.updated_at = Utc::now().naive_utc();
match diesel::replace_into(ciphers::table) match diesel::replace_into(ciphers::table)
@ -134,6 +150,8 @@ impl Cipher {
} }
pub fn delete(self, conn: &DbConn) -> QueryResult<()> { pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
self.update_users_revision(conn);
FolderCipher::delete_all_by_cipher(&self.uuid, &conn)?; FolderCipher::delete_all_by_cipher(&self.uuid, &conn)?;
CollectionCipher::delete_all_by_cipher(&self.uuid, &conn)?; CollectionCipher::delete_all_by_cipher(&self.uuid, &conn)?;
Attachment::delete_all_by_cipher(&self.uuid, &conn)?; Attachment::delete_all_by_cipher(&self.uuid, &conn)?;
@ -157,6 +175,7 @@ impl Cipher {
None => { None => {
match folder_uuid { match folder_uuid {
Some(new_folder) => { Some(new_folder) => {
self.update_users_revision(conn);
let folder_cipher = FolderCipher::new(&new_folder, &self.uuid); let folder_cipher = FolderCipher::new(&new_folder, &self.uuid);
folder_cipher.save(&conn).or(Err("Couldn't save folder setting")) folder_cipher.save(&conn).or(Err("Couldn't save folder setting"))
}, },
@ -169,6 +188,7 @@ impl Cipher {
if current_folder == new_folder { if current_folder == new_folder {
Ok(()) //nothing to do Ok(()) //nothing to do
} else { } else {
self.update_users_revision(conn);
match FolderCipher::find_by_folder_and_cipher(&current_folder, &self.uuid, &conn) { match FolderCipher::find_by_folder_and_cipher(&current_folder, &self.uuid, &conn) {
Some(current_folder) => { Some(current_folder) => {
current_folder.delete(&conn).or(Err("Failed removing old folder mapping")) current_folder.delete(&conn).or(Err("Failed removing old folder mapping"))
@ -181,6 +201,7 @@ impl Cipher {
} }
}, },
None => { None => {
self.update_users_revision(conn);
match FolderCipher::find_by_folder_and_cipher(&current_folder, &self.uuid, &conn) { match FolderCipher::find_by_folder_and_cipher(&current_folder, &self.uuid, &conn) {
Some(current_folder) => { Some(current_folder) => {
current_folder.delete(&conn).or(Err("Failed removing old folder mapping")) current_folder.delete(&conn).or(Err("Failed removing old folder mapping"))

View file

@ -71,6 +71,7 @@ use db::schema::{folders, folders_ciphers};
/// Database methods /// Database methods
impl Folder { impl Folder {
pub fn save(&mut self, conn: &DbConn) -> bool { pub fn save(&mut self, conn: &DbConn) -> bool {
User::update_uuid_revision(&self.user_uuid, conn);
self.updated_at = Utc::now().naive_utc(); self.updated_at = Utc::now().naive_utc();
match diesel::replace_into(folders::table) match diesel::replace_into(folders::table)
@ -82,6 +83,7 @@ impl Folder {
} }
pub fn delete(self, conn: &DbConn) -> QueryResult<()> { pub fn delete(self, conn: &DbConn) -> QueryResult<()> {
User::update_uuid_revision(&self.user_uuid, conn);
FolderCipher::delete_all_by_folder(&self.uuid, &conn)?; FolderCipher::delete_all_by_folder(&self.uuid, &conn)?;
diesel::delete( diesel::delete(

View file

@ -109,8 +109,7 @@ impl UserOrganization {
use diesel; use diesel;
use diesel::prelude::*; use diesel::prelude::*;
use db::DbConn; use db::DbConn;
use db::schema::organizations; use db::schema::{organizations, users_organizations, users_collections, ciphers_collections};
use db::schema::users_organizations;
/// Database methods /// Database methods
impl Organization { impl Organization {
@ -297,6 +296,26 @@ impl UserOrganization {
.filter(users_organizations::org_uuid.eq(org_uuid)) .filter(users_organizations::org_uuid.eq(org_uuid))
.first::<Self>(&**conn).ok() .first::<Self>(&**conn).ok()
} }
pub fn find_by_cipher_and_org(cipher_uuid: &str, org_uuid: &str, conn: &DbConn) -> Vec<Self> {
users_organizations::table
.filter(users_organizations::org_uuid.eq(org_uuid))
.left_join(users_collections::table.on(
users_collections::user_uuid.eq(users_organizations::user_uuid)
))
.left_join(ciphers_collections::table.on(
ciphers_collections::collection_uuid.eq(users_collections::collection_uuid).and(
ciphers_collections::cipher_uuid.eq(&cipher_uuid)
)
))
.filter(
users_organizations::access_all.eq(true).or( // AccessAll..
ciphers_collections::cipher_uuid.eq(&cipher_uuid) // ..or access to collection with cipher
)
)
.select(users_organizations::all_columns)
.load::<Self>(&**conn).expect("Error loading user organizations")
}
} }