Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow all manager to create collections again #5488

Merged

Conversation

BlackDex
Copy link
Collaborator

@BlackDex BlackDex commented Jan 28, 2025

This commit checks if the member is a manager or better, and if so allows it to createCollections. We actually check if it is less then a Manager, since the limitCollectionCreation should be set to false to allow it and true to prevent.

This should fix an issue discussed in #5484

Fixes #5489

@BlackDex
Copy link
Collaborator Author

@stefan0xC, if you are able, please check and verify.

@BlackDex BlackDex requested a review from dani-garcia January 28, 2025 14:09
@BlackDex
Copy link
Collaborator Author

BlackDex commented Jan 28, 2025

Also, we can't allow it for users too, as that will currently break because we check for Manager Headers.
To allow this more globally, we should add all the custom role features and change the whole RBAC Checking.

@stefan0xC
Copy link
Contributor

Tested it a bit and found the following issues:

  1. You can remove your edit access if you save it with "Can view" permissions but I think that one is fine.
  2. If I add a new collection, it seems that added new collections are not handled immediately as manageable (if I reload the list eg. by switching to sends or the admin console and back to vault) this works again.
  3. When editing a collection by setting it as Can manage seems to be a bit quirky.
    I. e. first time I get an error message saying I'm not part of the organization, second time my user is not in the collection anymore and I forcibly get logged out.

Here are the logs from the 3. issue

[2025-01-28 20:04:42.334][request][INFO] GET /api/organizations/2825d73d-f461-41a0-8364-845f701946be/collections/details
[2025-01-28 20:04:42.339][request][INFO] GET /api/organizations/2825d73d-f461-41a0-8364-845f701946be/users/mini-details
[2025-01-28 20:04:42.340][response][INFO] (get_org_user_mini_details) GET /api/organizations/<org_id>/users/mini-details => 200 OK
[2025-01-28 20:04:42.346][request][INFO] GET /api/organizations/2825d73d-f461-41a0-8364-845f701946be/groups
[2025-01-28 20:04:42.347][response][INFO] (get_groups) GET /api/organizations/<org_id>/groups => 200 OK
[2025-01-28 20:04:42.348][response][INFO] (get_org_collections_details) GET /api/organizations/<org_id>/collections/details => 200 OK
[2025-01-28 20:04:52.220][request][INFO] PUT /api/organizations/2825d73d-f461-41a0-8364-845f701946be/collections/64ffc671-555c-4870-b715-dff0b8103227
[2025-01-28 20:04:52.221][rocket::request::from_param::_][WARN] Note: Using `String` as a parameter type is inefficient. Use `&str` instead.
[2025-01-28 20:04:52.221][rocket::request::from_param::_][INFO] `String` is used a parameter guard in /home/stefan/Projects/rust/.rustup/toolchains/1.84.0-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250.
[2025-01-28 20:04:52.223][vaultwarden::api::core::organizations][ERROR] User is not part of organization
[2025-01-28 20:04:52.223][response][INFO] (put_organization_collection_update) PUT /api/organizations/<org_id>/collections/<col_id> => 400 Bad Request
[...]
[2025-01-28 20:06:24.938][request][INFO] PUT /api/organizations/2825d73d-f461-41a0-8364-845f701946be/collections/64ffc671-555c-4870-b715-dff0b8103227
[2025-01-28 20:06:24.939][rocket::request::from_param::_][WARN] Note: Using `String` as a parameter type is inefficient. Use `&str` instead.
[2025-01-28 20:06:24.939][rocket::request::from_param::_][INFO] `String` is used a parameter guard in /home/stefan/Projects/rust/.rustup/toolchains/1.84.0-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250.
[2025-01-28 20:06:24.940][auth][ERROR] Unauthorized Error: The current user isn't a manager for this collection
[2025-01-28 20:06:24.940][vaultwarden::api::core::organizations::_][WARN] Request guard `ManagerHeaders` failed: "The current user isn't a manager for this collection".
[2025-01-28 20:06:24.940][rocket::server::_][WARN] No 401 catcher registered. Using Rocket default.
[2025-01-28 20:06:24.940][response][INFO] (put_organization_collection_update) PUT /api/organizations/<org_id>/collections/<col_id> => 401 Unauthorized
[2025-01-28 20:06:25.027][tungstenite::protocol][DEBUG] Received close frame: Some(CloseFrame { code: Away, reason: "" })
[2025-01-28 20:06:25.027][tungstenite::protocol][DEBUG] Replying to close with Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None }, payload: [3, 233] }
[2025-01-28 20:06:25.027][vaultwarden::api::notifications][INFO] Closing WS connection from 192.168.1.10
[2025-01-28 20:06:25.070][request][INFO] GET /

