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

[AC-2172] Member modal - limit admin access #8343

Merged
merged 70 commits into from
Apr 17, 2024

Conversation

eliykat
Copy link
Member

@eliykat eliykat commented Mar 15, 2024

Type of change

- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other

Objective

In the Member modal, if owners and admins cannot manage all collections and items, then you should only be able to edit collection assignments for collections that you have Can Manage access to.

This depends on:

On the plus side, once those are merged, this PR is fairly minimal (if dense).

Sever changes are WIP.

Code changes

  • member-dialog.component.ts - most of this diff is just adding a collection.canEdit check in mapCollectionToAccessItemView. However, that requires the org and the v1 flag, so there's a large footprint just getting those values there.
    • note that this (should) provide us with optionality for both the v1 flag and the collection management setting, because everything hinges off this readonly property.
  • access-selector.component.ts -
    • there were a few places where we used item.readonly to mean "collection access via a group", because that was the only type of readonly item. However, we now have 2 types (collection access via group, and a collection you don't manage), so some places needed updating to limit their reach.
    • when giving the multiselect its initial items (via the selectionList), exclude any readonly items, because you can't give access to something that's readonly.

Screenshots

Before you submit

  • Please add unit tests where it makes sense to do so (encouraged but not required)
  • If this change requires a documentation update - notify the documentation team
  • If this change has particular deployment requirements - notify the DevOps team
  • Ensure that all UI additions follow WCAG AA requirements

… collections in the org vault edit collections modal
…ditCipherCollections for better updates to collections modal when flag is off
@github-actions github-actions bot added the needs-qa Marks a PR as requiring QA approval label Mar 15, 2024
Copy link

codecov bot commented Mar 15, 2024

Codecov Report

Attention: Patch coverage is 4.76190% with 20 lines in your changes are missing coverage. Please review.

Project coverage is 27.37%. Comparing base (f45eec1) to head (17cd687).

Files Patch % Lines
...omponents/member-dialog/member-dialog.component.ts 0.00% 17 Missing ⚠️
...web/src/app/vault/core/collection-admin.service.ts 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8343      +/-   ##
==========================================
- Coverage   27.37%   27.37%   -0.01%     
==========================================
  Files        2344     2344              
  Lines       68455    68463       +8     
  Branches    12798    12800       +2     
==========================================
  Hits        18739    18739              
- Misses      48312    48320       +8     
  Partials     1404     1404              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bitwarden-bot
Copy link

bitwarden-bot commented Mar 15, 2024

Logo
Checkmarx One – Scan Summary & Details68d24085-ea2e-4998-a1cc-d04e14dfbaf2

New Issues

Severity Issue Source File / Package Checkmarx Insight
MEDIUM Angular_Improper_Type_Pipe_Usage /apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html: 54 Attack Vector
MEDIUM Angular_Improper_Type_Pipe_Usage /apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html: 36 Attack Vector

Fixed Issues

Severity Issue Source File / Package
HIGH Client_DOM_Code_Injection /apps/web/src/connectors/common.ts: 2
HIGH Client_DOM_Code_Injection /apps/browser/src/autofill/services/collect-autofill-content.service.ts: 1054
HIGH Client_DOM_Stored_XSS /apps/web/src/connectors/sso.ts: 33
HIGH Client_DOM_XSS /apps/browser/src/auth/scripts/duo.js: 285
HIGH Client_DOM_XSS /apps/browser/src/auth/scripts/duo.js: 285
HIGH Client_DOM_XSS /apps/desktop/src/auth/scripts/duo.js: 285
HIGH Client_DOM_XSS /apps/desktop/src/auth/scripts/duo.js: 285
HIGH Client_DOM_XSS /apps/web/src/connectors/common.ts: 2
HIGH Client_DOM_XSS /apps/web/src/connectors/common.ts: 2
HIGH Client_DOM_XSS /apps/web/src/connectors/common.ts: 2
HIGH Client_DOM_XSS /apps/web/src/connectors/common.ts: 2
HIGH Client_DOM_XSS /apps/web/src/connectors/sso.ts: 21
HIGH Client_DOM_XSS /apps/web/src/connectors/sso.ts: 19
HIGH Client_DOM_XSS /apps/web/src/connectors/sso.ts: 15
MEDIUM Absolute_Path_Traversal /apps/cli/src/commands/serve.command.ts: 311
MEDIUM Absolute_Path_Traversal /apps/cli/src/commands/serve.command.ts: 343
MEDIUM Absolute_Path_Traversal /apps/cli/src/commands/serve.command.ts: 311
MEDIUM Absolute_Path_Traversal /apps/cli/src/commands/serve.command.ts: 343
MEDIUM Angular_Improper_Type_Pipe_Usage /apps/browser/src/vault/popup/components/fido2/fido2-use-browser-link.component.html: 1
MEDIUM Angular_Improper_Type_Pipe_Usage /apps/web/src/app/billing/organizations/adjust-subscription.component.html: 54
MEDIUM Angular_Improper_Type_Pipe_Usage /apps/web/src/app/billing/organizations/adjust-subscription.component.html: 18
MEDIUM Client_Privacy_Violation /apps/browser/src/background/runtime.background.ts: 331
MEDIUM Client_Privacy_Violation /apps/web/src/app/tools/reports/pages/breach-report.component.html: 14
MEDIUM Client_Privacy_Violation /apps/browser/src/auth/popup/account-switching/account.component.ts: 12
MEDIUM Client_Privacy_Violation /apps/browser/src/auth/popup/account-switching/account.component.ts: 12
MEDIUM Client_Privacy_Violation /apps/browser/src/auth/popup/account-switching/account.component.ts: 12
MEDIUM Client_Privacy_Violation /apps/web/src/app/auth/settings/two-factor-verify.component.html: 3
MEDIUM Client_Privacy_Violation /libs/components/src/color-password/color-password.component.ts: 25
MEDIUM Client_Privacy_Violation /libs/components/src/color-password/color-password.component.ts: 26
MEDIUM Client_Privacy_Violation /apps/desktop/src/auth/lock.component.html: 32
MEDIUM Client_Privacy_Violation /apps/web/src/app/auth/lock.component.html: 18
MEDIUM Client_Privacy_Violation /apps/web/src/app/billing/shared/add-credit.component.ts: 80
MEDIUM Client_Privacy_Violation /apps/web/src/app/billing/shared/add-credit.component.ts: 30
MEDIUM Client_Privacy_Violation /apps/web/src/app/billing/shared/add-credit.component.ts: 146
MEDIUM Client_Privacy_Violation /apps/web/src/app/billing/shared/add-credit.component.ts: 70
MEDIUM Client_Privacy_Violation /apps/web/src/app/billing/shared/add-credit.component.ts: 135
MEDIUM Client_Privacy_Violation /apps/web/src/app/auth/lock.component.html: 18
MEDIUM Client_Privacy_Violation /apps/desktop/src/auth/lock.component.html: 32
MEDIUM Client_Privacy_Violation /apps/web/src/app/auth/recover-two-factor.component.html: 37
MEDIUM Client_Privacy_Violation /apps/web/src/app/billing/shared/add-credit.component.html: 46
MEDIUM Client_Privacy_Violation /apps/desktop/src/vault/app/vault/view.component.html: 534
MEDIUM Client_Privacy_Violation /apps/web/src/connectors/webauthn-fallback.ts: 116
MEDIUM Client_Privacy_Violation /bitwarden_license/bit-web/src/app/auth/sso/sso.component.ts: 161
MEDIUM Client_Privacy_Violation /bitwarden_license/bit-web/src/app/auth/sso/sso.component.ts: 161
MEDIUM Client_Privacy_Violation /libs/components/src/color-password/color-password.component.ts: 14
MEDIUM Client_Privacy_Violation /libs/components/src/color-password/color-password.component.ts: 14
MEDIUM Client_Privacy_Violation /apps/desktop/src/vault/app/vault/view.component.html: 60
MEDIUM Client_Privacy_Violation /apps/desktop/src/vault/app/vault/view.component.html: 56
MEDIUM Client_Privacy_Violation /apps/browser/src/tools/popup/generator/password-generator-history.component.html: 26
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/components/vault/password-history.component.html: 18
MEDIUM Client_Privacy_Violation /apps/desktop/src/app/tools/password-generator-history.component.html: 15
MEDIUM Client_Privacy_Violation /apps/desktop/src/vault/app/vault/password-history.component.html: 12
MEDIUM Client_Privacy_Violation /apps/desktop/src/vault/app/vault/view.component.html: 50
MEDIUM Client_Privacy_Violation /libs/components/src/color-password/color-password.component.ts: 14
MEDIUM Client_Privacy_Violation /libs/components/src/color-password/color-password.component.ts: 14
MEDIUM Client_Privacy_Violation /apps/browser/src/tools/popup/generator/password-generator-history.component.html: 26
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/components/vault/password-history.component.html: 18
MEDIUM Client_Privacy_Violation /apps/desktop/src/app/tools/password-generator-history.component.html: 15
MEDIUM Client_Privacy_Violation /apps/desktop/src/vault/app/vault/password-history.component.html: 12
MEDIUM Missing_HSTS_Header /apps/cli/src/auth/commands/login.command.ts: 705
MEDIUM SSRF /libs/importer/src/importers/lastpass/access/services/rest-client.ts: 69
MEDIUM SSRF /libs/importer/src/importers/lastpass/access/services/rest-client.ts: 69
LOW Angular_Usage_of_Unsafe_DOM_Sanitizer /apps/desktop/src/app/components/avatar.component.ts: 75
LOW Angular_Usage_of_Unsafe_DOM_Sanitizer /libs/components/src/avatar/avatar.component.ts: 80
LOW Angular_Usage_of_Unsafe_DOM_Sanitizer /libs/components/src/icon/icon.component.ts: 18
LOW Angular_Usage_of_Unsafe_DOM_Sanitizer /libs/components/src/icon/icon.component.ts: 18
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/accessibility-cookie.component.html: 18
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/common.ts: 2
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/common.ts: 2
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/common.ts: 2
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/sso.ts: 21
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/common.ts: 2
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/sso.ts: 19
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/common.ts: 2
LOW Client_DOM_Open_Redirect /apps/web/src/connectors/sso.ts: 15
LOW Client_DOM_Open_Redirect /apps/browser/src/tools/popup/generator/password-generator-history.component.ts: 18
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/popup/account-switching/current-account.component.ts: 31
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/popup/login-via-auth-request.component.ts: 54
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/login/login-via-auth-request.component.ts: 62
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/popup/login-via-auth-request.component.ts: 54
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/login/login-via-auth-request.component.ts: 62
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/popup/account-switching/account.component.ts: 25
LOW Client_DOM_Open_Redirect /apps/browser/src/vault/popup/components/vault/password-history.component.ts: 21
LOW Client_DOM_Open_Redirect /apps/browser/src/popup/settings/premium.component.ts: 27
LOW Client_DOM_Open_Redirect /apps/browser/src/vault/popup/components/vault/attachments.component.ts: 32
LOW Client_DOM_Open_Redirect /libs/common/src/auth/iframe-component.ts: 49
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /libs/common/src/auth/webauthn-iframe.ts: 25
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /libs/common/src/auth/webauthn-iframe.ts: 25
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/desktop/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_DOM_Open_Redirect /apps/browser/src/auth/scripts/duo.js: 277
LOW Client_Hardcoded_Domain /apps/web/src/app/billing/shared/payment.component.ts: 56
LOW Client_Hardcoded_Domain /apps/web/src/app/billing/shared/payment.component.ts: 56
LOW Client_Hardcoded_Domain /apps/web/src/connectors/captcha.ts: 57
LOW Client_Password_In_Comment /libs/angular/src/vault/components/add-edit.component.ts: 663
LOW Client_Password_In_Comment /apps/web/src/app/vault/org-vault/add-edit.component.ts: 108
LOW Client_Password_In_Comment /apps/web/src/app/vault/org-vault/collections.component.ts: 59
LOW Client_Password_In_Comment /libs/angular/src/platform/utils/safe-provider.ts: 108
LOW Client_Password_In_Comment /libs/common/src/state-migrations/migrations/30-move-policy-state-to-state-provider.ts: 13
LOW Client_Password_In_Comment /apps/browser/src/autofill/background/notification.background.ts: 566
LOW Client_Password_In_Comment /libs/common/src/services/event/event-collection.service.ts: 93
LOW Client_Password_In_Comment /libs/common/src/services/event/event-collection.service.ts: 88
LOW Client_Password_In_Comment /libs/common/src/platform/biometrics/biometric-state.service.ts: 62
LOW Client_Password_In_Comment /libs/common/src/platform/biometrics/biometric-state.service.ts: 30
LOW Client_Password_In_Comment /apps/web/src/app/auth/key-rotation/user-key-rotation.service.ts: 46
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 224
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 437
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 416
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 387
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 340
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 340
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 319
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 319
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 274
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 246
LOW Client_Password_In_Comment /apps/browser/src/autofill/overlay/pages/list/autofill-overlay-list.ts: 455
LOW Client_Password_In_Comment /apps/browser/src/autofill/background/overlay.background.ts: 516
LOW Client_Password_In_Comment /apps/browser/src/autofill/background/overlay.background.ts: 516
LOW Client_Password_In_Comment /apps/browser/src/autofill/background/overlay.background.ts: 227
LOW Client_Password_In_Comment /apps/browser/src/autofill/background/overlay.background.ts: 227
LOW Client_Password_In_Comment /libs/angular/src/auth/components/sso.component.ts: 225
LOW Client_Password_In_Comment /apps/browser/src/autofill/services/autofill.service.ts: 441
LOW Client_Password_In_Comment /apps/web/src/app/vault/org-vault/vault.component.ts: 785
LOW Client_Password_In_Comment /apps/web/src/app/vault/org-vault/vault.component.ts: 785
LOW

More results are available on AST platform

@eliykat
Copy link
Member Author

eliykat commented Apr 8, 2024

I had some interesting issues with data flow in Angular. I noticed that disabled rows were still appearing in the value being emitted by the access-selector until the user interacted with it. (The commit exhibiting this problem is 3d406bb.)

I tried to fix this in fdbeb48, but that is not a proper fix, and it caused unit tests to start failing because the control was emitting more times than expected.

My diagnosis:

  • writeValue takes the FormControl value and updates the native HTML elements (unidirectional)
  • the callback registered by registerOnChange takes the HTML values and updates the FormControl value (unidirectional)
  • however, my implementation was giving potentially disabled values to writeValue (i.e. access selections that the user doesn't have permission to edit), and writeValue was then updating the HTML elements, but also expecting it to write back to the FormControl value to remove these disabled items (bidirectional! bad)

After some experimentation, I thought the best way to resolve it was to not pass potentially "disabled" values into the FormControl to begin with. The fixes are in the last 2 commits. The updated logic is:

  • the access-selector FormControl only emits enabled (non-readonly) rows, so you should only give it non-readonly rows (AccessItemValues) when setting the initial value. This avoids the bidirectional flow issue, because writeValue is given a valid value from the start and does not need to alter it
  • the AccessItemViews you pass in should represent selectable (non-readonly) or already selected items
    • all readonly AccessItemViews are selected immediately (restoring previous logic)
    • this only leaves items in the multi-select that the user has permission to grant access to (items that are readonly and not already selected are never passed in)

It does make the logic more complex in some ways, but the LOC impact is still small, and it avoids trying to hack around Angular change detection, which I think is worth it.

Interestingly, it reverts all changes to the access-selector - we now set up all our data in the member modal only. Arguably that's a good thing because it reflects the presentational design of the component and avoids adding complexity to it.

vincentsalucci
vincentsalucci previously approved these changes Apr 9, 2024
@eliykat
Copy link
Member Author

eliykat commented Apr 15, 2024

I noticed that the previous logic did not filter out readonly collections when inviting a new user. This meant they were all selected by default. I moved the initial assignment of collectionAccessItems out of loadOrganizationUser and back into the main loading method so that it runs for both new and existing orgUsers, with some tweaks to allow for a null userDetails.

),
);

const accessSelections = mapToAccessSelections(userDetails);
// Set current collections and groups the user has access to (excluding collections the current user doesn't have
// permissions to change - they are included as readonly via the CollectionAccessItems
Copy link
Member

Choose a reason for hiding this comment

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

Missing a closing ) for this comment.

vincentsalucci
vincentsalucci previously approved these changes Apr 15, 2024
@eliykat eliykat requested a review from a team April 16, 2024 00:58
@eliykat eliykat merged commit 4db3838 into main Apr 17, 2024
59 of 62 checks passed
@eliykat eliykat deleted the ac/ac-2172/member-modal---access-selector-changes branch April 17, 2024 01:03
MGibson1 pushed a commit that referenced this pull request Apr 22, 2024
* limit admin permissions to assign members to collections that the admin
doesn't have can manage permissions for
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.

None yet

5 participants