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

[PM-16812] Shortcut duplicate group patch requests #5354

Open
wants to merge 24 commits into
base: main
Choose a base branch
from

Conversation

eliykat
Copy link
Member

@eliykat eliykat commented Jan 31, 2025

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-16812

📔 Objective

Solve 3 issues with our current SCIM PATCH group handling:

  1. Azure Entra ID sends redundant "add" requests for every remaining user in a group any time a user is removed. (As described in this existing support ticket). I've addressed this by querying group membership from the high availability db replica first and returning early if the request is redundant. This avoids a locking operation on the primary db, and the replica is better able to handle the load.
  2. There is potentially a race condition (with some unconfirmed reports) with competing requests reading existing group membership from the database, updating the membership in memory, then writing it back to the database. The result is that some users are not added to the group, because they've been overwritten by a competing request. This is addressed by sending all members to the database and having the sproc gracefully ignore existing members.
  3. (a late entrant) The group PATCH command does not deduplicate orgUserIds in the request.

While I was here, I refactored the Group Patch command to use a flat switch statement (rather than the various nested if / else ifs), and extracted constants to a separate file. This is implemented (along with the main changes) as a vNext version of the command behind a feature flag.

Testing is covered by:

  • new integration tests on the new database query
  • copy + paste of the existing unit tests on PatchGroupCommand, with some updates and extra cases to cover the updated behavior
  • copy + paste of the existing SCIM integration tests on the GroupController. There are no changes to the tests themselves as they are pretty high level, and specific functionality is covered in the unit tests. However, the suite is configured to enable the feature flag so that we're testing the new code. This also required some changes to the factory class which wasn't using its base class properly, so the SubstituteService method wasn't working properly otherwise.

📸 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

LaunchDarkly flag references

🔍 1 flag added or modified

Name Key Aliases found Info
Shortcut duplicate group PATCH requests pm-16812-shortcut-duplicate-patch-requests

Copy link

codecov bot commented Jan 31, 2025

Codecov Report

Attention: Patch coverage is 82.78146% with 26 lines in your changes missing coverage. Please review.

Project coverage is 44.38%. Comparing base (bde11da) to head (0360f7a).

Files with missing lines Patch % Lines
..._license/src/Scim/Groups/PatchGroupCommandvNext.cs 87.50% 7 Missing and 6 partials ⚠️
...apper/AdminConsole/Repositories/GroupRepository.cs 0.00% 13 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5354      +/-   ##
==========================================
+ Coverage   44.30%   44.38%   +0.08%     
==========================================
  Files        1497     1498       +1     
  Lines       69212    69360     +148     
  Branches     6241     6260      +19     
==========================================
+ Hits        30665    30788     +123     
- Misses      37224    37243      +19     
- Partials     1323     1329       +6     

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

Copy link
Contributor

github-actions bot commented Jan 31, 2025

Logo
Checkmarx One – Scan Summary & Details787d0581-d88d-42e5-8fcc-7ce9d7841f7c

New Issues (13)

Checkmarx found the following issues in this Pull Request

