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-10319] - Revoke Non Complaint Users for 2FA and Single Org Policy Enablement #5037

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

Conversation

jrmccannon
Copy link
Contributor

@jrmccannon jrmccannon commented Nov 13, 2024

🎟️ Tracking

PM-10319

📔 Objective

This change revokes non-compliant users when 2FA or Single Org policies are enabled. This adds the a RevokeNonCompliantOrganizationUserCommand along with a bulk set status stored procedure. It also adds two new email templates to be sent when a user is revoked from an organization.

📸 Screenshots

Two FA Policy Revocation Email
image

Single Org Policy Email
image

⏰ 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

@jrmccannon jrmccannon requested review from a team as code owners November 13, 2024 20:38
@jrmccannon jrmccannon changed the title [PM-10319] [PM-10319] - Revoke Non Complaint Users for 2FA and Single Org Policy Enablement Nov 13, 2024
Copy link
Contributor

github-actions bot commented Nov 13, 2024

Logo
Checkmarx One – Scan Summary & Details739ca795-2b37-4507-a15a-d7ee56e8bddb

New Issues

Severity Issue Source File / Package Checkmarx Insight
MEDIUM CSRF /src/Billing/Controllers/PayPalController.cs: 66 Attack Vector
MEDIUM CSRF /src/Api/AdminConsole/Controllers/ProviderUsersController.cs: 114 Attack Vector
MEDIUM CSRF /src/Api/AdminConsole/Controllers/ProviderUsersController.cs: 127 Attack Vector
MEDIUM Missing_HSTS_Header /src/Admin/Views/Home/Index.cshtml: 14 Attack Vector
LOW Missing_CSP_Header /src/Core/MailTemplates/Handlebars/FamiliesForEnterprise/FamiliesForEnterpriseRemovedFromFamilyUser.html.hbs: 5 Attack Vector
LOW Unsafe_Use_Of_Target_blank /src/Core/MailTemplates/Handlebars/AdminConsole/OrganizationUserRevokedForTwoFactorPolicy.html.hbs: 11 Attack Vector
LOW Unsafe_Use_Of_Target_blank /src/Core/MailTemplates/Handlebars/AdminConsole/OrganizationUserRevokedForTwoFactorPolicy.html.hbs: 11 Attack Vector

Fixed Issues

Severity Issue Source File / Package
MEDIUM CSRF /src/Billing/Controllers/RecoveryController.cs: 38
MEDIUM CSRF /src/Billing/Controllers/StripeController.cs: 164
MEDIUM CSRF /src/Api/AdminConsole/Public/Controllers/MembersController.cs: 95
MEDIUM CSRF /src/Admin/AdminConsole/Controllers/OrganizationsController.cs: 372
LOW Log_Forging /src/Api/AdminConsole/Controllers/ProvidersController.cs: 72
LOW Log_Forging /src/Api/AdminConsole/Controllers/ProvidersController.cs: 72
LOW Log_Forging /src/Api/AdminConsole/Controllers/ProvidersController.cs: 72

Copy link

codecov bot commented Nov 13, 2024

Codecov Report

Attention: Patch coverage is 64.50382% with 93 lines in your changes missing coverage. Please review.

Project coverage is 43.10%. Comparing base (dac8f66) to head (8669e90).

Files with missing lines Patch % Lines
.../Services/Implementations/HandlebarsMailService.cs 4.00% 24 Missing ⚠️
...icies/PolicyValidators/SingleOrgPolicyValidator.cs 68.18% 8 Missing and 6 partials ⚠️
...Users/RevokeNonCompliantOrganizationUserCommand.cs 81.35% 6 Missing and 5 partials ⚠️
...nizationDomains/VerifyOrganizationDomainCommand.cs 75.67% 7 Missing and 2 partials ⚠️
...lidators/TwoFactorAuthenticationPolicyValidator.cs 79.54% 4 Missing and 5 partials ⚠️
...Console/Repositories/OrganizationUserRepository.cs 0.00% 7 Missing ⚠️
...Console/Repositories/OrganizationUserRepository.cs 0.00% 7 Missing ⚠️
...nConsole/Services/Implementations/PolicyService.cs 42.85% 4 Missing ⚠️
src/Core/AdminConsole/Models/Data/SystemUser.cs 57.14% 3 Missing ⚠️
...re/Services/NoopImplementations/NoopMailService.cs 0.00% 2 Missing ⚠️
... and 3 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5037      +/-   ##
==========================================
+ Coverage   43.07%   43.10%   +0.03%     
==========================================
  Files        1417     1424       +7     
  Lines       64847    65055     +208     
  Branches     5927     5957      +30     
