-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[AC-1174] Bulk Collection Management (#3229)
* [AC-1174] Update SelectionReadOnlyRequestModel to use Guid for Id property * [AC-1174] Introduce initial bulk-access collection endpoint * [AC-1174] Introduce BulkAddCollectionAccessCommand and validation logic/tests * [AC-1174] Add CreateOrUpdateAccessMany method to CollectionRepository * [AC-1174] Add event logs for bulk add collection access command * [AC-1174] Add User_BumpAccountRevisionDateByCollectionIds and database migration script * [AC-1174] Implement EF repository method * [AC-1174] Improve null checks * [AC-1174] Remove unnecessary BulkCollectionAccessRequestModel helpers * [AC-1174] Add unit tests for new controller endpoint * [AC-1174] Fix formatting * [AC-1174] Remove comment * [AC-1174] Remove redundant organizationId parameter * [AC-1174] Ensure user and group Ids are distinct * [AC-1174] Cleanup tests based on PR feedback * [AC-1174] Formatting * [AC-1174] Update CollectionGroup alias in the sproc * [AC-1174] Add some additional comments to SQL sproc * [AC-1174] Add comment explaining additional SaveChangesAsync call --------- Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
- Loading branch information
1 parent
2c7d02d
commit 5d431ad
Showing
16 changed files
with
943 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace Bit.Api.Models.Request; | ||
|
||
public class BulkCollectionAccessRequestModel | ||
{ | ||
public IEnumerable<Guid> CollectionIds { get; set; } | ||
public IEnumerable<SelectionReadOnlyRequestModel> Groups { get; set; } | ||
public IEnumerable<SelectionReadOnlyRequestModel> Users { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
src/Core/OrganizationFeatures/OrganizationCollections/BulkAddCollectionAccessCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using Bit.Core.Entities; | ||
using Bit.Core.Enums; | ||
using Bit.Core.Exceptions; | ||
using Bit.Core.Models.Data; | ||
using Bit.Core.OrganizationFeatures.OrganizationCollections.Interfaces; | ||
using Bit.Core.Repositories; | ||
using Bit.Core.Services; | ||
|
||
namespace Bit.Core.OrganizationFeatures.OrganizationCollections; | ||
|
||
public class BulkAddCollectionAccessCommand : IBulkAddCollectionAccessCommand | ||
{ | ||
private readonly ICollectionRepository _collectionRepository; | ||
private readonly IOrganizationUserRepository _organizationUserRepository; | ||
private readonly IGroupRepository _groupRepository; | ||
private readonly IEventService _eventService; | ||
|
||
public BulkAddCollectionAccessCommand( | ||
ICollectionRepository collectionRepository, | ||
IOrganizationUserRepository organizationUserRepository, | ||
IGroupRepository groupRepository, | ||
IEventService eventService) | ||
{ | ||
_collectionRepository = collectionRepository; | ||
_organizationUserRepository = organizationUserRepository; | ||
_groupRepository = groupRepository; | ||
_eventService = eventService; | ||
} | ||
|
||
public async Task AddAccessAsync(ICollection<Collection> collections, | ||
ICollection<CollectionAccessSelection> users, | ||
ICollection<CollectionAccessSelection> groups) | ||
{ | ||
await ValidateRequestAsync(collections, users, groups); | ||
|
||
await _collectionRepository.CreateOrUpdateAccessForManyAsync( | ||
collections.First().OrganizationId, | ||
collections.Select(c => c.Id), | ||
users, | ||
groups | ||
); | ||
|
||
await _eventService.LogCollectionEventsAsync(collections.Select(c => | ||
(c, EventType.Collection_Updated, (DateTime?)DateTime.UtcNow))); | ||
} | ||
|
||
private async Task ValidateRequestAsync(ICollection<Collection> collections, ICollection<CollectionAccessSelection> usersAccess, ICollection<CollectionAccessSelection> groupsAccess) | ||
{ | ||
if (collections == null || collections.Count == 0) | ||
{ | ||
throw new BadRequestException("No collections were provided."); | ||
} | ||
|
||
var orgId = collections.First().OrganizationId; | ||
|
||
if (collections.Any(c => c.OrganizationId != orgId)) | ||
{ | ||
throw new BadRequestException("All collections must belong to the same organization."); | ||
} | ||
|
||
var collectionUserIds = usersAccess?.Select(u => u.Id).Distinct().ToList(); | ||
|
||
if (collectionUserIds is { Count: > 0 }) | ||
{ | ||
var users = await _organizationUserRepository.GetManyAsync(collectionUserIds); | ||
|
||
if (users.Count != collectionUserIds.Count) | ||
{ | ||
throw new BadRequestException("One or more users do not exist."); | ||
} | ||
|
||
if (users.Any(u => u.OrganizationId != orgId)) | ||
{ | ||
throw new BadRequestException("One or more users do not belong to the same organization as the collection being assigned."); | ||
} | ||
} | ||
|
||
var collectionGroupIds = groupsAccess?.Select(g => g.Id).Distinct().ToList(); | ||
|
||
if (collectionGroupIds is { Count: > 0 }) | ||
{ | ||
var groups = await _groupRepository.GetManyByManyIds(collectionGroupIds); | ||
|
||
if (groups.Count != collectionGroupIds.Count) | ||
{ | ||
throw new BadRequestException("One or more groups do not exist."); | ||
} | ||
|
||
if (groups.Any(g => g.OrganizationId != orgId)) | ||
{ | ||
throw new BadRequestException("One or more groups do not belong to the same organization as the collection being assigned."); | ||
} | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...rganizationFeatures/OrganizationCollections/Interfaces/IBulkAddCollectionAccessCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Bit.Core.Entities; | ||
using Bit.Core.Models.Data; | ||
|
||
namespace Bit.Core.OrganizationFeatures.OrganizationCollections.Interfaces; | ||
|
||
public interface IBulkAddCollectionAccessCommand | ||
{ | ||
Task AddAccessAsync(ICollection<Collection> collections, | ||
ICollection<CollectionAccessSelection> users, ICollection<CollectionAccessSelection> groups); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.