Skip to content

Conversation

@voommen-livefront
Copy link
Collaborator

🎟️ Tracking

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

📔 Objective

Added the usePhishingBlocker flag to dbo.Organization
Updated EntityFramework & Migrations
Added a flag in the Admin pages for an organization to Use Phishing Blocker
Updated the models and views here as well.

📸 Screenshots

UI for Admin Console

image

Database (MSSQL)

image

Phishing Blocker in API calls

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

@claude
Copy link
Contributor

claude bot commented Nov 21, 2025

Claude finished @voommen-livefront's task —— View job


Code Review Complete ✓

I've completed a thorough review of this PR. The implementation follows the established patterns for adding organization flags and includes proper database migrations, model updates, and licensing support for self-hosted instances.


Summary of Changes

This PR adds the UsePhishingBlocker flag across the organization infrastructure:

  • Database schema updates (MSSQL, MySQL, PostgreSQL, SQLite)
  • Entity Framework migrations
  • Claims-based licensing support for self-hosted
  • Admin console UI integration
  • Comprehensive test coverage updates

Recent commits show good responsiveness to feedback:

  • Migration scripts now include proper column existence checks
  • Additional views refreshed (OrganizationCipherDetailsCollectionsView, ProviderOrganizationOrganizationDetailsView)
  • Removed deprecated constructor assignment (moved to claims-based system)
  • Proper alignment formatting in table definition

Critical Issues

Finding 1: Missing UsePhishingBlocker validation in VerifyData method

The UsePhishingBlocker property is correctly added to claims (OrganizationLicenseClaimsFactory.cs:60) but is not validated in the VerifyData method that verifies license data matches the organization.

Location: src/Core/Billing/Organizations/Models/OrganizationLicense.cs:464

Issue: The VerifyData method validates all organization properties against license claims, but UsePhishingBlocker is missing from the validation chain. This means:

  • Self-hosted instances won't properly validate this flag
  • License tampering or mismatches won't be detected
  • Inconsistent behavior with other similar flags

Required fix:

// After line 427, add:
var usePhishingBlocker = claimsPrincipal.GetValue<bool>(nameof(UsePhishingBlocker));

// In the return statement (line 464), add:
useAutomaticUserConfirmation == organization.UseAutomaticUserConfirmation &&
usePhishingBlocker == organization.UsePhishingBlocker;

Why this matters: Every other organization capability flag (UseAutomaticUserConfirmation, UseOrganizationDomains, UseAdminSponsoredFamilies, UseRiskInsights, etc.) is validated in this method. Omitting UsePhishingBlocker creates a security gap where the license system cannot verify this capability is properly licensed.


Minor Issues

Finding 2: Missing unit test coverage for UsePhishingBlocker in OrganizationEditModel.ToOrganization

While integration tests were updated, the OrganizationEditModel.ToOrganization method (line 333) assigns UsePhishingBlocker but there's no specific unit test verifying this assignment works correctly.

Suggestion: Add a unit test in the Admin.Test project to verify the property is correctly mapped.


Finding 3: Missing UsePhishingBlocker assignment in OrganizationEditModel constructor from license

The constructor at OrganizationEditModel.cs:38-113 initializes from an Organization entity (line 110), but there's no corresponding constructor that accepts an OrganizationLicense object. This is consistent with existing patterns, but worth noting for completeness.

Note: This is likely not required based on current architecture, but documenting for awareness.


Good Practices Observed

  • Proper use of claims-based licensing system (avoiding deprecated property-based approach)
  • Consistent naming and patterns matching existing organization flags
  • Migration scripts include proper idempotency checks
  • Test fixtures updated comprehensively across unit and integration tests
  • Admin UI follows established patterns and permission controls
  • Database changes properly cascaded through stored procedures and views
  • EntityFramework migrations generated for all database providers

Action Items

  1. MUST FIX: Add UsePhishingBlocker validation to VerifyData method in OrganizationLicense.cs
  2. ⚠️ RECOMMENDED: Add unit test coverage for OrganizationEditModel.ToOrganization
  3. ✓ Ensure CI passes (particularly the failing unit tests for license verification once Finding 1 is fixed)

Testing Notes

I cannot run the build or tests directly, but based on the codecov report:

  • Patch coverage: 79.31% (6 lines missing coverage)
  • Missing coverage appears in OrganizationEditModel, OrganizationFactory, OrganizationViewModel, and OrganizationLicenseClaimsFactory
  • These are likely test initialization lines and not critical paths

Recommendation: Author should verify all tests pass locally after addressing Finding 1, particularly OrganizationLicenseTests.OrganizationLicense_LoadedFromDisk_VerifyData_Passes.


@github-actions
Copy link
Contributor

github-actions bot commented Nov 21, 2025

Logo
Checkmarx One – Scan Summary & Detailsf0a13631-d5e7-4178-974f-6610bf8c8b09

Great job! No new security vulnerabilities introduced in this pull request

@codecov
Copy link

codecov bot commented Nov 21, 2025