==========================================
+ Hits        27930    28043     +113     
- Misses      35683    35758      +75     
- Partials     1234     1254      +20     

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


🚨 Try these New Features:

@eliykat eliykat requested a review from r-tome November 15, 2024 07:22
Copy link
Contributor

@r-tome r-tome left a comment

Choose a reason for hiding this comment

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

Looks good, left some suggestions

jrmccannon and others added 7 commits November 15, 2024 09:45
…evokeNonCompliantOrganizationUserCommand.cs

Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com>
…ation. Adding unknown type to event system user. Adding optional parameter to SaveAsync in policy service in order to pass in event system user.


public async Task<OrganizationDomain> UserVerifyOrganizationDomainAsync(OrganizationDomain organizationDomain)
{
var domainVerificationResult = await VerifyOrganizationDomainAsync(organizationDomain);
var actingUser = new StandardUser(currentContext.UserId ?? Guid.Empty, await currentContext.OrganizationOwner(organizationDomain.OrganizationId));
Copy link
Contributor

Choose a reason for hiding this comment

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

Why pass an empty Guid and not the nullable Guid in the first parameter?

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'd rather not have null. I could throw at this point instead of using Guid.Empty. I was just defaulting to Guid.Empty in the event that a caller hasn't initialized the CurrentContext.

Do we know which applications would call this method without the CurrentContext populated with a user?

Copy link
Member

@eliykat eliykat Nov 21, 2024

Choose a reason for hiding this comment

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

I'm not sure about this method specifically, but generally:

  • the Public API and SCIM - CurrentContext.UserId is null because it's the organization that's authenticated, not the user
  • a system call (jobs) - also not tied to a user

A regular call from a client through the private api will always have UserId populated (to my knowledge) because CurrentContext is always initialized in the middleware and the private api always requires user authentication.

What this means for you here I'm not sure. This method seems specifically designed to be called by a user, so throwing if there is no UserId available seems reasonable. And if the UserId is null for some reason, then _currentContext.OrganizationOwner is probably not going to be accurate either (as this is also user specific). Really it seems like an invalid state.

Copy link
Contributor Author

@jrmccannon jrmccannon Nov 22, 2024

Choose a reason for hiding this comment

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

Added exception throw redirecting caller to use the other method. Not sure which exception to throw, so just going with InvalidOperation for now.

{
if (_featureService.IsEnabled(FeatureFlagKeys.Pm13322AddPolicyDefinitions))
{
// Transitional mapping - this will be moved to callers once the feature flag is removed
// TODO make sure to populate with SystemUser if not an actual user
Copy link
Contributor

Choose a reason for hiding this comment

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

TODO no longer needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This TODO will get addressed with a subsequent story.

Copy link
Member

@eliykat eliykat Nov 21, 2024

Choose a reason for hiding this comment

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

I can do this when I remove the policy definition feature flag shortly. Callers will have to construct their own PolicyUpdate objects, so I'll need to pass in the right ActingUser at that time.

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.

Looking good, just a couple of things.

Also see my feedback above re: empty guid vs. throwing.

Comment on lines +133 to +152
if (isAccountDeprovisioningEnabled)
{
await sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>()
.Received(1)
.RevokeNonCompliantOrganizationUsersAsync(Arg.Any<RevokeOrganizationUsersRequest>());
await sutProvider.GetDependency<IMailService>()
.Received(1)
.SendOrganizationUserRevokedForPolicySingleOrgEmailAsync(organization.DisplayName(),
"user3@example.com");
}
else
{
await sutProvider.GetDependency<IRemoveOrganizationUserCommand>()
.Received(1)
.RemoveUserAsync(policyUpdate.OrganizationId, nonCompliantUser.Id, savingUserId);
await sutProvider.GetDependency<IMailService>()
.Received(1)
.SendOrganizationUserRemovedForPolicySingleOrgEmailAsync(organization.DisplayName(),
"user3@example.com");
}
Copy link
Member

Choose a reason for hiding this comment

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

Not a blocker, but I generally avoid conditional assertions in tests; this suggests to me that you should just have 2 tests. That's easier to clean up as well, because you can just delete the whole test.

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.

4 participants