mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 08:02:49 -05:00
[AC-2154] Logging organization data before migrating for flexible collections (#3761)
* [AC-2154] Logging organization data before migrating for flexible collections * [AC-2154] Refactored logging command to perform the data migration * [AC-2154] Moved validation inside the command * [AC-2154] PR feedback * [AC-2154] Changed logging level to warning * [AC-2154] Fixed unit test * [AC-2154] Removed logging unnecessary data * [AC-2154] Removed primary constructor * [AC-2154] Added comments
This commit is contained in:
@ -0,0 +1,12 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationCollectionEnhancements.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Enable collection enhancements for an organization.
|
||||
/// This command will be deprecated once all organizations have collection enhancements enabled.
|
||||
/// </summary>
|
||||
public interface IOrganizationEnableCollectionEnhancementsCommand
|
||||
{
|
||||
Task EnableCollectionEnhancements(Organization organization);
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationCollectionEnhancements.Interfaces;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationCollectionEnhancements;
|
||||
|
||||
public class OrganizationEnableCollectionEnhancementsCommand : IOrganizationEnableCollectionEnhancementsCommand
|
||||
{
|
||||
private readonly ICollectionRepository _collectionRepository;
|
||||
private readonly IGroupRepository _groupRepository;
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly ILogger<OrganizationEnableCollectionEnhancementsCommand> _logger;
|
||||
|
||||
public OrganizationEnableCollectionEnhancementsCommand(ICollectionRepository collectionRepository,
|
||||
IGroupRepository groupRepository,
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IOrganizationService organizationService,
|
||||
ILogger<OrganizationEnableCollectionEnhancementsCommand> logger)
|
||||
{
|
||||
_collectionRepository = collectionRepository;
|
||||
_groupRepository = groupRepository;
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
_organizationService = organizationService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task EnableCollectionEnhancements(Organization organization)
|
||||
{
|
||||
if (organization.FlexibleCollections)
|
||||
{
|
||||
throw new BadRequestException("Organization has already been migrated to the new collection enhancements");
|
||||
}
|
||||
|
||||
// Log the Organization data that will change when the migration is complete
|
||||
await LogPreMigrationDataAsync(organization.Id);
|
||||
|
||||
// Run the data migration script
|
||||
await _organizationRepository.EnableCollectionEnhancements(organization.Id);
|
||||
|
||||
organization.FlexibleCollections = true;
|
||||
await _organizationService.ReplaceAndUpdateCacheAsync(organization);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method logs the data that will be migrated to the new collection enhancements so that it can be restored if needed
|
||||
/// </summary>
|
||||
/// <param name="organizationId"></param>
|
||||
private async Task LogPreMigrationDataAsync(Guid organizationId)
|
||||
{
|
||||
var groups = await _groupRepository.GetManyByOrganizationIdAsync(organizationId);
|
||||
// Grab Group Ids that have AccessAll enabled as it will be removed in the data migration
|
||||
var groupIdsWithAccessAllEnabled = groups
|
||||
.Where(g => g.AccessAll)
|
||||
.Select(g => g.Id)
|
||||
.ToList();
|
||||
|
||||
var organizationUsers = await _organizationUserRepository.GetManyByOrganizationAsync(organizationId, type: null);
|
||||
// Grab OrganizationUser Ids that have AccessAll enabled as it will be removed in the data migration
|
||||
var organizationUserIdsWithAccessAllEnabled = organizationUsers
|
||||
.Where(ou => ou.AccessAll)
|
||||
.Select(ou => ou.Id)
|
||||
.ToList();
|
||||
// Grab OrganizationUser Ids of Manager users as that will be downgraded to User in the data migration
|
||||
var migratedManagers = organizationUsers
|
||||
.Where(ou => ou.Type == OrganizationUserType.Manager)
|
||||
.Select(ou => ou.Id)
|
||||
.ToList();
|
||||
|
||||
var usersEligibleToManageCollections = organizationUsers
|
||||
.Where(ou =>
|
||||
ou.Type == OrganizationUserType.Manager ||
|
||||
(ou.Type == OrganizationUserType.Custom &&
|
||||
!string.IsNullOrEmpty(ou.Permissions) &&
|
||||
ou.GetPermissions().EditAssignedCollections)
|
||||
)
|
||||
.Select(ou => ou.Id)
|
||||
.ToList();
|
||||
var collectionUsers = await _collectionRepository.GetManyByOrganizationIdWithAccessAsync(organizationId);
|
||||
// Grab CollectionUser permissions that will change in the data migration
|
||||
var collectionUsersData = collectionUsers.SelectMany(tuple =>
|
||||
tuple.Item2.Users.Select(user =>
|
||||
new
|
||||
{
|
||||
CollectionId = tuple.Item1.Id,
|
||||
OrganizationUserId = user.Id,
|
||||
user.ReadOnly,
|
||||
user.HidePasswords
|
||||
}))
|
||||
.Where(cud => usersEligibleToManageCollections.Any(ou => ou == cud.OrganizationUserId))
|
||||
.ToList();
|
||||
|
||||
var logObject = new
|
||||
{
|
||||
OrganizationId = organizationId,
|
||||
GroupAccessAll = groupIdsWithAccessAllEnabled,
|
||||
UserAccessAll = organizationUserIdsWithAccessAllEnabled,
|
||||
MigratedManagers = migratedManagers,
|
||||
CollectionUsers = collectionUsersData
|
||||
};
|
||||
|
||||
_logger.LogWarning("Flexible Collections data migration started. Backup data: {@LogObject}", logObject);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user