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

Split Organization.LimitCollectionCreationDeletion into two separate business rules #4730

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

addisonbeck
Copy link
Contributor

@addisonbeck addisonbeck commented Sep 3, 2024

🎟️ Tracking

🧵 Jira Ticket: PM-10863

📚 Stacked PRs

  1. server: Split LimitCollectionCreationDeletion into two database columns #4709
  2. server: Split Organization.LimitCollectionCreationDeletion into two separate business rules #4730
    ⬆️ YOU ARE HERE
  3. clients: Split Organization.LimitCollectionCreationDeletion into two separate business rules clients#11223
  4. server: Turn on LimitCollectionCreationDeletionSplit for self host #4808
  5. server: Remove LimitCollectionCreationDeletionSplit feature flag #4809
  6. clients: Remove LimitCollectionCreationDeletionSplit feature flag clients#11258
  7. server: Drop LimitCollectionCreationDeletion from the database #4810

📔 Objective

🤳 The Bigger Picture

There is an option in the Admin Console that removes collection creation and
deletion controls from all organization members that are not in the Owner and
Admin roles. This PR stack splits this conjoined option into two separate
controls: one to block create operations and one to block delete
operations. This is a part of an effort to make these settings better align
with what customers expect it to do.

👉 This Pull Request 👍

In the previous PR we added two new database columns to facilitate a rename &
split operation on an existing column. In this PR we go about implementing
the new columns in server models and implementing the desired functionality
of those new properties throughout business logic and tests.

This PR and the two following it encompass all of the functional changes to
the system implemented by this PR stack. The next PR implements the feature
in the admin console UI in clients, and the one after that enables the
feature for self hosted installations. The first and second PRs are
maintenance tasks to support evolutionary database design and entity
framework.

🧮 Side Effects

There are several side effects involved in this PR. This includes:

  1. Updates to the front end of the admin portal to support the new
    organization properties.
  2. Updates to license files. We're removing these settings and
    AllowAdminsAccessToAllCollections from the license file as part of this
    work.
  3. A lot of difficult to follow updates to tests - mostly around licensing
    backwards compatibility.

📸 Screenshots

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

Copy link
Contributor

github-actions bot commented Sep 3, 2024

Logo
Checkmarx One – Scan Summary & Details4cb56aa9-1ab9-4f6e-93a0-24ddee8c350a

New Issues

Severity Issue Source File / Package Checkmarx Insight
MEDIUM Privacy_Violation /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 564 Attack Vector
MEDIUM Privacy_Violation /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 589 Attack Vector
MEDIUM Privacy_Violation /src/Api/Auth/Controllers/TwoFactorController.cs: 488 Attack Vector
MEDIUM Privacy_Violation /src/Api/Auth/Controllers/WebAuthnController.cs: 178 Attack Vector
MEDIUM Privacy_Violation /src/Api/Controllers/DevicesController.cs: 132 Attack Vector
MEDIUM Privacy_Violation /src/Api/Auth/Controllers/AccountsController.cs: 863 Attack Vector
MEDIUM Privacy_Violation /src/Api/Auth/Controllers/AccountsController.cs: 845 Attack Vector
MEDIUM Privacy_Violation /src/Api/Auth/Controllers/AccountsController.cs: 560 Attack Vector
MEDIUM Privacy_Violation /src/Api/Auth/Controllers/AccountsController.cs: 412 Attack Vector
MEDIUM Privacy_Violation /src/Api/Vault/Controllers/CiphersController.cs: 906 Attack Vector
MEDIUM Privacy_Violation /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 274 Attack Vector
MEDIUM Privacy_Violation /src/Api/Controllers/DevicesController.cs: 158 Attack Vector
MEDIUM Privacy_Violation /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 365 Attack Vector
MEDIUM Privacy_Violation /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 418 Attack Vector
LOW Log_Forging /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 576 Attack Vector
LOW Log_Forging /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 551 Attack Vector
LOW Log_Forging /src/Api/Auth/Controllers/WebAuthnController.cs: 85 Attack Vector
LOW Log_Forging /src/Api/Auth/Controllers/WebAuthnController.cs: 68 Attack Vector
LOW Log_Forging /src/Api/Auth/Controllers/WebAuthnController.cs: 153 Attack Vector
LOW Log_Forging /src/Api/Auth/Controllers/AccountsController.cs: 404 Attack Vector
LOW Log_Forging /src/Api/Auth/Controllers/AccountsController.cs: 837 Attack Vector
LOW Log_Forging /src/Api/Auth/Controllers/AccountsController.cs: 855 Attack Vector
LOW Log_Forging /src/Api/Controllers/DevicesController.cs: 123 Attack Vector
LOW Log_Forging /src/Api/Auth/Controllers/AccountsController.cs: 552 Attack Vector
LOW Log_Forging /src/Api/Vault/Controllers/CiphersController.cs: 898 Attack Vector
LOW Log_Forging /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 254 Attack Vector
LOW Log_Forging /src/Api/Controllers/DevicesController.cs: 149 Attack Vector
LOW Log_Forging /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 330 Attack Vector
LOW Log_Forging /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 393 Attack Vector

