From add8783e31ee82d6985c4a027f610db4b87351ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Tom=C3=A9?= <108268980+r-tome@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:06:13 +0100 Subject: [PATCH] [PM-11667] Remove all code related to the outdated custom permissions 'Edit/Delete Assigned Collections' (#4736) --- .../OrganizationUsersController.cs | 40 --- .../ProfileOrganizationResponseModel.cs | 31 -- .../Public/Models/MemberBaseModel.cs | 35 +- .../Enums/OrganizationUserType.cs | 36 +- .../AdminConsole/Models/Data/Permissions.cs | 6 - .../OrganizationUserUserDetailsQuery.cs | 12 +- src/Core/Context/CurrentContext.cs | 2 - .../Controllers/MembersControllerTests.cs | 21 -- .../OrganizationUserUserDetailsQueryTests.cs | 63 +--- test/Core.Test/Models/PermissionsTests.cs | 4 - ...lFlexibleCollectionsDataMigrationsTests.cs | 335 ------------------ 11 files changed, 5 insertions(+), 580 deletions(-) delete mode 100644 test/Infrastructure.IntegrationTest/AdminConsole/Migrations/FinalFlexibleCollectionsDataMigrationsTests.cs diff --git a/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs b/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs index ce9fd5d8f..89c61b8de 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs @@ -17,7 +17,6 @@ using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Business; -using Bit.Core.Models.Data; using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces; @@ -108,16 +107,6 @@ public class OrganizationUsersController : Controller var response = new OrganizationUserDetailsResponseModel(organizationUser.Item1, organizationUser.Item2); - // Downgrade Custom users with no other permissions than 'Edit/Delete Assigned Collections' to User - response.Type = GetFlexibleCollectionsUserType(response.Type, response.Permissions); - - // Set 'Edit/Delete Assigned Collections' custom permissions to false - if (response.Permissions is not null) - { - response.Permissions.EditAssignedCollections = false; - response.Permissions.DeleteAssignedCollections = false; - } - if (includeGroups) { response.Groups = await _groupRepository.GetManyIdsByUserIdAsync(organizationUser.Item1.Id); @@ -638,35 +627,6 @@ public class OrganizationUsersController : Controller new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2))); } - private OrganizationUserType GetFlexibleCollectionsUserType(OrganizationUserType type, Permissions permissions) - { - // Downgrade Custom users with no other permissions than 'Edit/Delete Assigned Collections' to User - if (type == OrganizationUserType.Custom && permissions is not null) - { - if ((permissions.EditAssignedCollections || permissions.DeleteAssignedCollections) && - permissions is - { - AccessEventLogs: false, - AccessImportExport: false, - AccessReports: false, - CreateNewCollections: false, - EditAnyCollection: false, - DeleteAnyCollection: false, - ManageGroups: false, - ManagePolicies: false, - ManageSso: false, - ManageUsers: false, - ManageResetPassword: false, - ManageScim: false - }) - { - return OrganizationUserType.User; - } - } - - return type; - } - private async Task> Get_vNext(Guid orgId, bool includeGroups = false, bool includeCollections = false) { diff --git a/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs b/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs index 65b7a38a8..17ebfc095 100644 --- a/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs +++ b/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs @@ -71,37 +71,6 @@ public class ProfileOrganizationResponseModel : ResponseModel KeyConnectorEnabled = ssoConfigData.MemberDecryptionType == MemberDecryptionType.KeyConnector && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl); KeyConnectorUrl = ssoConfigData.KeyConnectorUrl; } - - // Downgrade Custom users with no other permissions than 'Edit/Delete Assigned Collections' to User - if (Type == OrganizationUserType.Custom && Permissions is not null) - { - if ((Permissions.EditAssignedCollections || Permissions.DeleteAssignedCollections) && - Permissions is - { - AccessEventLogs: false, - AccessImportExport: false, - AccessReports: false, - CreateNewCollections: false, - EditAnyCollection: false, - DeleteAnyCollection: false, - ManageGroups: false, - ManagePolicies: false, - ManageSso: false, - ManageUsers: false, - ManageResetPassword: false, - ManageScim: false - }) - { - organization.Type = OrganizationUserType.User; - } - } - - // Set 'Edit/Delete Assigned Collections' custom permissions to false - if (Permissions is not null) - { - Permissions.EditAssignedCollections = false; - Permissions.DeleteAssignedCollections = false; - } } public Guid Id { get; set; } diff --git a/src/Api/AdminConsole/Public/Models/MemberBaseModel.cs b/src/Api/AdminConsole/Public/Models/MemberBaseModel.cs index 79ec0ad78..931f63741 100644 --- a/src/Api/AdminConsole/Public/Models/MemberBaseModel.cs +++ b/src/Api/AdminConsole/Public/Models/MemberBaseModel.cs @@ -1,7 +1,6 @@ using System.ComponentModel.DataAnnotations; using Bit.Core.Entities; using Bit.Core.Enums; -using Bit.Core.Models.Data; using Bit.Core.Models.Data.Organizations.OrganizationUsers; namespace Bit.Api.AdminConsole.Public.Models; @@ -17,7 +16,7 @@ public abstract class MemberBaseModel throw new ArgumentNullException(nameof(user)); } - Type = GetFlexibleCollectionsUserType(user.Type, user.GetPermissions()); + Type = user.Type; ExternalId = user.ExternalId; ResetPasswordEnrolled = user.ResetPasswordKey != null; @@ -34,7 +33,7 @@ public abstract class MemberBaseModel throw new ArgumentNullException(nameof(user)); } - Type = GetFlexibleCollectionsUserType(user.Type, user.GetPermissions()); + Type = user.Type; ExternalId = user.ExternalId; ResetPasswordEnrolled = user.ResetPasswordKey != null; @@ -66,34 +65,4 @@ public abstract class MemberBaseModel /// default to false. /// public PermissionsModel? Permissions { get; set; } - - // TODO: AC-2188 - Remove this method when the custom users with no other permissions than 'Edit/Delete Assigned Collections' are migrated - private OrganizationUserType GetFlexibleCollectionsUserType(OrganizationUserType type, Permissions permissions) - { - // Downgrade Custom users with no other permissions than 'Edit/Delete Assigned Collections' to User - if (type == OrganizationUserType.Custom) - { - if ((permissions.EditAssignedCollections || permissions.DeleteAssignedCollections) && - permissions is - { - AccessEventLogs: false, - AccessImportExport: false, - AccessReports: false, - CreateNewCollections: false, - EditAnyCollection: false, - DeleteAnyCollection: false, - ManageGroups: false, - ManagePolicies: false, - ManageSso: false, - ManageUsers: false, - ManageResetPassword: false, - ManageScim: false - }) - { - return OrganizationUserType.User; - } - } - - return type; - } } diff --git a/src/Core/AdminConsole/Enums/OrganizationUserType.cs b/src/Core/AdminConsole/Enums/OrganizationUserType.cs index ac3393eea..be5986a65 100644 --- a/src/Core/AdminConsole/Enums/OrganizationUserType.cs +++ b/src/Core/AdminConsole/Enums/OrganizationUserType.cs @@ -1,6 +1,4 @@ -using Bit.Core.Models.Data; - -namespace Bit.Core.Enums; +namespace Bit.Core.Enums; public enum OrganizationUserType : byte { @@ -10,35 +8,3 @@ public enum OrganizationUserType : byte // Manager = 3 has been intentionally permanently deleted Custom = 4, } - -public static class OrganizationUserTypeExtensions -{ - public static OrganizationUserType GetFlexibleCollectionsUserType(this OrganizationUserType type, Permissions permissions) - { - // Downgrade Custom users with no other permissions than 'Edit/Delete Assigned Collections' to User - if (type == OrganizationUserType.Custom && permissions is not null) - { - if ((permissions.EditAssignedCollections || permissions.DeleteAssignedCollections) && - permissions is - { - AccessEventLogs: false, - AccessImportExport: false, - AccessReports: false, - CreateNewCollections: false, - EditAnyCollection: false, - DeleteAnyCollection: false, - ManageGroups: false, - ManagePolicies: false, - ManageSso: false, - ManageUsers: false, - ManageResetPassword: false, - ManageScim: false - }) - { - return OrganizationUserType.User; - } - } - - return type; - } -} diff --git a/src/Core/AdminConsole/Models/Data/Permissions.cs b/src/Core/AdminConsole/Models/Data/Permissions.cs index 8e94292b3..9edc3f1d5 100644 --- a/src/Core/AdminConsole/Models/Data/Permissions.cs +++ b/src/Core/AdminConsole/Models/Data/Permissions.cs @@ -10,10 +10,6 @@ public class Permissions public bool CreateNewCollections { get; set; } public bool EditAnyCollection { get; set; } public bool DeleteAnyCollection { get; set; } - [Obsolete("Pre-Flexible Collections logic.")] - public bool EditAssignedCollections { get; set; } - [Obsolete("Pre-Flexible Collections logic.")] - public bool DeleteAssignedCollections { get; set; } public bool ManageGroups { get; set; } public bool ManagePolicies { get; set; } public bool ManageSso { get; set; } @@ -30,8 +26,6 @@ public class Permissions (CreateNewCollections, "createnewcollections"), (EditAnyCollection, "editanycollection"), (DeleteAnyCollection, "deleteanycollection"), - (EditAssignedCollections, "editassignedcollections"), - (DeleteAssignedCollections, "deleteassignedcollections"), (ManageGroups, "managegroups"), (ManagePolicies, "managepolicies"), (ManageSso, "managesso"), diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/OrganizationUserUserDetailsQuery.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/OrganizationUserUserDetailsQuery.cs index 8322bbb47..22fce0802 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/OrganizationUserUserDetailsQuery.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/OrganizationUserUserDetailsQuery.cs @@ -1,5 +1,4 @@ -using Bit.Core.Enums; -using Bit.Core.Models.Data.Organizations.OrganizationUsers; +using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.Repositories; using Bit.Core.Utilities; using Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces; @@ -33,15 +32,6 @@ public class OrganizationUserUserDetailsQuery : IOrganizationUserUserDetailsQuer { var userPermissions = o.GetPermissions(); - // Downgrade Custom users with no other permissions than 'Edit/Delete Assigned Collections' to User - o.Type = o.Type.GetFlexibleCollectionsUserType(userPermissions); - - if (userPermissions is not null) - { - userPermissions.EditAssignedCollections = false; - userPermissions.DeleteAssignedCollections = false; - } - o.Permissions = CoreHelpers.ClassToJsonData(userPermissions); return o; diff --git a/src/Core/Context/CurrentContext.cs b/src/Core/Context/CurrentContext.cs index 20413068e..8143216f3 100644 --- a/src/Core/Context/CurrentContext.cs +++ b/src/Core/Context/CurrentContext.cs @@ -509,8 +509,6 @@ public class CurrentContext : ICurrentContext CreateNewCollections = hasClaim("createnewcollections"), EditAnyCollection = hasClaim("editanycollection"), DeleteAnyCollection = hasClaim("deleteanycollection"), - EditAssignedCollections = hasClaim("editassignedcollections"), - DeleteAssignedCollections = hasClaim("deleteassignedcollections"), ManageGroups = hasClaim("managegroups"), ManagePolicies = hasClaim("managepolicies"), ManageSso = hasClaim("managesso"), diff --git a/test/Api.IntegrationTest/AdminConsole/Public/Controllers/MembersControllerTests.cs b/test/Api.IntegrationTest/AdminConsole/Public/Controllers/MembersControllerTests.cs index cd46369a3..11c60ad57 100644 --- a/test/Api.IntegrationTest/AdminConsole/Public/Controllers/MembersControllerTests.cs +++ b/test/Api.IntegrationTest/AdminConsole/Public/Controllers/MembersControllerTests.cs @@ -10,7 +10,6 @@ using Bit.Core.Billing.Enums; using Bit.Core.Enums; using Bit.Core.Models.Data; using Bit.Core.Repositories; -using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Helpers; using Xunit; @@ -109,26 +108,6 @@ public class MembersControllerTests : IClassFixture, IAsy result.Permissions); } - [Theory] - [BitAutoData(true, true)] - [BitAutoData(false, true)] - [BitAutoData(true, false)] - public async Task Get_CustomMember_WithDeprecatedPermissions_TreatsAsUser(bool editAssignedCollections, bool deleteAssignedCollections) - { - var (email, orgUser) = await OrganizationTestHelpers.CreateNewUserWithAccountAsync(_factory, _organization.Id, - OrganizationUserType.Custom, new Permissions { EditAssignedCollections = editAssignedCollections, DeleteAssignedCollections = deleteAssignedCollections }); - - var response = await _client.GetAsync($"/public/members/{orgUser.Id}"); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var result = await response.Content.ReadFromJsonAsync(); - Assert.NotNull(result); - Assert.Equal(email, result.Email); - - Assert.Equal(OrganizationUserType.User, result.Type); - Assert.Null(result.Permissions); - } - [Fact] public async Task Post_CustomMember_Success() { diff --git a/test/Api.Test/AdminConsole/Queries/OrganizationUserUserDetailsQueryTests.cs b/test/Api.Test/AdminConsole/Queries/OrganizationUserUserDetailsQueryTests.cs index f7aba6a38..bf52fab66 100644 --- a/test/Api.Test/AdminConsole/Queries/OrganizationUserUserDetailsQueryTests.cs +++ b/test/Api.Test/AdminConsole/Queries/OrganizationUserUserDetailsQueryTests.cs @@ -1,8 +1,5 @@ -using Bit.Core.Enums; -using Bit.Core.Models.Data; -using Bit.Core.Models.Data.Organizations.OrganizationUsers; +using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.Repositories; -using Bit.Core.Utilities; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Core.AdminConsole.OrganizationFeatures.OrganizationUsers; @@ -15,33 +12,6 @@ namespace Api.Test.AdminConsole.Queries; [SutProviderCustomize] public class OrganizationUserUserDetailsQueryTests { - [Theory] - [BitAutoData] - public async Task Get_DowngradesCustomUsersWithDeprecatedPermissions( - ICollection organizationUsers, - SutProvider sutProvider, - Guid organizationId) - { - Get_Setup(organizationUsers, sutProvider, organizationId); - - var customUser = organizationUsers.First(); - customUser.Type = OrganizationUserType.Custom; - customUser.Permissions = CoreHelpers.ClassToJsonData(new Permissions - { - EditAssignedCollections = true, - DeleteAssignedCollections = true, - }); - - var response = await sutProvider.Sut.GetOrganizationUserUserDetails(new OrganizationUserUserDetailsQueryRequest { OrganizationId = organizationId }); - - var customUserResponse = response.First(r => r.Id == organizationUsers.First().Id); - Assert.Equal(OrganizationUserType.User, customUserResponse.Type); - - var customUserPermissions = customUserResponse.GetPermissions(); - Assert.False(customUserPermissions.EditAssignedCollections); - Assert.False(customUserPermissions.DeleteAssignedCollections); - } - [Theory] [BitAutoData] public async Task Get_HandlesNullPermissionsObject( @@ -56,37 +26,6 @@ public class OrganizationUserUserDetailsQueryTests Assert.True(response.All(r => organizationUsers.Any(ou => ou.Id == r.Id))); } - [Theory] - [BitAutoData] - public async Task Get_SetsDeprecatedCustomPermissionstoFalse( - ICollection organizationUsers, - SutProvider sutProvider, - Guid organizationId) - { - Get_Setup(organizationUsers, sutProvider, organizationId); - - var customUser = organizationUsers.First(); - customUser.Type = OrganizationUserType.Custom; - customUser.Permissions = CoreHelpers.ClassToJsonData(new Permissions - { - AccessReports = true, - EditAssignedCollections = true, - DeleteAssignedCollections = true, - AccessEventLogs = true - }); - - var response = await sutProvider.Sut.GetOrganizationUserUserDetails(new OrganizationUserUserDetailsQueryRequest { OrganizationId = organizationId }); - - var customUserResponse = response.First(r => r.Id == organizationUsers.First().Id); - Assert.Equal(OrganizationUserType.Custom, customUserResponse.Type); - - var customUserPermissions = customUserResponse.GetPermissions(); - Assert.True(customUserPermissions.AccessReports); - Assert.True(customUserPermissions.AccessEventLogs); - Assert.False(customUserPermissions.EditAssignedCollections); - Assert.False(customUserPermissions.DeleteAssignedCollections); - } - [Theory] [BitAutoData] public async Task Get_ReturnsUsers( diff --git a/test/Core.Test/Models/PermissionsTests.cs b/test/Core.Test/Models/PermissionsTests.cs index f663cd17a..8e3a5873e 100644 --- a/test/Core.Test/Models/PermissionsTests.cs +++ b/test/Core.Test/Models/PermissionsTests.cs @@ -15,8 +15,6 @@ public class PermissionsTests "\"createNewCollections\": true,", "\"editAnyCollection\": true,", "\"deleteAnyCollection\": true,", - "\"editAssignedCollections\": false,", - "\"deleteAssignedCollections\": false,", "\"manageGroups\": false,", "\"managePolicies\": false,", "\"manageSso\": false,", @@ -36,8 +34,6 @@ public class PermissionsTests CreateNewCollections = true, EditAnyCollection = true, DeleteAnyCollection = true, - EditAssignedCollections = false, - DeleteAssignedCollections = false, ManageGroups = false, ManagePolicies = false, ManageSso = false, diff --git a/test/Infrastructure.IntegrationTest/AdminConsole/Migrations/FinalFlexibleCollectionsDataMigrationsTests.cs b/test/Infrastructure.IntegrationTest/AdminConsole/Migrations/FinalFlexibleCollectionsDataMigrationsTests.cs deleted file mode 100644 index 5e0ad98ee..000000000 --- a/test/Infrastructure.IntegrationTest/AdminConsole/Migrations/FinalFlexibleCollectionsDataMigrationsTests.cs +++ /dev/null @@ -1,335 +0,0 @@ -using System.Text.Json; -using Bit.Core.AdminConsole.Entities; -using Bit.Core.Entities; -using Bit.Core.Enums; -using Bit.Core.Models.Data; -using Bit.Core.Repositories; -using Bit.Core.Utilities; -using Bit.Infrastructure.IntegrationTest.Services; -using Newtonsoft.Json.Linq; -using Xunit; - -namespace Bit.Infrastructure.IntegrationTest.AdminConsole.Migrations; - -public class FinalFlexibleCollectionsDataMigrationsTests -{ - private const string _migrationName = "FinalFlexibleCollectionsDataMigrations"; - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_WithEditAssignedCollections_WithCustomUserType_MigratesToUserNullPermissions( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, - OrganizationUserType.Custom, editAssignedCollections: true, deleteAssignedCollections: false); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert that the user was migrated to a User type with null permissions - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(OrganizationUserType.User, migratedOrgUser.Type); - Assert.Null(migratedOrgUser.Permissions); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_WithDeleteAssignedCollections_WithCustomUserType_MigratesToUserNullPermissions( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, - OrganizationUserType.Custom, editAssignedCollections: false, deleteAssignedCollections: true); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert that the user was migrated to a User type with null permissions - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(OrganizationUserType.User, migratedOrgUser.Type); - Assert.Null(migratedOrgUser.Permissions); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_WithEditAndDeleteAssignedCollections_WithCustomUserType_MigratesToUserNullPermissions( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, - OrganizationUserType.Custom, editAssignedCollections: true, deleteAssignedCollections: true); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert that the user was migrated to a User type with null permissions - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(OrganizationUserType.User, migratedOrgUser.Type); - Assert.Null(migratedOrgUser.Permissions); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_WithoutAssignedCollectionsPermissions_WithCustomUserType_RemovesAssignedCollectionsPermissions( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, OrganizationUserType.Custom, - editAssignedCollections: false, deleteAssignedCollections: false, accessEventLogs: true); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert that the user kept the accessEventLogs permission and lost the editAssignedCollections and deleteAssignedCollections permissions - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(OrganizationUserType.Custom, migratedOrgUser.Type); - Assert.NotEqual(orgUser.Permissions, migratedOrgUser.Permissions); - Assert.NotNull(migratedOrgUser.Permissions); - Assert.Contains("accessEventLogs", orgUser.Permissions); - Assert.Contains("editAssignedCollections", orgUser.Permissions); - Assert.Contains("deleteAssignedCollections", orgUser.Permissions); - - Assert.Contains("accessEventLogs", migratedOrgUser.Permissions); - var migratedOrgUserPermissions = migratedOrgUser.GetPermissions(); - Assert.NotNull(migratedOrgUserPermissions); - Assert.True(migratedOrgUserPermissions.AccessEventLogs); - Assert.DoesNotContain("editAssignedCollections", migratedOrgUser.Permissions); - Assert.DoesNotContain("deleteAssignedCollections", migratedOrgUser.Permissions); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_WithAdminUserType_RemovesAssignedCollectionsPermissions( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, OrganizationUserType.Admin, - editAssignedCollections: false, deleteAssignedCollections: false, accessEventLogs: true); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert that the user kept the Admin type and lost the editAssignedCollections and deleteAssignedCollections - // permissions but kept the accessEventLogs permission - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(OrganizationUserType.Admin, migratedOrgUser.Type); - Assert.NotEqual(orgUser.Permissions, migratedOrgUser.Permissions); - Assert.NotNull(migratedOrgUser.Permissions); - Assert.Contains("accessEventLogs", orgUser.Permissions); - Assert.Contains("editAssignedCollections", orgUser.Permissions); - Assert.Contains("deleteAssignedCollections", orgUser.Permissions); - - Assert.Contains("accessEventLogs", migratedOrgUser.Permissions); - Assert.True(migratedOrgUser.GetPermissions().AccessEventLogs); - Assert.DoesNotContain("editAssignedCollections", migratedOrgUser.Permissions); - Assert.DoesNotContain("deleteAssignedCollections", migratedOrgUser.Permissions); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_WithoutAssignedCollectionsPermissions_DoesNothing( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, OrganizationUserType.Custom, - editAssignedCollections: false, deleteAssignedCollections: false, accessEventLogs: false); - // Remove the editAssignedCollections and deleteAssignedCollections permissions - orgUser.Permissions = JsonSerializer.Serialize(new - { - AccessEventLogs = false, - AccessImportExport = false, - AccessReports = false, - CreateNewCollections = false, - EditAnyCollection = false, - DeleteAnyCollection = false, - ManageGroups = false, - ManagePolicies = false, - ManageSso = false, - ManageUsers = false, - ManageResetPassword = false, - ManageScim = false - }, JsonHelpers.CamelCase); - await organizationUserRepository.ReplaceAsync(orgUser); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert that the user remained unchanged - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(OrganizationUserType.Custom, orgUser.Type); - Assert.Equal(OrganizationUserType.Custom, migratedOrgUser.Type); - Assert.NotNull(migratedOrgUser.Permissions); - // Assert that the permissions remain unchanged by comparing JSON data, ignoring the order of properties - Assert.True(JToken.DeepEquals(JObject.Parse(orgUser.Permissions), JObject.Parse(migratedOrgUser.Permissions))); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_HandlesNull( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, OrganizationUserType.Custom, - editAssignedCollections: false, deleteAssignedCollections: false, accessEventLogs: false); - - orgUser.Permissions = null; - await organizationUserRepository.ReplaceAsync(orgUser); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert no changes - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(orgUser.Type, migratedOrgUser.Type); - Assert.Null(migratedOrgUser.Permissions); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_HandlesNullString( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, OrganizationUserType.Custom, - editAssignedCollections: false, deleteAssignedCollections: false, accessEventLogs: false); - - // We haven't tracked down the source of this yet but it does occur in our cloud database - orgUser.Permissions = "NULL"; - await organizationUserRepository.ReplaceAsync(orgUser); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert no changes - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(orgUser.Type, migratedOrgUser.Type); - Assert.Equal("NULL", migratedOrgUser.Permissions); - } - - [DatabaseTheory, DatabaseData(MigrationName = _migrationName)] - public async Task RunMigration_HandlesNonJsonValues( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - IMigrationTesterService migrationTester) - { - // Setup data - var orgUser = await SetupData( - userRepository, organizationRepository, organizationUserRepository, OrganizationUserType.Custom, - editAssignedCollections: false, deleteAssignedCollections: false, accessEventLogs: false); - - orgUser.Permissions = "asdfasdfasfd"; - await organizationUserRepository.ReplaceAsync(orgUser); - - // Run data migration - migrationTester.ApplyMigration(); - - // Assert no changes - var migratedOrgUser = await organizationUserRepository.GetByIdAsync(orgUser.Id); - Assert.NotNull(migratedOrgUser); - Assert.Equal(orgUser.Id, migratedOrgUser.Id); - Assert.Equal(orgUser.Type, migratedOrgUser.Type); - Assert.Equal("asdfasdfasfd", migratedOrgUser.Permissions); - } - - private async Task SetupData( - IUserRepository userRepository, - IOrganizationRepository organizationRepository, - IOrganizationUserRepository organizationUserRepository, - OrganizationUserType organizationUserType, - bool editAssignedCollections, - bool deleteAssignedCollections, - bool accessEventLogs = false) - { - var permissions = new Permissions - { - AccessEventLogs = accessEventLogs, - AccessImportExport = false, - AccessReports = false, - CreateNewCollections = false, - EditAnyCollection = false, - DeleteAnyCollection = false, - EditAssignedCollections = editAssignedCollections, - DeleteAssignedCollections = deleteAssignedCollections, - ManageGroups = false, - ManagePolicies = false, - ManageSso = false, - ManageUsers = false, - ManageResetPassword = false, - ManageScim = false - }; - - var user = await userRepository.CreateAsync(new User - { - Name = "Test User 1", - Email = $"test+{Guid.NewGuid()}@example.com", - ApiKey = "TEST", - SecurityStamp = "stamp", - Kdf = KdfType.PBKDF2_SHA256, - KdfIterations = 1, - KdfMemory = 2, - KdfParallelism = 3 - }); - - var organization = await organizationRepository.CreateAsync(new Organization - { - Name = "Test Org", - BillingEmail = user.Email, // TODO: EF does not enforce this being NOT NULl - Plan = "Test", // TODO: EF does not enforce this being NOT NULl - PrivateKey = "privatekey", - }); - - var orgUser = await organizationUserRepository.CreateAsync(new OrganizationUser - { - OrganizationId = organization.Id, - UserId = user.Id, - Status = OrganizationUserStatusType.Confirmed, - ResetPasswordKey = "resetpasswordkey1", - Type = organizationUserType, - Permissions = JsonSerializer.Serialize(permissions, JsonHelpers.CamelCase) - }); - - return orgUser; - } -}