Browse Source

refactor: cipher permission logic to prioritize user access

Updated permission checks to return user collection permissions if available, otherwise fallback to group permissions. Clarified comments to indicate user permissions overrule group permissions and corrected the logic for the 'manage' flag to use boolean OR instead of AND.
pull/6017/head
Richy 3 weeks ago
committed by Richy
parent
commit
f2a3bb7059
  1. 24
      src/db/models/cipher.rs

24
src/db/models/cipher.rs

@ -609,22 +609,23 @@ impl Cipher {
let mut rows: Vec<(bool, bool, bool)> = Vec::new(); let mut rows: Vec<(bool, bool, bool)> = Vec::new();
if let Some(collections) = cipher_sync_data.cipher_collections.get(&self.uuid) { if let Some(collections) = cipher_sync_data.cipher_collections.get(&self.uuid) {
for collection in collections { for collection in collections {
//User permissions // User permissions
if let Some(cu) = cipher_sync_data.user_collections.get(collection) { if let Some(cu) = cipher_sync_data.user_collections.get(collection) {
rows.push((cu.read_only, cu.hide_passwords, cu.manage)); rows.push((cu.read_only, cu.hide_passwords, cu.manage));
} // Group permissions
} else if let Some(cg) = cipher_sync_data.user_collections_groups.get(collection) {
//Group permissions
if let Some(cg) = cipher_sync_data.user_collections_groups.get(collection) {
rows.push((cg.read_only, cg.hide_passwords, cg.manage)); rows.push((cg.read_only, cg.hide_passwords, cg.manage));
} }
} }
} }
rows rows
} else { } else {
let mut access_flags = self.get_user_collections_access_flags(user_uuid, conn).await; let user_permissions = self.get_user_collections_access_flags(user_uuid, conn).await;
access_flags.append(&mut self.get_group_collections_access_flags(user_uuid, conn).await); if !user_permissions.is_empty() {
access_flags user_permissions
} else {
self.get_group_collections_access_flags(user_uuid, conn).await
}
}; };
if rows.is_empty() { if rows.is_empty() {
@ -633,6 +634,9 @@ impl Cipher {
} }
// A cipher can be in multiple collections with inconsistent access flags. // A cipher can be in multiple collections with inconsistent access flags.
// Also, user permission overrule group permissions
// and only user permissions are returned by the code above.
//
// For example, a cipher could be in one collection where the user has // For example, a cipher could be in one collection where the user has
// read-only access, but also in another collection where the user has // read-only access, but also in another collection where the user has
// read/write access. For a flag to be in effect for a cipher, upstream // read/write access. For a flag to be in effect for a cipher, upstream
@ -641,13 +645,15 @@ impl Cipher {
// and `hide_passwords` columns. This could ideally be done as part of the // and `hide_passwords` columns. This could ideally be done as part of the
// query, but Diesel doesn't support a min() or bool_and() function on // query, but Diesel doesn't support a min() or bool_and() function on
// booleans and this behavior isn't portable anyway. // booleans and this behavior isn't portable anyway.
//
// The only exception is for the `manage` flag, that needs a boolean OR!
let mut read_only = true; let mut read_only = true;
let mut hide_passwords = true; let mut hide_passwords = true;
let mut manage = false; let mut manage = false;
for (ro, hp, mn) in rows.iter() { for (ro, hp, mn) in rows.iter() {
read_only &= ro; read_only &= ro;
hide_passwords &= hp; hide_passwords &= hp;
manage &= mn; manage |= mn;
} }
Some((read_only, hide_passwords, manage)) Some((read_only, hide_passwords, manage))

Loading…
Cancel
Save