2022-07-25 09:56:23 +01:00
|
|
|
|
using Bit.Core.Context;
|
|
|
|
|
|
using Bit.Core.Entities;
|
2021-08-10 14:38:58 -04:00
|
|
|
|
using Bit.Core.Enums;
|
2017-04-03 12:27:02 -04:00
|
|
|
|
using Bit.Core.Exceptions;
|
2021-08-10 14:38:58 -04:00
|
|
|
|
using Bit.Core.Models.Business;
|
2017-05-11 12:22:14 -04:00
|
|
|
|
using Bit.Core.Models.Data;
|
2017-04-08 10:44:13 -04:00
|
|
|
|
using Bit.Core.Repositories;
|
2017-04-03 12:27:02 -04:00
|
|
|
|
|
|
|
|
|
|
namespace Bit.Core.Services;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2017-04-03 12:27:02 -04:00
|
|
|
|
public class CollectionService : ICollectionService
|
|
|
|
|
|
{
|
2017-04-27 09:19:30 -04:00
|
|
|
|
private readonly IEventService _eventService;
|
2017-04-03 12:27:02 -04:00
|
|
|
|
private readonly IOrganizationRepository _organizationRepository;
|
|
|
|
|
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
2017-04-27 09:19:30 -04:00
|
|
|
|
private readonly ICollectionRepository _collectionRepository;
|
2017-04-03 12:27:02 -04:00
|
|
|
|
private readonly IUserRepository _userRepository;
|
|
|
|
|
|
private readonly IMailService _mailService;
|
2021-08-10 14:38:58 -04:00
|
|
|
|
private readonly IReferenceEventService _referenceEventService;
|
2022-07-25 09:56:23 +01:00
|
|
|
|
private readonly ICurrentContext _currentContext;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2017-04-27 09:19:30 -04:00
|
|
|
|
public CollectionService(
|
|
|
|
|
|
IEventService eventService,
|
2017-04-03 12:27:02 -04:00
|
|
|
|
IOrganizationRepository organizationRepository,
|
|
|
|
|
|
IOrganizationUserRepository organizationUserRepository,
|
2017-04-27 09:19:30 -04:00
|
|
|
|
ICollectionRepository collectionRepository,
|
2017-04-03 12:27:02 -04:00
|
|
|
|
IUserRepository userRepository,
|
2021-08-10 14:38:58 -04:00
|
|
|
|
IMailService mailService,
|
2022-07-25 09:56:23 +01:00
|
|
|
|
IReferenceEventService referenceEventService,
|
2017-04-03 12:27:02 -04:00
|
|
|
|
ICurrentContext currentContext)
|
|
|
|
|
|
{
|
2017-12-01 16:00:30 -05:00
|
|
|
|
_eventService = eventService;
|
2017-04-03 12:27:02 -04:00
|
|
|
|
_organizationRepository = organizationRepository;
|
|
|
|
|
|
_organizationUserRepository = organizationUserRepository;
|
2017-04-27 09:19:30 -04:00
|
|
|
|
_collectionRepository = collectionRepository;
|
2017-04-03 12:27:02 -04:00
|
|
|
|
_userRepository = userRepository;
|
|
|
|
|
|
_mailService = mailService;
|
2021-08-10 14:38:58 -04:00
|
|
|
|
_referenceEventService = referenceEventService;
|
2022-07-25 09:56:23 +01:00
|
|
|
|
_currentContext = currentContext;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2017-04-03 12:27:02 -04:00
|
|
|
|
|
2017-04-27 09:19:30 -04:00
|
|
|
|
public async Task SaveAsync(Collection collection, IEnumerable<SelectionReadOnly> groups = null,
|
|
|
|
|
|
Guid? assignUserId = null)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-04-03 12:27:02 -04:00
|
|
|
|
var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
|
|
|
|
|
|
if (org == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new BadRequestException("Organization not found");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-17 14:58:45 -04:00
|
|
|
|
if (collection.Id == default(Guid))
|
2017-04-08 10:44:13 -04:00
|
|
|
|
{
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (org.MaxCollections.HasValue)
|
2017-05-09 12:41:36 -04:00
|
|
|
|
{
|
|
|
|
|
|
var collectionCount = await _collectionRepository.GetCountByOrganizationIdAsync(org.Id);
|
|
|
|
|
|
if (org.MaxCollections.Value <= collectionCount)
|
|
|
|
|
|
{
|
2017-05-11 12:22:14 -04:00
|
|
|
|
throw new BadRequestException("You have reached the maximum number of collections " +
|
2017-04-27 09:19:30 -04:00
|
|
|
|
$"({org.MaxCollections.Value}) for this organization.");
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2017-12-01 16:00:30 -05:00
|
|
|
|
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (groups == null || !org.UseGroups)
|
2018-10-17 14:58:45 -04:00
|
|
|
|
{
|
2017-05-09 12:41:36 -04:00
|
|
|
|
await _collectionRepository.CreateAsync(collection);
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2018-10-17 14:58:45 -04:00
|
|
|
|
else
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2018-10-17 14:58:45 -04:00
|
|
|
|
await _collectionRepository.CreateAsync(collection, groups);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Assign a user to the newly created collection.
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (assignUserId.HasValue)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-10-17 14:58:45 -04:00
|
|
|
|
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(org.Id, assignUserId.Value);
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (orgUser != null && orgUser.Status == Enums.OrganizationUserStatusType.Confirmed)
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2018-07-09 23:07:04 -04:00
|
|
|
|
await _collectionRepository.UpdateUsersAsync(collection.Id,
|
2018-10-17 14:58:45 -04:00
|
|
|
|
new List<SelectionReadOnly> {
|
|
|
|
|
|
new SelectionReadOnly { Id = orgUser.Id, ReadOnly = false } });
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2022-08-29 15:53:48 -04:00
|
|
|
|
|
2017-12-01 16:00:30 -05:00
|
|
|
|
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Created);
|
2021-08-10 14:38:58 -04:00
|
|
|
|
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.CollectionCreated, org));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (!org.UseGroups)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-05-09 12:41:36 -04:00
|
|
|
|
await _collectionRepository.ReplaceAsync(collection);
|
2017-04-08 10:44:13 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2017-11-24 11:53:15 -05:00
|
|
|
|
await _collectionRepository.ReplaceAsync(collection, groups ?? new List<SelectionReadOnly>());
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2017-12-01 16:00:30 -05:00
|
|
|
|
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Updated);
|
2017-04-08 10:44:13 -04:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-01 16:00:30 -05:00
|
|
|
|
public async Task DeleteAsync(Collection collection)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-12-01 16:00:30 -05:00
|
|
|
|
await _collectionRepository.DeleteAsync(collection);
|
|
|
|
|
|
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Deleted);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2017-12-01 16:00:30 -05:00
|
|
|
|
|
|
|
|
|
|
public async Task DeleteUserAsync(Collection collection, Guid organizationUserId)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-07-09 23:07:04 -04:00
|
|
|
|
var orgUser = await _organizationUserRepository.GetByIdAsync(organizationUserId);
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (orgUser == null || orgUser.OrganizationId != collection.OrganizationId)
|
2017-12-01 16:00:30 -05:00
|
|
|
|
{
|
|
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
2018-07-09 23:07:04 -04:00
|
|
|
|
await _collectionRepository.DeleteUserAsync(collection.Id, organizationUserId);
|
|
|
|
|
|
await _eventService.LogOrganizationUserEventAsync(orgUser, Enums.EventType.OrganizationUser_Updated);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2018-07-09 23:07:04 -04:00
|
|
|
|
|
|
|
|
|
|
public async Task<IEnumerable<Collection>> GetOrganizationCollections(Guid organizationId)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-07-09 23:07:04 -04:00
|
|
|
|
if (!await _currentContext.ViewAllCollections(organizationId) && !await _currentContext.ManageUsers(organizationId))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
2022-07-25 09:56:23 +01:00
|
|
|
|
|
|
|
|
|
|
IEnumerable<Collection> orgCollections;
|
|
|
|
|
|
if (await _currentContext.OrganizationAdmin(organizationId) || await _currentContext.ViewAllCollections(organizationId))
|
|
|
|
|
|
{
|
2022-07-28 17:23:43 +01:00
|
|
|
|
// Admins, Owners, Providers and Custom (with collection management permissions) can access all items even if not assigned to them
|
2022-07-25 09:56:23 +01:00
|
|
|
|
orgCollections = await _collectionRepository.GetManyByOrganizationIdAsync(organizationId);
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2022-07-25 09:56:23 +01:00
|
|
|
|
var collections = await _collectionRepository.GetManyByUserIdAsync(_currentContext.UserId.Value);
|
|
|
|
|
|
orgCollections = collections.Where(c => c.OrganizationId == organizationId);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 09:56:23 +01:00
|
|
|
|
return orgCollections;
|
2017-04-03 12:27:02 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|