Severity Issue Source File / Package Checkmarx Insight
MEDIUM Missing_HSTS_Header /src/Billing/Startup.cs: 37
detailsThe web-application does not define an HSTS header, leaving it vulnerable to attack.
Attack Vector
MEDIUM Privacy_Violation /src/Core/Auth/Services/Implementations/AuthRequestService.cs: 226
detailsMethod UpdateAuthRequestAsync at line 226 of /src/Core/Auth/Services/Implementations/AuthRequestService.cs sends user information outside the appli...
Attack Vector
LOW Log_Forging /bitwarden_license/src/Scim/Controllers/v2/GroupsController.cs: 104
detailsMethod Patch at line 104 of /bitwarden_license/src/Scim/Controllers/v2/GroupsController.cs gets user input from element model. This element’s value...
Attack Vector
LOW Log_Forging /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 204
detailsMethod Put at line 204 of /src/Api/AdminConsole/Controllers/OrganizationsController.cs gets user input from element model. This element’s value flo...
Attack Vector
LOW Log_Forging /src/Api/AdminConsole/Controllers/OrganizationsController.cs: 531
detailsMethod PutCollectionManagement at line 531 of /src/Api/AdminConsole/Controllers/OrganizationsController.cs gets user input from element model. This...
Attack Vector
LOW Log_Forging /src/Api/Billing/Controllers/OrganizationBillingController.cs: 163
detailsMethod UpdatePaymentMethodAsync at line 163 of /src/Api/Billing/Controllers/OrganizationBillingController.cs gets user input from element requestBo...
Attack Vector
LOW Log_Forging /src/Api/Billing/Controllers/OrganizationBillingController.cs: 163
detailsMethod UpdatePaymentMethodAsync at line 163 of /src/Api/Billing/Controllers/OrganizationBillingController.cs gets user input from element requestBo...
Attack Vector
LOW Log_Forging /src/Api/Billing/Controllers/OrganizationBillingController.cs: 163
detailsMethod UpdatePaymentMethodAsync at line 163 of /src/Api/Billing/Controllers/OrganizationBillingController.cs gets user input from element requestBo...
Attack Vector
LOW Log_Forging /src/Api/Billing/Controllers/ProviderBillingController.cs: 104
detailsMethod UpdateTaxInformationAsync at line 104 of /src/Api/Billing/Controllers/ProviderBillingController.cs gets user input from element requestBody....
Attack Vector
LOW Log_Forging /src/Api/Billing/Controllers/ProviderBillingController.cs: 104
detailsMethod UpdateTaxInformationAsync at line 104 of /src/Api/Billing/Controllers/ProviderBillingController.cs gets user input from element requestBody....
Attack Vector
LOW Log_Forging /src/Api/Billing/Controllers/ProviderBillingController.cs: 104
detailsMethod UpdateTaxInformationAsync at line 104 of /src/Api/Billing/Controllers/ProviderBillingController.cs gets user input from element requestBody....
Attack Vector
LOW Log_Forging /src/Api/Billing/Controllers/OrganizationBillingController.cs: 163
detailsMethod UpdatePaymentMethodAsync at line 163 of /src/Api/Billing/Controllers/OrganizationBillingController.cs gets user input from element requestBo...
Attack Vector
LOW Missing_CSP_Header /src/Core/MailTemplates/Handlebars/Layouts/Full.html.hbs: 164
detailsA Content Security Policy is not explicitly defined within the web-application.
Attack Vector
Fixed Issues (16)

Great job! The following issues were fixed in this Pull Request

Severity Issue Source File / Package
MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 392
MEDIUM CSRF /src/Api/AdminConsole/Controllers/OrganizationUsersController.cs: 392
MEDIUM CSRF /src/Api/AdminConsole/Public/Controllers/MembersController.cs: 173
MEDIUM CSRF /src/Api/AdminConsole/Public/Controllers/MembersController.cs: 173
MEDIUM CSRF /src/Billing/Controllers/BitPayController.cs: 52
MEDIUM CSRF /src/Billing/Controllers/FreshdeskController.cs: 43
MEDIUM CSRF /src/Billing/Controllers/FreshdeskController.cs: 43
MEDIUM Privacy_Violation /src/Core/Auth/Services/Implementations/AuthRequestService.cs: 221
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/RecoveryController.cs: 38
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/RecoveryController.cs: 38
LOW Log_Forging /src/Billing/Controllers/StripeController.cs: 164
LOW Log_Forging /src/Billing/Controllers/RecoveryController.cs: 38
LOW Log_Forging /src/Billing/Controllers/RecoveryController.cs: 38
LOW Log_Forging /src/Api/Billing/Controllers/OrganizationSponsorshipsController.cs: 76

Comment on lines +134 to +147
private async Task AddMembersAsync(Group group, HashSet<Guid> usersToAdd)
{
// Azure Entra ID is known to send redundant "add" requests for each existing member every time any member
// is removed. To avoid excessive load on the database, we check against the high availability replica and
// return early if they already exist.
var groupMembers = await _groupRepository.GetManyUserIdsByIdAsync(group.Id, useReadOnlyReplica: true);
if (usersToAdd.IsSubsetOf(groupMembers))
{
_logger.LogDebug("Ignoring duplicate SCIM request to add members {Members} to group {Group}", usersToAdd, group.Id);
return;
}

await _groupRepository.AddGroupUsersByIdAsync(group.Id, usersToAdd);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

The interesting part of the new command.

@eliykat eliykat marked this pull request as ready for review February 5, 2025 05:20
@eliykat eliykat requested review from a team as code owners February 5, 2025 05:20
@eliykat eliykat requested a review from jrmccannon February 5, 2025 05:20
rkac-bw
rkac-bw previously approved these changes Feb 6, 2025
Copy link
Contributor

@rkac-bw rkac-bw left a comment

Choose a reason for hiding this comment

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

lgtm

@eliykat
Copy link
Member Author

eliykat commented Feb 6, 2025

Database tests are failing but for an unrelated sproc. Investigating it with the team. PR can still be reviewed in the meantime.

jrmccannon
jrmccannon previously approved these changes Feb 7, 2025
@eliykat eliykat dismissed stale reviews from jrmccannon and rkac-bw via 0360f7a February 10, 2025 21:08
@eliykat
Copy link
Member Author

eliykat commented Feb 10, 2025

Resolved conflicts - the only conflict was around the feature flag definitions in Constants.cs.

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.

3 participants