mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-06-12 13:17:43 +02:00
Add manage role for collections and groups (#5386)
* Add manage role for collections and groups This commit will add the manage role/column to collections and groups. We need this to allow users part of a collection either directly or via groups to be able to delete ciphers. Without this, they are only able to either edit or view them when using new clients, since these check the manage role. Still trying to keep it compatible with previous versions and able to revert to an older Vaultwarden version and the `access_all` feature of the older installations. In a future version we should really check and fix these rights and create some kind of migration step to also remove the `access_all` feature and convert that to a `manage` option. But this commit at least creates the base for this already. This should resolve #5367 Signed-off-by: BlackDex <black.dex@gmail.com> * Fix an issue with access_all If owners or admins do not have the `access_all` flag set, in case they do not want to see all collection on the password manager view, they didn't see any collections at all anymore. This should fix that they are still able to view all the collections and have access to it. Signed-off-by: BlackDex <black.dex@gmail.com> --------- Signed-off-by: BlackDex <black.dex@gmail.com>
This commit is contained in:

committed by
GitHub

parent
ef2695de0c
commit
d1dee04615
@ -140,6 +140,7 @@ struct NewCollectionGroupData {
|
||||
hide_passwords: bool,
|
||||
id: GroupId,
|
||||
read_only: bool,
|
||||
manage: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -148,6 +149,7 @@ struct NewCollectionMemberData {
|
||||
hide_passwords: bool,
|
||||
id: MembershipId,
|
||||
read_only: bool,
|
||||
manage: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -362,18 +364,13 @@ async fn get_org_collections_details(
|
||||
|| (CONFIG.org_groups_enabled()
|
||||
&& GroupUser::has_access_to_collection_by_member(&col.uuid, &member.uuid, &mut conn).await);
|
||||
|
||||
// Not assigned collections should not be returned
|
||||
if !assigned {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the users assigned directly to the given collection
|
||||
let users: Vec<Value> = col_users
|
||||
.iter()
|
||||
.filter(|collection_user| collection_user.collection_uuid == col.uuid)
|
||||
.map(|collection_user| {
|
||||
collection_user.to_json_details_for_user(
|
||||
*membership_type.get(&collection_user.membership_uuid).unwrap_or(&(MembershipType::User as i32)),
|
||||
.filter(|collection_member| collection_member.collection_uuid == col.uuid)
|
||||
.map(|collection_member| {
|
||||
collection_member.to_json_details_for_member(
|
||||
*membership_type.get(&collection_member.membership_uuid).unwrap_or(&(MembershipType::User as i32)),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@ -437,7 +434,7 @@ async fn post_organization_collections(
|
||||
.await;
|
||||
|
||||
for group in data.groups {
|
||||
CollectionGroup::new(collection.uuid.clone(), group.id, group.read_only, group.hide_passwords)
|
||||
CollectionGroup::new(collection.uuid.clone(), group.id, group.read_only, group.hide_passwords, group.manage)
|
||||
.save(&mut conn)
|
||||
.await?;
|
||||
}
|
||||
@ -451,12 +448,19 @@ async fn post_organization_collections(
|
||||
continue;
|
||||
}
|
||||
|
||||
CollectionUser::save(&member.user_uuid, &collection.uuid, user.read_only, user.hide_passwords, &mut conn)
|
||||
.await?;
|
||||
CollectionUser::save(
|
||||
&member.user_uuid,
|
||||
&collection.uuid,
|
||||
user.read_only,
|
||||
user.hide_passwords,
|
||||
user.manage,
|
||||
&mut conn,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
if headers.membership.atype == MembershipType::Manager && !headers.membership.access_all {
|
||||
CollectionUser::save(&headers.membership.user_uuid, &collection.uuid, false, false, &mut conn).await?;
|
||||
CollectionUser::save(&headers.membership.user_uuid, &collection.uuid, false, false, false, &mut conn).await?;
|
||||
}
|
||||
|
||||
Ok(Json(collection.to_json()))
|
||||
@ -513,7 +517,9 @@ async fn post_organization_collection_update(
|
||||
CollectionGroup::delete_all_by_collection(&col_id, &mut conn).await?;
|
||||
|
||||
for group in data.groups {
|
||||
CollectionGroup::new(col_id.clone(), group.id, group.read_only, group.hide_passwords).save(&mut conn).await?;
|
||||
CollectionGroup::new(col_id.clone(), group.id, group.read_only, group.hide_passwords, group.manage)
|
||||
.save(&mut conn)
|
||||
.await?;
|
||||
}
|
||||
|
||||
CollectionUser::delete_all_by_collection(&col_id, &mut conn).await?;
|
||||
@ -527,7 +533,8 @@ async fn post_organization_collection_update(
|
||||
continue;
|
||||
}
|
||||
|
||||
CollectionUser::save(&member.user_uuid, &col_id, user.read_only, user.hide_passwords, &mut conn).await?;
|
||||
CollectionUser::save(&member.user_uuid, &col_id, user.read_only, user.hide_passwords, user.manage, &mut conn)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(Json(collection.to_json_details(&headers.user.uuid, None, &mut conn).await))
|
||||
@ -685,10 +692,10 @@ async fn get_org_collection_detail(
|
||||
CollectionUser::find_by_collection_swap_user_uuid_with_member_uuid(&collection.uuid, &mut conn)
|
||||
.await
|
||||
.iter()
|
||||
.map(|collection_user| {
|
||||
collection_user.to_json_details_for_user(
|
||||
.map(|collection_member| {
|
||||
collection_member.to_json_details_for_member(
|
||||
*membership_type
|
||||
.get(&collection_user.membership_uuid)
|
||||
.get(&collection_member.membership_uuid)
|
||||
.unwrap_or(&(MembershipType::User as i32)),
|
||||
)
|
||||
})
|
||||
@ -758,7 +765,7 @@ async fn put_collection_users(
|
||||
continue;
|
||||
}
|
||||
|
||||
CollectionUser::save(&user.user_uuid, &col_id, d.read_only, d.hide_passwords, &mut conn).await?;
|
||||
CollectionUser::save(&user.user_uuid, &col_id, d.read_only, d.hide_passwords, d.manage, &mut conn).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -866,6 +873,7 @@ struct CollectionData {
|
||||
id: CollectionId,
|
||||
read_only: bool,
|
||||
hide_passwords: bool,
|
||||
manage: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -874,6 +882,7 @@ struct MembershipData {
|
||||
id: MembershipId,
|
||||
read_only: bool,
|
||||
hide_passwords: bool,
|
||||
manage: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -1012,6 +1021,7 @@ async fn send_invite(
|
||||
&collection.uuid,
|
||||
col.read_only,
|
||||
col.hide_passwords,
|
||||
col.manage,
|
||||
&mut conn,
|
||||
)
|
||||
.await?;
|
||||
@ -1504,6 +1514,7 @@ async fn edit_member(
|
||||
&collection.uuid,
|
||||
col.read_only,
|
||||
col.hide_passwords,
|
||||
col.manage,
|
||||
&mut conn,
|
||||
)
|
||||
.await?;
|
||||
@ -2475,11 +2486,12 @@ struct SelectedCollection {
|
||||
id: CollectionId,
|
||||
read_only: bool,
|
||||
hide_passwords: bool,
|
||||
manage: bool,
|
||||
}
|
||||
|
||||
impl SelectedCollection {
|
||||
pub fn to_collection_group(&self, groups_uuid: GroupId) -> CollectionGroup {
|
||||
CollectionGroup::new(self.id.clone(), groups_uuid, self.read_only, self.hide_passwords)
|
||||
CollectionGroup::new(self.id.clone(), groups_uuid, self.read_only, self.hide_passwords, self.manage)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,9 +291,7 @@ fn get_favicons_node(dom: Tokenizer<StringReader<'_>, FaviconEmitter>, icons: &m
|
||||
TAG_HEAD if token.closing => {
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,6 @@ fn websockets_hub<'r>(
|
||||
|
||||
if serde_json::from_str(msg).ok() == Some(INITIAL_MESSAGE) {
|
||||
yield Message::binary(INITIAL_RESPONSE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +224,6 @@ fn anonymous_websockets_hub<'r>(ws: WebSocket, token: String, ip: ClientIp) -> R
|
||||
|
||||
if serde_json::from_str(msg).ok() == Some(INITIAL_MESSAGE) {
|
||||
yield Message::binary(INITIAL_RESPONSE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user