mirror of
https://github.com/bitwarden/server.git
synced 2025-06-28 06:36:15 -05:00

* Implement UpdateCollectionCommand to handle collection updates with organization checks and access permissions. * Introduce IUpdateCollectionCommand interface for defining the collection update contract. * Add unit tests for UpdateCollectionCommand to validate various scenarios including permission checks and error handling.
60 lines
2.4 KiB
C#
60 lines
2.4 KiB
C#
using Bit.Core.Entities;
|
|
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 UpdateCollectionCommand : IUpdateCollectionCommand
|
|
{
|
|
private readonly IEventService _eventService;
|
|
private readonly IOrganizationRepository _organizationRepository;
|
|
private readonly ICollectionRepository _collectionRepository;
|
|
|
|
public UpdateCollectionCommand(
|
|
IEventService eventService,
|
|
IOrganizationRepository organizationRepository,
|
|
ICollectionRepository collectionRepository)
|
|
{
|
|
_eventService = eventService;
|
|
_organizationRepository = organizationRepository;
|
|
_collectionRepository = collectionRepository;
|
|
}
|
|
|
|
public async Task<Collection> UpdateAsync(Collection collection, IEnumerable<CollectionAccessSelection> groups = null,
|
|
IEnumerable<CollectionAccessSelection> users = null)
|
|
{
|
|
var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
|
|
if (org == null)
|
|
{
|
|
throw new BadRequestException("Organization not found");
|
|
}
|
|
|
|
var groupsList = groups?.ToList();
|
|
var usersList = users?.ToList();
|
|
|
|
// Cannot use Manage with ReadOnly/HidePasswords permissions
|
|
var invalidAssociations = groupsList?.Where(cas => cas.Manage && (cas.ReadOnly || cas.HidePasswords));
|
|
if (invalidAssociations?.Any() ?? false)
|
|
{
|
|
throw new BadRequestException("The Manage property is mutually exclusive and cannot be true while the ReadOnly or HidePasswords properties are also true.");
|
|
}
|
|
|
|
// A collection should always have someone with Can Manage permissions
|
|
var groupHasManageAccess = groupsList?.Any(g => g.Manage) ?? false;
|
|
var userHasManageAccess = usersList?.Any(u => u.Manage) ?? false;
|
|
if (!groupHasManageAccess && !userHasManageAccess && !org.AllowAdminAccessToAllCollectionItems)
|
|
{
|
|
throw new BadRequestException(
|
|
"At least one member or group must have can manage permission.");
|
|
}
|
|
|
|
await _collectionRepository.ReplaceAsync(collection, org.UseGroups ? groupsList : null, usersList);
|
|
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Updated);
|
|
|
|
return collection;
|
|
}
|
|
}
|