first request to /api/organizations/2825d73d-f461-41a0-8364-845f701946be/collections/64ffc671-555c-4870-b715-dff0b8103227 sends

{
 "groups":[],
 "users":  [
    {"id":"62ac3290-2ab3-4e58-9a1c-45c83570b6e6","readOnly":false,"hidePasswords":false,"manage":false},
    {"id":"b0089b1c-960f-408b-a36c-8ed5ad54aa9e","readOnly":false,"hidePasswords":false,"manage":false},
    {"id":"4d574091-85a8-4dc7-8c21-c96e0eded250","readOnly":false,"hidePasswords":false,"manage":false},
    {"id":"510e2949-e433-4d3f-9bdc-35c9f9e7347a","readOnly":false,"hidePasswords":false,"manage":true},
    {"id":"9ca6e1d0-c334-4e09-b0d4-9251c04eb5bb","readOnly":false,"hidePasswords":false,"manage":false},
    {"id":"22ecb6d3-1c48-43c8-94f6-9380a4ac71dd","readOnly":false,"hidePasswords":false,"manage":false}
 ],
  "externalId":null,
  "name":"2.7OHlTYWwJYK4uBnke11IOQ==|ukizJ9GF8zHZrDphVAdN8A==|t9MMTfYTjSvi+JV08JDK4sJ+ou+4qNnrL4JC+SZi544="}

which is weird because according to my database those are my users different memberships

uuid user_uuid org_uuid
62ac3290-2ab3-4e58-9a1c-45c83570b6e6 59dc70d5-b579-4ede-ad12-e4a7cb20618f 00e3f9d7-8a96-4db9-9c32-83d76f38d9bc
b0089b1c-960f-408b-a36c-8ed5ad54aa9e 59dc70d5-b579-4ede-ad12-e4a7cb20618f 13e9831c-3bad-45ee-ad06-baf67a1027ec
4d574091-85a8-4dc7-8c21-c96e0eded250 59dc70d5-b579-4ede-ad12-e4a7cb20618f 152bd996-19f9-40ee-b991-e52333a7e719
510e2949-e433-4d3f-9bdc-35c9f9e7347a 59dc70d5-b579-4ede-ad12-e4a7cb20618f 2825d73d-f461-41a0-8364-845f701946be
9ca6e1d0-c334-4e09-b0d4-9251c04eb5bb 59dc70d5-b579-4ede-ad12-e4a7cb20618f 95253266-0eaf-45d1-8ff6-da31c2689729
22ecb6d3-1c48-43c8-94f6-9380a4ac71dd 59dc70d5-b579-4ede-ad12-e4a7cb20618f ef9b802a-986f-4163-ac36-240605e62829

I have not yet checked further into why this happens.

@BlackDex
Copy link
Collaborator Author

Thanks for the in depth test
I think the can view is supposed to remove that access as, you can only create new ones, not manage all.

The rest i would need to check too. And i also see a warning regarding not using a &str?

@stefan0xC
Copy link
Contributor

stefan0xC commented Jan 28, 2025

I think the can view is supposed to remove that access as, you can only create new ones, not manage all.

