vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

commit 513f8576724035d38e55162bd74ac2b395482055
parent 4cf9f83866bb1f0744e63b79d00cc7da6aba2de7
Author: Daniel GarcĂ­a <dani-garcia@users.noreply.github.com>
Date:   Fri,  1 Jun 2018 15:01:37 +0200

Merge pull request #36 from mprasil/cipher_access

Better check for cipher access
Diffstat:
Msrc/db/models/cipher.rs | 68++++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 48 insertions(+), 20 deletions(-)

diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs @@ -3,7 +3,7 @@ use serde_json::Value as JsonValue; use uuid::Uuid; -use super::{User, Organization, UserOrganization, Attachment, FolderCipher, CollectionCipher, UserOrgType}; +use super::{User, Organization, Attachment, FolderCipher, CollectionCipher, UserOrgType}; #[derive(Debug, Identifiable, Queryable, Insertable, Associations)] #[table_name = "ciphers"] @@ -194,29 +194,57 @@ impl Cipher { } pub fn is_write_accessible_to_user(&self, user_uuid: &str, conn: &DbConn) -> bool { - match self.user_uuid { - Some(ref self_user_uuid) => self_user_uuid == user_uuid, // cipher directly owned by user - None =>{ - match self.organization_uuid { - Some(ref org_uuid) => { - match users_organizations::table - .filter(users_organizations::org_uuid.eq(org_uuid)) - .filter(users_organizations::user_uuid.eq(user_uuid)) - .filter(users_organizations::access_all.eq(true)) - .first::<UserOrganization>(&**conn).ok() { - Some(_) => true, - None => false //TODO R/W access on collection - } - }, - None => false // cipher not in organization and not owned by user - } - } + match ciphers::table + .filter(ciphers::uuid.eq(&self.uuid)) + .left_join(users_organizations::table.on( + ciphers::organization_uuid.eq(users_organizations::org_uuid.nullable()).and( + users_organizations::user_uuid.eq(user_uuid) + ) + )) + .left_join(ciphers_collections::table) + .left_join(users_collections::table.on( + ciphers_collections::collection_uuid.eq(users_collections::collection_uuid) + )) + .filter(ciphers::user_uuid.eq(user_uuid).or( // Cipher owner + users_organizations::access_all.eq(true).or( // access_all in Organization + users_organizations::type_.le(UserOrgType::Admin as i32).or( // Org admin or owner + users_collections::user_uuid.eq(user_uuid).and( + users_collections::read_only.eq(false) //R/W access to collection + ) + ) + ) + )) + .select(ciphers::all_columns) + .first::<Self>(&**conn).ok() { + Some(_) => true, + None => false } } pub fn is_accessible_to_user(&self, user_uuid: &str, conn: &DbConn) -> bool { - // TODO also check for read-only access - self.is_write_accessible_to_user(user_uuid, conn) + match ciphers::table + .filter(ciphers::uuid.eq(&self.uuid)) + .left_join(users_organizations::table.on( + ciphers::organization_uuid.eq(users_organizations::org_uuid.nullable()).and( + users_organizations::user_uuid.eq(user_uuid) + ) + )) + .left_join(ciphers_collections::table) + .left_join(users_collections::table.on( + ciphers_collections::collection_uuid.eq(users_collections::collection_uuid) + )) + .filter(ciphers::user_uuid.eq(user_uuid).or( // Cipher owner + users_organizations::access_all.eq(true).or( // access_all in Organization + users_organizations::type_.le(UserOrgType::Admin as i32).or( // Org admin or owner + users_collections::user_uuid.eq(user_uuid) // Access to Collection + ) + ) + )) + .select(ciphers::all_columns) + .first::<Self>(&**conn).ok() { + Some(_) => true, + None => false + } } pub fn get_folder_uuid(&self, user_uuid: &str, conn: &DbConn) -> Option<String> {