diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index d8e622f2..0b9b125e 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -773,8 +773,8 @@ async fn post_collections_update( err!("Cipher doesn't exist") }; - if !cipher.is_write_accessible_to_user(&headers.user.uuid, &mut conn).await { - err!("Cipher is not write accessible") + if !cipher.is_in_editable_collection_by_user(&headers.user.uuid, &mut conn).await { + err!("Collection cannot be changed") } let posted_collections = HashSet::::from_iter(data.collection_ids); @@ -850,8 +850,8 @@ async fn post_collections_admin( err!("Cipher doesn't exist") }; - if !cipher.is_write_accessible_to_user(&headers.user.uuid, &mut conn).await { - err!("Cipher is not write accessible") + if !cipher.is_in_editable_collection_by_user(&headers.user.uuid, &mut conn).await { + err!("Collection cannot be changed") } let posted_collections = HashSet::::from_iter(data.collection_ids); diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index 8cbad4b7..49a74ebc 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -717,6 +717,15 @@ impl Cipher { } } + // used for checking if collection can be edited (only if user has access to a collection they + // can write to and also passwords are not hidden to prevent privilege escalation) + pub async fn is_in_editable_collection_by_user(&self, user_uuid: &UserId, conn: &mut DbConn) -> bool { + match self.get_access_restrictions(user_uuid, None, conn).await { + Some((read_only, hide_passwords, manage)) => (!read_only && !hide_passwords) || manage, + None => false, + } + } + pub async fn is_accessible_to_user(&self, user_uuid: &UserId, conn: &mut DbConn) -> bool { self.get_access_restrictions(user_uuid, None, conn).await.is_some() }