Yeah, I mean it's just weird that the web-vault doesn't prevent you from doing that (or warn you about it) but I think that might also have been the case previously so it's not something I'd fix either. (edit: also removing your own access seems to work as it did before.)

@stefan0xC
Copy link
Contributor

stefan0xC commented Jan 28, 2025

I think I have found the issue. When get_org_collections_details is called it's using:

pub async fn find_by_collection_swap_user_uuid_with_member_uuid(
collection_uuid: &CollectionId,
conn: &mut DbConn,
) -> Vec<CollectionMembership> {
let col_users = db_run! { conn: {
users_collections::table
.filter(users_collections::collection_uuid.eq(collection_uuid))
.inner_join(users_organizations::table.on(users_organizations::user_uuid.eq(users_collections::user_uuid)))
.select((users_organizations::uuid, users_collections::collection_uuid, users_collections::read_only, users_collections::hide_passwords, users_collections::manage))

This seems to join the tables incorrectly and returns all memberships from all members that are assigned to the given collection regardless of the organization instead of only the members for that organization that are assigned to the collection. So I think it should be more like

select uo.uuid from collections as c
        inner join users_collections as uc on c.uuid=uc.collection_uuid
      inner join users_organizations as uo on c.org_uuid = uo.org_uuid
   where uo.user_uuid = uc.user_uuid and c.uuid = '8613531a-e984-4a70-aa41-52d1eab0b332';

Or to make it easier, since we already know the org_id, we could just pass that too maybe.

@BlackDex
Copy link
Collaborator Author

I found the issue of not having direct manage access to a collection after creation, we need to return the detailed collection json, that solved the issue.

This commit checks if the member is a manager or better, and if so allows it to createCollections.
We actually check if it is less then a Manager, since the `limitCollectionCreation` should be set to false to allow it and true to prevent.

This should fix an issue discussed in dani-garcia#5484

Signed-off-by: BlackDex <[email protected]>
@BlackDex BlackDex force-pushed the allow-managers-to-create-collections branch from 6af2b80 to 980b0d9 Compare January 29, 2025 13:15
@BlackDex
Copy link
Collaborator Author

@stefan0xC if you can recheck the same scenario, that would be cool.
I think that should be fixed now.

@BlackDex BlackDex force-pushed the allow-managers-to-create-collections branch from 980b0d9 to 2fb337d Compare January 29, 2025 13:25
@stefan0xC
Copy link
Contributor

stefan0xC commented Jan 29, 2025

Yeah, I think I found another issue though in get_org_collections_details:

pub async fn find_by_organization_swap_user_uuid_with_member_uuid(
org_uuid: &OrganizationId,
conn: &mut DbConn,
) -> Vec<CollectionMembership> {
let col_users = db_run! { conn: {
users_collections::table
.inner_join(collections::table.on(collections::uuid.eq(users_collections::collection_uuid)))
.filter(collections::org_uuid.eq(org_uuid))
.inner_join(users_organizations::table.on(users_organizations::user_uuid.eq(users_collections::user_uuid)))
.select((users_organizations::uuid, users_collections::collection_uuid, users_collections::read_only, users_collections::hide_passwords, users_collections::manage))

The filter should probably be applied to users_organizations::org_uuid instead of users_collections::org_uuid because it also returns too many Memberships for all collections.

Signed-off-by: BlackDex <[email protected]>
@BlackDex BlackDex force-pushed the allow-managers-to-create-collections branch from 2fb337d to 692967f Compare January 29, 2025 14:39
@BlackDex
Copy link
Collaborator Author

@stefan0xC, i added an extra filter there too. That should help.

Copy link
Contributor

@stefan0xC stefan0xC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. 👍 Seems like I cannot replicate those issues anymore.

@BlackDex BlackDex requested review from dani-garcia and removed request for dani-garcia January 29, 2025 14:58
@dani-garcia dani-garcia merged commit 3c29f82 into dani-garcia:main Jan 29, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Former Managers can't create collections anymore in 1.33.0 Webvault v2025.1.1
3 participants