Skip to content

Conversation

@r-tome
Copy link
Contributor

@r-tome r-tome commented Oct 22, 2025

🎟️ Tracking

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

📔 Objective

Wire up VNextSavePolicyCommand behind the PolicyValidatorsRefactor feature flag across all policy save endpoints: private API PutVNext, public API Put, domain verification, and SSO configuration

⏰ 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

@r-tome r-tome requested a review from JimmyVo16 October 22, 2025 16:20
@codecov
Copy link

codecov bot commented Oct 22, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.31%. Comparing base (3668a44) to head (0b4b98a).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6483      +/-   ##
==========================================
+ Coverage   52.27%   52.31%   +0.03%     
==========================================
  Files        1909     1909              
  Lines       84598    84664      +66     
  Branches     7558     7562       +4     
==========================================
+ Hits        44223    44289      +66     
  Misses      38659    38659              
  Partials     1716     1716              

☔ 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.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 22, 2025

Logo
Checkmarx One – Scan Summary & Detailsc51355d6-af16-44b5-9694-656a4633ebb3

New Issues (3)

Checkmarx found the following issues in this Pull Request

Severity Issue Source File / Package Checkmarx Insight
MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 427
detailsMethod at line 427 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
ID: qB2Oh4bvPkc2tAsuqY%2B%2FiPKPcCE%3D
Attack Vector
MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1537
detailsMethod at line 1537 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
ID: oS5I%2FDxqQus8L80ybnB6qqHIyTo%3D
Attack Vector
MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1408
detailsMethod at line 1408 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
ID: siIZQHKaoXC15rRHhlVxewk6xUo%3D
Attack Vector
Fixed Issues (2)

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

Severity Issue Source File / Package
MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 72
MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 300

@r-tome r-tome requested a review from Copilot October 24, 2025 10:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces wiring for VNextSavePolicyCommand behind the PolicyValidatorsRefactor feature flag across policy save endpoints. The implementation allows gradual migration from the legacy ISavePolicyCommand to the new IVNextSavePolicyCommand interface.

Key Changes

  • Added IVNextSavePolicyCommand dependency injection alongside existing ISavePolicyCommand across services and controllers
  • Implemented feature flag checks that route policy saves to either the new VNext command or legacy command based on the PolicyValidatorsRefactor flag
  • Added comprehensive test coverage for both enabled and disabled feature flag scenarios

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Core/Constants.cs Added PolicyValidatorsRefactor feature flag constant
src/Core/Auth/Services/Implementations/SsoConfigService.cs Integrated VNext command with conditional routing based on feature flag for TDE policy saves
src/Core/AdminConsole/OrganizationFeatures/OrganizationDomains/VerifyOrganizationDomainCommand.cs Added feature flag check to route SingleOrg policy saves through VNext command
src/Api/AdminConsole/Public/Models/Request/PolicyUpdateRequestModel.cs Added ToSavePolicyModel method to support VNext command interface
src/Api/AdminConsole/Public/Controllers/PoliciesController.cs Implemented feature flag routing for public API policy updates
src/Api/AdminConsole/Controllers/PoliciesController.cs Implemented feature flag routing for private API PutVNext endpoint
test/Core.Test/Auth/Services/SsoConfigServiceTests.cs Added test verifying VNext command usage when feature flag enabled
test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationDomains/VerifyOrganizationDomainCommandTests.cs Added test verifying VNext command usage when feature flag enabled
test/Api.Test/Controllers/PoliciesControllerTests.cs Added tests for both enabled and disabled feature flag scenarios in PutVNext
test/Api.Test/AdminConsole/Public/Controllers/PoliciesControllerTests.cs Added tests for both enabled and disabled feature flag scenarios in public API Put

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@r-tome r-tome changed the title Ac/pm 26690/use vnextsavepolicycommand [PM-26690] Wire VNextSavePolicyCommand behind PolicyValidatorsRefactor feature flag Oct 24, 2025
@r-tome r-tome marked this pull request as ready for review October 24, 2025 10:34
@r-tome r-tome requested review from a team as code owners October 24, 2025 10:34
Copy link
Contributor

@JimmyVo16 JimmyVo16 left a comment

Choose a reason for hiding this comment

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

Just one small suggestion.

