[PM-22450] Bump Collection.RevisionDate on edits and access changes#7380
[PM-22450] Bump Collection.RevisionDate on edits and access changes#7380
Conversation
…d update corresponding tests. Adjust tests to verify correct RevisionDate assignment during collection updates.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #7380 +/- ##
==========================================
+ Coverage 58.56% 62.92% +4.36%
==========================================
Files 2063 2063
Lines 91198 91279 +81
Branches 8125 8132 +7
==========================================
+ Hits 53406 57439 +4033
+ Misses 35881 31841 -4040
- Partials 1911 1999 +88 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
New Issues (2)Checkmarx found the following issues in this Pull Request
|
There was a problem hiding this comment.
The ticket says we need to bump the revision date in these scenarios:
- Whenever a collection has its name updated (including when it’s nested)
- Whenever a collection has its user/group assignment updated
- Whenever a user has their access to a collection updated
- Whenever a group has their access to a collection updated
I'm guessing this covers 1 and 2. What about 3 and 4? (That said - this PR is still good to merge.)
…cess updates. Update ICollectionRepository and its implementations to accept revision date parameter. Modify stored procedure to update collection revision dates accordingly. Add tests to verify correct behavior of access creation and revision date updates.
… affected collections during group creation and updates. Enhance integration tests to verify that collection revision dates are correctly updated when groups are created or modified.
…ionUserRepository and related stored procedures. Add integration tests to ensure revision dates are correctly bumped during organization user creation and updates.
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE This PR bumps Code Review Details
|
Great callout! I went even further and also updated when user is invited with collection access. |
src/Sql/dbo/Stored Procedures/OrganizationUser_CreateManyWithCollectionsGroups.sql
Outdated
Show resolved
Hide resolved
src/Sql/dbo/Stored Procedures/OrganizationUser_CreateManyWithCollectionsGroups.sql
Outdated
Show resolved
Hide resolved
src/Sql/dbo/Stored Procedures/OrganizationUser_UpdateWithCollections.sql
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/AdminConsole/Repositories/GroupRepository.cs
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationUserRepository.cs
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationUserRepository.cs
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationUserRepository.cs
Outdated
Show resolved
Hide resolved
....IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryTests.cs
Outdated
Show resolved
Hide resolved
...tionTest/AdminConsole/Repositories/OrganizationUserRepository/OrganizationUserCreateTests.cs
Outdated
Show resolved
Hide resolved
… updating RevisionDate of affected collections. This change improves readability and maintainability by consolidating the logic for identifying affected collections in Group_UpdateWithCollections and OrganizationUser_UpdateWithCollections procedures.
…ocedure to accept RevisionDate parameter for updating affected collections. Update OrganizationUserRepository to utilize the provided RevisionDate when available, ensuring accurate revision date management during organization user operations.
…on script to utilize temporary table for CollectionUser data insertion. This change improves performance and maintains consistency in updating RevisionDate for affected collections.
…from created OrganizationUsers when updating affected collections. This change enhances the accuracy of revision date management across the repository.
…roup and Collection repositories. Update assertions to compare RevisionDate directly, improving accuracy in revision date management during tests.
…ndling of RevisionDate. Updated collection filtering logic to use HashSet for efficiency and ensured that affected collections are filtered by OrganizationId, enhancing accuracy in revision date management.
The Dapper repositories use a System.Text.Json serialize/deserialize round-trip to build *WithCollections objects. System.Text.Json silently skips properties with non-public setters, so RevisionDate was reverting to DateTime.UtcNow instead of preserving the value set in C#.
src/Sql/dbo/Stored Procedures/OrganizationUser_CreateManyWithCollectionsGroups.sql
Show resolved
Hide resolved
…on script to improve the logic for updating RevisionDate. The update now uses INNER JOINs to ensure accurate filtering of collections based on OrganizationId and CollectionUser data, enhancing the precision of revision date management.
| [MaxLength(300)] | ||
| public string? ExternalId { get; set; } | ||
| public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; | ||
| public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; |
There was a problem hiding this comment.
The repository serializes/deserializes the entity for the sproc call, and the internal set prevented RevisionDate from being set, causing the value to be lost. Making it public fixes that.
There was a problem hiding this comment.
I also saw that only some entities have an internal set. I'm not sure why we have that inconsistency.
mkincaid-bw
left a comment
There was a problem hiding this comment.
Mainly formatting nit-picks and a comment on joins
| IF @RevisionDate IS NOT NULL | ||
| BEGIN | ||
| -- Bump the revision date on all affected collections | ||
| UPDATE C |
There was a problem hiding this comment.
⛏️ UPDATE statements should be broken out on separate lines per the style guide
| [Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) | ||
|
|
||
| -- Bump RevisionDate on all affected collections | ||
| UPDATE C |
There was a problem hiding this comment.
⛏️ UPDATE statements should be broken out on separate lines per the style guide
|
|
||
| -- Bump RevisionDate on all affected collections | ||
| ;WITH [AffectedCollectionsCTE] AS ( | ||
| SELECT [Id] FROM @Collections |
There was a problem hiding this comment.
⛏️ SELECT statements should be broken out on separate lines per the style guide
| -- Bump RevisionDate on all affected collections | ||
| IF @RevisionDate IS NOT NULL | ||
| BEGIN | ||
| UPDATE C |
There was a problem hiding this comment.
⛏️ UPDATE statements should be broken out on separate lines per the style guide
Also, the join to the OrganizationUser table can cause a performance bottleneck depending on how SQL server decides to execute the query. Since the list of CollectionIds are in the #CollectionUserData table, I think the join is unnecessary, and we can probably just use that.
UPDATE
C
SET
C.[RevisionDate] = @RevisionDate
FROM
[dbo].[Collection] C
INNER JOIN
#CollectionUserData CUD ON CUD.[CollectionId] = C.[Id]| [Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) | ||
|
|
||
| -- Bump RevisionDate on all affected collections | ||
| UPDATE C |
There was a problem hiding this comment.
⛏️ UPDATE statements should be broken out on separate lines per the style guide
|
|
||
| -- Bump RevisionDate on all affected collections | ||
| ;WITH [AffectedCollectionsCTE] AS ( | ||
| SELECT [Id] FROM @Collections |
There was a problem hiding this comment.
⛏️ SELECT statements should be broken out on separate lines per the style guide
| FROM [dbo].[CollectionUser] CU | ||
| WHERE CU.[OrganizationUserId] = @Id | ||
| ) | ||
| UPDATE C |
There was a problem hiding this comment.
⛏️ UPDATE statements should be broken out on separate lines per the style guide
src/Infrastructure.Dapper/AdminConsole/Repositories/OrganizationUserRepository.cs
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/AdminConsole/Repositories/GroupRepository.cs
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationUserRepository.cs
Show resolved
Hide resolved
....IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryTests.cs
Outdated
Show resolved
Hide resolved
…he supplied parameter is empty
|
@mkincaid-bw Thanks for catching all the style guide violations! All fixed now. |
| public string? ExternalId { get; set; } | ||
| public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; | ||
| public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; | ||
| public DateTime RevisionDate { get; set; } = DateTime.UtcNow; |
There was a problem hiding this comment.
🎨 SUGGESTED: The internal set → set change here (and on OrganizationUser.RevisionDate) widens the access modifier. Since Core.csproj already declares InternalsVisibleTo for Core.Test, Infrastructure.IntegrationTest, and Identity.IntegrationTest, the test assemblies can already use internal set. The production callers in this PR (EF/Dapper repos) only read Group.RevisionDate and OrganizationUser.RevisionDate — they don't set them.
Consider keeping internal set to preserve the encapsulation that prevents accidental modification from assemblies outside Core. CreationDate on both entities still uses internal set, so this change also introduces an inconsistency between the two date properties.
There was a problem hiding this comment.
That is wrong, Claude. I had to make the set public because otherwise on
it fails to populateRevisionDate with the given value and defaults to DateTime.UtcNow. I noticed this because the tests would fail.
|





🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-22450
📔 Objective
Collection.RevisionDatewas not updated when a collection was edited or when its access changed. Clients rely on this date to know when to re-sync. This PR bumps it across all code paths: collection edits viaUpdateCollectionCommand, user/group assignment changes, and bulk access operations -- in both stored procedures and EF repositories.