From 246959f4219aee1187a352a94ec40dc0f892acec Mon Sep 17 00:00:00 2001 From: Jared McCannon Date: Fri, 6 Feb 2026 15:35:06 -0600 Subject: [PATCH] Fixed bug where revoked users were being left out of policy requirement call. Moved out of loop and doing after users have been restored. This is more performant. (#6960) Fixed bug where revoked users were being left out of policy requirement call. Moved out of loop and doing after users have been restored. This is more performant. --- .../v1/RestoreOrganizationUserCommand.cs | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/RestoreUser/v1/RestoreOrganizationUserCommand.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/RestoreUser/v1/RestoreOrganizationUserCommand.cs index a764410e51..dd9c73a21d 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/RestoreUser/v1/RestoreOrganizationUserCommand.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/RestoreUser/v1/RestoreOrganizationUserCommand.cs @@ -106,8 +106,7 @@ public class RestoreOrganizationUserCommand( await organizationUserRepository.RestoreAsync(organizationUser.Id, status); if (organizationUser.UserId.HasValue - && (await policyRequirementQuery.GetAsync(organizationUser.UserId - .Value)).State == OrganizationDataOwnershipState.Enabled + && (await policyRequirementQuery.GetAsync(organizationUser.UserId.Value)).State == OrganizationDataOwnershipState.Enabled && status == OrganizationUserStatusType.Confirmed && featureService.IsEnabled(FeatureFlagKeys.DefaultUserCollectionRestore) && !string.IsNullOrWhiteSpace(defaultCollectionName)) @@ -199,9 +198,6 @@ public class RestoreOrganizationUserCommand( var orgUsersAndOrgs = await GetRelatedOrganizationUsersAndOrganizationsAsync(filteredUsers); var result = new List>(); - var organizationUsersDataOwnershipEnabled = (await policyRequirementQuery - .GetManyByOrganizationIdAsync(organizationId)) - .ToList(); foreach (var organizationUser in filteredUsers) { @@ -238,19 +234,10 @@ public class RestoreOrganizationUserCommand( var status = OrganizationService.GetPriorActiveOrganizationUserStatusType(organizationUser); await organizationUserRepository.RestoreAsync(organizationUser.Id, status); + organizationUser.Status = status; if (organizationUser.UserId.HasValue) { - if (organizationUsersDataOwnershipEnabled.Contains(organizationUser.Id) - && status == OrganizationUserStatusType.Confirmed - && !string.IsNullOrWhiteSpace(defaultCollectionName) - && featureService.IsEnabled(FeatureFlagKeys.DefaultUserCollectionRestore)) - { - await collectionRepository.CreateDefaultCollectionsAsync(organizationUser.OrganizationId, - [organizationUser.Id], - defaultCollectionName); - } - await pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value); } @@ -264,9 +251,37 @@ public class RestoreOrganizationUserCommand( } } + if (featureService.IsEnabled(FeatureFlagKeys.DefaultUserCollectionRestore)) + { + await CreateDefaultCollectionsForConfirmedUsersAsync(organizationId, defaultCollectionName, + result.Where(r => r.Item2 == "").Select(x => x.Item1).ToList()); + } + return result; } + private async Task CreateDefaultCollectionsForConfirmedUsersAsync(Guid organizationId, string defaultCollectionName, + ICollection restoredUsers) + { + if (!string.IsNullOrWhiteSpace(defaultCollectionName)) + { + var organizationUsersDataOwnershipEnabled = (await policyRequirementQuery + .GetManyByOrganizationIdAsync(organizationId)) + .ToList(); + + var usersToCreateDefaultCollectionsFor = restoredUsers.Where(x => + organizationUsersDataOwnershipEnabled.Contains(x.Id) + && x.Status == OrganizationUserStatusType.Confirmed).ToList(); + + if (usersToCreateDefaultCollectionsFor.Count != 0) + { + await collectionRepository.CreateDefaultCollectionsAsync(organizationId, + usersToCreateDefaultCollectionsFor.Select(x => x.Id), + defaultCollectionName); + } + } + } + private async Task CheckPoliciesBeforeRestoreAsync(OrganizationUser orgUser, bool userHasTwoFactorEnabled) { // An invited OrganizationUser isn't linked with a user account yet, so these checks are irrelevant