{
var performedBy = new SystemUser(EventSystemUser.Unknown);
await _vNextSavePolicyCommand.SaveAsync(new SavePolicyModel(singleOrgPolicy, performedBy, new EmptyMetadataModel()));
await _vNextSavePolicyCommand.SaveAsync(new SavePolicyModel(resetPasswordPolicy, performedBy, new EmptyMetadataModel()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding a different constructor for SavePolicyModel, so the client can simply pass in what it has, and the SavePolicyModel object will fill in the default values.

Currently, the client needs to be aware that EmptyMetadataModel is the default value. We're also calling this logic in multiple places, so centralizing it would be nice, even if the value is low.

So something like this.

public record SavePolicyModel(PolicyUpdate PolicyUpdate, IActingUser? PerformedBy, IPolicyMetadataModel Metadata)
{
    public SavePolicyModel(PolicyUpdate PolicyUpdate)
        : this(PolicyUpdate, null, new EmptyMetadataModel())
    {
    }

    public SavePolicyModel(PolicyUpdate PolicyUpdate, IActingUser performedBy)
        : this(PolicyUpdate, performedBy, new EmptyMetadataModel())
    {
    }

    public SavePolicyModel(PolicyUpdate PolicyUpdate, EmptyMetadataModel metadata)
        : this(PolicyUpdate, null, metadata)
    {
    }
}

@sonarqubecloud
Copy link

@r-tome r-tome requested a review from JimmyVo16 October 27, 2025 15:15
JimmyVo16
JimmyVo16 previously approved these changes Oct 27, 2025
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Base automatically changed from ac/pm-26429/add-validation-to-policy-data-and-metadata to main November 3, 2025 15:44
@r-tome r-tome dismissed stale reviews from Patrick-Pimentel-Bitwarden and JimmyVo16 November 3, 2025 15:44

The base branch was changed.

@r-tome r-tome marked this pull request as draft November 3, 2025 16:33
@r-tome r-tome force-pushed the ac/pm-26690/use-vnextsavepolicycommand branch from cf6d0d1 to 5cbadc1 Compare November 3, 2025 16:35
…on feature flag

- Added IFeatureService and IVNextSavePolicyCommand dependencies to PoliciesController.
- Updated PutVNext method to conditionally use VNextSavePolicyCommand or SavePolicyCommand based on the PolicyValidatorsRefactor feature flag.
- Enhanced unit tests to verify behavior for both enabled and disabled states of the feature flag.
…d based on feature flag

- Introduced IFeatureService and IVNextSavePolicyCommand to manage policy saving based on the PolicyValidatorsRefactor feature flag.
- Updated the Put method to conditionally use the new VNextSavePolicyCommand or the legacy SavePolicyCommand.
- Added unit tests to validate the behavior of the Put method for both enabled and disabled states of the feature flag.
…ommand based on feature flag

- Added IFeatureService and IVNextSavePolicyCommand dependencies to VerifyOrganizationDomainCommand.
- Updated EnableSingleOrganizationPolicyAsync method to conditionally use VNextSavePolicyCommand or SavePolicyCommand based on the PolicyValidatorsRefactor feature flag.
- Enhanced unit tests to validate the behavior when the feature flag is enabled.
…feature flag

- Added IFeatureService and IVNextSavePolicyCommand dependencies to SsoConfigService.
- Updated SaveAsync method to conditionally use VNextSavePolicyCommand or SavePolicyCommand based on the PolicyValidatorsRefactor feature flag.
- Added unit tests to validate the behavior when the feature flag is enabled.
…ptyMetadataModel parameter. Update related usages across the codebase to reflect the new constructor overloads.
@r-tome r-tome force-pushed the ac/pm-26690/use-vnextsavepolicycommand branch from 5cbadc1 to fe9e8a7 Compare November 3, 2025 16:53
@r-tome r-tome marked this pull request as ready for review November 3, 2025 17:06
@claude
Copy link

claude bot commented Nov 3, 2025

Claude finished @r-tome's task —— View job


Code Review Complete

Summary

This PR successfully implements the VNextSavePolicyCommand wiring behind the PolicyValidatorsRefactor feature flag across all targeted policy save endpoints. The implementation follows a consistent pattern and includes comprehensive test coverage. Previous review feedback from @JimmyVo16 regarding SavePolicyModel constructors has been properly addressed.


Critical Issues

None identified - the implementation is solid and follows good practices.


Suggested Improvements

1. Missing null-safety directive in Constants.cs

Location: src/Core/Constants.cs:146

Issue: The new feature flag constant was added to a file that has #nullable disable at the top, perpetuating the technical debt.

Recommendation: While this aligns with the existing file pattern, consider creating a follow-up task to migrate Constants.cs to nullable reference types per ADR 0024. The file comment already acknowledges this with "FIXME: Update this file to be null safe".

Impact: Low - cosmetic/technical debt

2. Inconsistent feature flag checking pattern

Locations:

  • src/Api/AdminConsole/Controllers/PoliciesController.cs:230-232
  • src/Api/AdminConsole/Public/Controllers/PoliciesController.cs:101-110
  • src/Core/Auth/Services/Implementations/SsoConfigService.cs:100-112
  • src/Core/AdminConsole/OrganizationFeatures/OrganizationDomains/VerifyOrganizationDomainCommand.cs:147-155

Issue: Two different patterns are used for feature flag branching:

Pattern 1 (ternary operator in PoliciesController.cs:230):

var policy = _featureService.IsEnabled(FeatureFlagKeys.PolicyValidatorsRefactor) ?
    await _vNextSavePolicyCommand.SaveAsync(savePolicyRequest) :
    await _savePolicyCommand.VNextSaveAsync(savePolicyRequest);

Pattern 2 (if-else in Public/PoliciesController.cs:101):

Policy policy;
if (_featureService.IsEnabled(FeatureFlagKeys.PolicyValidatorsRefactor))
{
    var savePolicyModel = model.ToSavePolicyModel(_currentContext.OrganizationId!.Value, type);
    policy = await _vNextSavePolicyCommand.SaveAsync(savePolicyModel);
}
else
{
    var policyUpdate = model.ToPolicyUpdate(_currentContext.OrganizationId!.Value, type);
    policy = await _savePolicyCommand.SaveAsync(policyUpdate);
}

Recommendation: Standardize on the if-else pattern for better readability and consistency, especially when the branches involve different parameter transformations. The ternary is fine for simple value selections but becomes harder to read with async calls.

Impact: Low - readability/maintainability

3. Test naming could be more specific

Location: Test files

Issue: Test method names like Put_WhenPolicyValidatorsRefactorEnabled_UsesVNextSavePolicyCommand are clear but could be more precise about what "Uses" means.

Current:

Put_WhenPolicyValidatorsRefactorEnabled_UsesVNextSavePolicyCommand

Suggestion:

Put_WhenPolicyValidatorsRefactorEnabled_CallsVNextSavePolicyCommandAndNotLegacy

This makes it clearer that the test verifies both the positive case (calling VNext) and negative case (not calling legacy).

Impact: Very Low - test clarity

4. Potential for code duplication during feature flag cleanup

Issue: When the feature flag is eventually removed, there will be cleanup work across 4+ files to remove the branching logic and delete the legacy code paths.

Recommendation: Add a TODO comment at the feature flag constant definition to track the cleanup task:

// TODO: PM-XXXXX - Remove this feature flag after successful rollout
// Files to clean up: PoliciesController.cs, Public/PoliciesController.cs, 
// SsoConfigService.cs, VerifyOrganizationDomainCommand.cs
public const string PolicyValidatorsRefactor = "pm-26423-refactor-policy-side-effects";

Impact: Low - future maintainability


Good Practices Observed

  • Comprehensive test coverage: Added tests for both feature flag enabled and disabled states across all endpoints
  • Previous feedback addressed: The SavePolicyModel constructors suggested by @JimmyVo16 were properly implemented (lines 8-21 in SavePolicyModel.cs)
  • Consistent dependency injection: Both ISavePolicyCommand and IVNextSavePolicyCommand are properly injected in all affected services
  • Zero-knowledge preserved: No changes that could compromise data encryption
  • Proper acting user tracking: System users are correctly identified (e.g., SystemUser(EventSystemUser.PublicApi), SystemUser(EventSystemUser.Unknown))
  • Test isolation: Tests properly verify that only the expected command is called using DidNotReceiveWithAnyArgs()

Action Items

Required (Blocking)

None

Recommended (Non-blocking)

  1. Consider standardizing feature flag branching pattern across the codebase
  2. Add TODO comment to feature flag constant for future cleanup tracking
  3. Plan feature flag removal after successful rollout validation

Security & Performance Notes

  • Security: No security concerns identified. All changes maintain zero-knowledge architecture
  • Performance: No performance impact - feature flag check is a simple boolean comparison
  • Breaking Changes: None - changes are behind feature flag

Conclusion

This is a well-implemented feature flag integration. The code is production-ready with excellent test coverage. The suggested improvements are minor refinements that don't block merging. Great work on addressing the previous review feedback!

Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@r-tome r-tome merged commit 4aed97b into main Nov 6, 2025
39 checks passed
@r-tome r-tome deleted the ac/pm-26690/use-vnextsavepolicycommand branch November 6, 2025 11:35
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