Codecov Report

❌ Patch coverage is 78.57143% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 56.96%. Comparing base (6270591) to head (fe3356e).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
...Admin/AdminConsole/Models/OrganizationEditModel.cs 33.33% 2 Missing ⚠️
.../Core/AdminConsole/Services/OrganizationFactory.cs 33.33% 2 Missing ⚠️
...Admin/AdminConsole/Models/OrganizationViewModel.cs 0.00% 1 Missing ⚠️
...mplementations/OrganizationLicenseClaimsFactory.cs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6625      +/-   ##
==========================================
+ Coverage   52.98%   56.96%   +3.97%     
==========================================
  Files        1909     1902       -7     
  Lines       84828    84879      +51     
  Branches     7634     7633       -1     
==========================================
+ Hits        44948    48348    +3400     
+ Misses      38127    34705    -3422     
- Partials     1753     1826      +73     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@jrmccannon jrmccannon left a comment

Choose a reason for hiding this comment

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

@voommen-livefront
Usually when adding an organization feature, the feature needs to be added to the claims of the organization which will be included in the licensing file used by self-hosted instances.

If that needs to be considered for this flag, please review this guide that Admin Console has put together and also reach out to the billing team to validate the feature was added correctly.

Doing this will also break the unit tests and the doc has information on what to update to fix them.

Any questions let me know. Thanks!

@@ -0,0 +1,378 @@
/* Introduce new column 'UsePhishingBlocker' not nullable with default of 0 */
ALTER TABLE [dbo].[Organization] ADD [UsePhishingBlocker] bit NOT NULL CONSTRAINT [DF_Organization_UsePhishingBlocker] default (0)
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll need to protect this with a check to validate the table doesn't have the column already.

See an example here

@voommen-livefront voommen-livefront requested a review from a team as a code owner November 24, 2025 16:37
Copy link
Contributor

@mkincaid-bw mkincaid-bw left a comment

Choose a reason for hiding this comment

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

Minor change requested

[SyncSeats] BIT NOT NULL CONSTRAINT [DF_Organization_SyncSeats] DEFAULT (0),
[UseAutomaticUserConfirmation] BIT NOT NULL CONSTRAINT [DF_Organization_UseAutomaticUserConfirmation] DEFAULT (0),
[MaxStorageGbIncreased] SMALLINT NULL,
[UsePhishingBlocker] BIT NOT NULL CONSTRAINT [DF_Organization_UsePhishingBlocker] DEFAULT (0),
Copy link
Contributor

Choose a reason for hiding this comment

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

⛏️ Data type BIT and NOT NULL clause is not vertically aligned (changing it isn't necessary but it's nice when things line up 😃).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Formatting done.



--Manually refresh [dbo].[OrganizationUserOrganizationDetailsView]
IF OBJECT_ID('[dbo].[OrganizationUserOrganizationDetailsView]') IS NOT NULL
Copy link
Contributor

Choose a reason for hiding this comment

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

Since you are altering these 3 views by adding the new column, there's no need to refresh the views afterwards since they will be updated/refreshed as part of the ALTER statement (it won't hurt though).

What is important is refreshing any views that reference any table that was changed that are not modified in the migration. There are 5 views total that reference the Organization table and you've modified three. The other two are:

EXEC sp_refreshview N'[dbo].[OrganizationCipherDetailsCollectionsView]';
EXEC sp_refreshview N'[dbo].[ProviderOrganizationOrganizationDetailsView]';

You should also refresh any views that reference any of these 5 views. I checked and it appears that no other views reference these views, so we should be good there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thank you for catching this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added these two views to the scripts to be refreshed.

SmServiceAccounts = org.SmServiceAccounts;
UseRiskInsights = org.UseRiskInsights;
UseOrganizationDomains = org.UseOrganizationDomains;
UsePhishingBlocker = org.UsePhishingBlocker;
Copy link
Contributor

Choose a reason for hiding this comment

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

The large block comment above this section states that this is deprecated and "Do not add new properties to this constructor or extend its functionality." I think maybe this bit should be removed?

Those instructions also mention needing to add your new property to the CanUse and VerifyData methods. I'm assuming you can skip CanUse but you may want to double check if you need code in VerifyData. I am not very familiar with this license code but feel free to reach out to the billing team in slack if you have any questions!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You are right, I didn't need to add the property to the constructor.
Also, you are right, we don't need this property in VerifyData because this property does not limit or resitct the licensing in anyway. It's just a property of Organiation and if it is in a license JSON file, then it needs to be set in dbo.Organization.
I have removed the line from the constructor though.

@mkincaid-bw
Copy link
Contributor

Is this PR to address the incident from last week? If so, does the old code still need to be removed?

@Banrion
Copy link

Banrion commented Nov 25, 2025

Is this PR to address the incident from last week? If so, does the old code still need to be removed?

Yes. It's being tracked via PM-23358

Copy link
Contributor

@jrmccannon jrmccannon 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 from AC perspective

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

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.

7 participants