-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathUpdateCollectionCommand.cs
More file actions
87 lines (74 loc) · 3.67 KB
/
UpdateCollectionCommand.cs
File metadata and controls
87 lines (74 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
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 UpdateCollectionCommand : IUpdateCollectionCommand
{
private readonly IEventService _eventService;
private readonly IOrganizationRepository _organizationRepository;
private readonly ICollectionRepository _collectionRepository;
private readonly TimeProvider _timeProvider;
public UpdateCollectionCommand(
IEventService eventService,
IOrganizationRepository organizationRepository,
ICollectionRepository collectionRepository,
TimeProvider timeProvider)
{
_eventService = eventService;
_organizationRepository = organizationRepository;
_collectionRepository = collectionRepository;
_timeProvider = timeProvider;
}
public async Task<Collection> UpdateAsync(Collection collection, IEnumerable<CollectionAccessSelection> groups = null,
IEnumerable<CollectionAccessSelection> users = null)
{
if (collection.Type == CollectionType.DefaultUserCollection)
{
throw new BadRequestException("You cannot edit a collection with the type as DefaultUserCollection.");
}
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.
// When groups or users is null it means "don't change that association", so we must
// fall back to the existing relationships when evaluating this rule.
if (!org.AllowAdminAccessToAllCollectionItems)
{
IEnumerable<CollectionAccessSelection> groupsForValidation = groupsList;
IEnumerable<CollectionAccessSelection> usersForValidation = usersList;
if (groupsForValidation == null || usersForValidation == null)
{
var (_, currentAccess) = await _collectionRepository.GetByIdWithAccessAsync(collection.Id);
groupsForValidation ??= currentAccess.Groups;
usersForValidation ??= currentAccess.Users;
}
var groupHasManageAccess = groupsForValidation?.Any(g => g.Manage) ?? false;
var userHasManageAccess = usersForValidation?.Any(u => u.Manage) ?? false;
if (!groupHasManageAccess && !userHasManageAccess)
{
throw new BadRequestException(
"At least one member or group must have can manage permission.");
}
}
collection.RevisionDate = _timeProvider.GetUtcNow().UtcDateTime;
await _collectionRepository.ReplaceAsync(collection, org.UseGroups ? groupsList : null, usersList);
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Updated);
return collection;
}
}