Fixed Issues

Severity Issue Source File / Package
MEDIUM CSRF /src/Billing/Controllers/StripeController.cs: 176
MEDIUM CSRF /src/Billing/Controllers/StripeController.cs: 164
MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 235
MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 455
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164

@addisonbeck addisonbeck force-pushed the ac/addison/pm-10863/entity-updates branch 4 times, most recently from 1f19ac7 to eca4cfc Compare September 3, 2024 20:06
Copy link

codecov bot commented Sep 3, 2024

Codecov Report

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

Project coverage is 41.59%. Comparing base (c449886) to head (d9703a0).

Files with missing lines Patch % Lines
...onsole/Views/Organizations/_ViewInformation.cshtml 0.00% 5 Missing ⚠️
...le/Services/Implementations/OrganizationService.cs 0.00% 5 Missing ⚠️
...esponse/Organizations/OrganizationResponseModel.cs 0.00% 4 Missing ⚠️
...anizationCollectionManagementUpdateRequestModel.cs 0.00% 4 Missing ⚠️
.../Collections/BulkCollectionAuthorizationHandler.cs 81.81% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4730      +/-   ##
==========================================
+ Coverage   41.57%   41.59%   +0.02%     
==========================================
  Files        1357     1358       +1     
  Lines       64056    64112      +56     
  Branches     5891     5900       +9     
==========================================
+ Hits        26631    26669      +38     
- Misses      36208    36224      +16     
- Partials     1217     1219       +2     

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

@addisonbeck addisonbeck force-pushed the ac/addison/pm-10863/entity-updates branch 3 times, most recently from 30604fe to 03574a7 Compare September 5, 2024 20:40
@addisonbeck addisonbeck force-pushed the ac/addison/pm-10863/rename-limit-collection-creation-deletion branch 19 times, most recently from bd9fd83 to 5e231f7 Compare September 11, 2024 19:01
@addisonbeck addisonbeck force-pushed the ac/addison/pm-10863/rename-limit-collection-creation-deletion branch from 87d6654 to 69a1adf Compare September 16, 2024 10:59
Copy link
Member

@eliykat eliykat left a comment

Choose a reason for hiding this comment

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

There's a bit of complexity to this that I think you've handled really well 👍

@@ -55,6 +55,9 @@ public OrganizationResponseModel(Organization organization, string obj = "organi
SmServiceAccounts = organization.SmServiceAccounts;
MaxAutoscaleSmSeats = organization.MaxAutoscaleSmSeats;
MaxAutoscaleSmServiceAccounts = organization.MaxAutoscaleSmServiceAccounts;
LimitCollectionCreation = organization.LimitCollectionCreation;
LimitCollectionDeletion = organization.LimitCollectionDeletion;
// Deperectated: https://bitwarden.atlassian.net/browse/PM-10863
Copy link
Member

Choose a reason for hiding this comment

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

I actually love this misspelling

Copy link
Contributor Author

@addisonbeck addisonbeck Oct 4, 2024

Choose a reason for hiding this comment

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

So do I, but I did correct it anyway.

Commit: Fix mispelling

Comment on lines 129 to 131
var limitCollectionCreationEnabled = !(_featureService.IsEnabled(FeatureFlagKeys.LimitCollectionCreationDeletionSplit)
? organizationAbility is { LimitCollectionCreation: false }
: organizationAbility is { LimitCollectionCreationDeletion: false });
Copy link
Member

Choose a reason for hiding this comment

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

I think the true/false case is around the wrong way here. Also the variable is called enabled but it's set to true if the setting is disabled. Maybe the ! operator has been applied in the wrong place?

Would this work?

Suggested change
var limitCollectionCreationEnabled = !(_featureService.IsEnabled(FeatureFlagKeys.LimitCollectionCreationDeletionSplit)
? organizationAbility is { LimitCollectionCreation: false }
: organizationAbility is { LimitCollectionCreationDeletion: false });
var limitCollectionCreation = _featureService.IsEnabled(FeatureFlagKeys.LimitCollectionCreationDeletionSplit
? organizationAbility is { LimitCollectionCreation: true }
: organizationAbility is { LimitCollectionCreationDeletion: true });

Copy link
Contributor Author

@addisonbeck addisonbeck Oct 4, 2024

Choose a reason for hiding this comment

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

This conditional logic is really messy, but changing it too much breaks tests. An exact implementation of your suggestion makes logical sense, and is what I tried to do at first, but something here isn't right and it seemed out of scope for me to spend a lot of time on it.

You can see this by looking at the Github Actions runs on the PR. They pass right before this commit which is an exact implementation of your suggestion that fails.

As for this specifically:

Also the variable is called enabled but it's set to true if the setting is disabled.

That's not true. The variable is set to true if the setting is enabled. The right side of this equality operator is completely wrapped in an inversion, so the output of the whole ternary is inverted. The ternary evaluates to true if the setting is false and then that whole thing is flipped before the assignment to the variable.

Again, I know this is not very pleasant. I'm open to suggestions on how to improve this without getting off track too much from the work being done.

I'll drop the busted commit once you check it out.

Comment on lines 267 to 273
var limitCollectionDeletionEnabled = !(_featureService.IsEnabled(FeatureFlagKeys.LimitCollectionCreationDeletionSplit)
? organizationAbility is { LimitCollectionDeletion: false }
: organizationAbility is { LimitCollectionCreationDeletion: false });

var canDeleteManagedCollections =
!limitCollectionDeletionEnabled ||
org is { Type: OrganizationUserType.Owner or OrganizationUserType.Admin };
Copy link
Member

Choose a reason for hiding this comment

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

Same issue here as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Responded above

Comment on lines 370 to 375
/*
* Version 14 added LimitCollectionCreationDeletion and Version 15 added AllowAdminAccessToAllCollectionItems,
* however these are just user settings and it is not worth failing validation if they mismatch.
* They are intentionally excluded.
*/

Copy link
Member

@eliykat eliykat Oct 3, 2024

Choose a reason for hiding this comment

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

I think it's worth keeping some version of this comment, otherwise there's just an unexplained gap in the validation for version 14. Maybe

Version 14 added LimitCollectionCreationDeletion and Version 15 added AllowAdminAccessToAllCollectionItems, however they are no longer used and are intentionally excluded from validation.

Copy link
Contributor Author

@addisonbeck addisonbeck Oct 4, 2024

Choose a reason for hiding this comment

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

@@ -253,7 +253,8 @@ public async Task GetManyDetailsByUserAsync_Works(IUserRepository userRepository
Assert.Equal(orgUser1.Permissions, result.Permissions);
Assert.Equal(organization.SmSeats, result.SmSeats);
Assert.Equal(organization.SmServiceAccounts, result.SmServiceAccounts);
Assert.Equal(organization.LimitCollectionCreationDeletion, result.LimitCollectionCreationDeletion);
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to keep the existing assertion until we remove the property altogether?

Copy link
Contributor Author

@addisonbeck addisonbeck Oct 4, 2024

Choose a reason for hiding this comment

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

Yes. I've added this back.

Commit: Add back deleted assertion for deprecated property

Comment on lines 114 to 115
LimitCollectionCreationDeletion = true,
AllowAdminAccessToAllCollectionItems = true,
Copy link
Member

Choose a reason for hiding this comment

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

You should keep these values here given that we're continuing to include them in the license file for now.

Copy link
Contributor Author

@addisonbeck addisonbeck Oct 4, 2024

Choose a reason for hiding this comment

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

@@ -300,7 +313,6 @@ public void UpdateFromLicense(OrganizationLicense license)
UseSecretsManager = license.UseSecretsManager;
SmSeats = license.SmSeats;
SmServiceAccounts = license.SmServiceAccounts;
LimitCollectionCreationDeletion = license.LimitCollectionCreationDeletion;
Copy link
Member

Choose a reason for hiding this comment

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

This method is used when updating an existing org from a license file. You've removed the LimitCollectionCreationDeletion assignment, but not AllowAdminAccessToAllCollectionItems, which is inconsistent.

Also, the OrganizationService.SignUpAsync method (which creates a new org from a license file) has this changed feature flagged, but here it's not feature flagged.

Copy link
Contributor Author

@addisonbeck addisonbeck Oct 4, 2024

Choose a reason for hiding this comment

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

I've added this removed property assignment back, and feature toggled both it and the AllowAdminAccessToAllCollectionItems assignment. This should look the same between Create and Update operations now.

Commit: Improve feature toggling scenerios for self hosted org creation/update

Copy link
Member

Choose a reason for hiding this comment

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

Please explain to Priya how this will work for older self-hosted customers. Not everyone upgrades immediately, there is likely to be a period where they see 1 setting in self-host but the 2 new settings in cloud, and still need to update it via the license file. Your mapping code will handle this by ORing the 2 new values, but we may have to answer some questions about it in the meantime.

Copy link
Member

Choose a reason for hiding this comment

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

Relatedly - how are we timing the rollout? If we enable the feature flag in cloud first, then self-hosted customers will be in this state at least until the next self-hosted release. That's probably unavoidable but worth discussing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm planning to record some demos. I'll include one of an out-of-date self hosted combination and attach in Jira with an explanation. As for the rollout: what you said is what I was thinking. I don't know what else we could do other than release to self host with the feature on alongside cloud and hope for the best. Seems better to lag a little and explain.

Copy link
Member

Choose a reason for hiding this comment

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

Note that the endpoint for this (OrganizationsController.PutCollectionManagement) is still blocked for self-hosted. Does this need to be changed in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've unblocked this endpoint. Thanks for catching that.

Commit: Unblock PutCollectionManagement for self host

Base automatically changed from ac/addison/pm-10863/rename-limit-collection-creation-deletion to main October 3, 2024 17:43
@addisonbeck addisonbeck force-pushed the ac/addison/pm-10863/entity-updates branch 4 times, most recently from b634f66 to 0103218 Compare October 4, 2024 18:10
@addisonbeck addisonbeck force-pushed the ac/addison/pm-10863/entity-updates branch from 0103218 to d9703a0 Compare October 4, 2024 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants