Skip to content

Commit

Permalink
[AC-1597] Revert GetByUserIdWithPolicyDetailsAsync changes to unblock…
Browse files Browse the repository at this point in the history
… SQL CPU (#3203)

* Revert "[PM-3007] Caching user policies on PolicyService variable (#3117)"

This reverts commit 78588d0.

* Don't delete old migration script

* Add migration to revert sproc

(cherry picked from commit fc814ff)
  • Loading branch information
eliykat authored and vgrassia committed Aug 16, 2023
1 parent 31c2dc0 commit 3af60f1
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/Core/Repositories/IOrganizationUserRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Guid userId, Gui
Task<IEnumerable<OrganizationUserUserDetails>> GetManyByMinimumRoleAsync(Guid organizationId, OrganizationUserType minRole);
Task RevokeAsync(Guid id);
Task RestoreAsync(Guid id, OrganizationUserStatusType status);
Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId);
Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId, PolicyType policyType);
Task<int> GetOccupiedSmSeatCountByOrganizationIdAsync(Guid organizationId);
}
17 changes: 4 additions & 13 deletions src/Core/Services/Implementations/PolicyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public class PolicyService : IPolicyService
private readonly IMailService _mailService;
private readonly GlobalSettings _globalSettings;

private IEnumerable<OrganizationUserPolicyDetails> _cachedOrganizationUserPolicyDetails;

public PolicyService(
IEventService eventService,
IOrganizationRepository organizationRepository,
Expand Down Expand Up @@ -196,25 +194,18 @@ public async Task<bool> AnyPoliciesApplicableToUserAsync(Guid userId, PolicyType
return result.Any();
}

private async Task<IEnumerable<OrganizationUserPolicyDetails>> QueryOrganizationUserPolicyDetailsAsync(Guid userId, PolicyType? policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted)
private async Task<IEnumerable<OrganizationUserPolicyDetails>> QueryOrganizationUserPolicyDetailsAsync(Guid userId, PolicyType policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted)
{
// Check if the cached policies are available
if (_cachedOrganizationUserPolicyDetails == null)
{
// Cached policies not available, retrieve from the repository
_cachedOrganizationUserPolicyDetails = await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId);
}

var organizationUserPolicyDetails = await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId, policyType);
var excludedUserTypes = GetUserTypesExcludedFromPolicy(policyType);
return _cachedOrganizationUserPolicyDetails.Where(o =>
(policyType == null || o.PolicyType == policyType) &&
return organizationUserPolicyDetails.Where(o =>
o.PolicyEnabled &&
!excludedUserTypes.Contains(o.OrganizationUserType) &&
o.OrganizationUserStatus >= minStatus &&
!o.IsProvider);
}

private OrganizationUserType[] GetUserTypesExcludedFromPolicy(PolicyType? policyType)
private OrganizationUserType[] GetUserTypesExcludedFromPolicy(PolicyType policyType)
{
switch (policyType)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,13 @@ public async Task RestoreAsync(Guid id, OrganizationUserStatusType status)
}
}

public async Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId)
public async Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId, PolicyType policyType)
{
using (var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<OrganizationUserPolicyDetails>(
$"[{Schema}].[{Table}_ReadByUserIdWithPolicyDetails]",
new { UserId = userId },
new { UserId = userId, PolicyType = policyType },
commandType: CommandType.StoredProcedure);

return results.ToList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ public async Task RestoreAsync(Guid id, OrganizationUserStatusType status)
}
}

public async Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId)
public async Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId, PolicyType policyType)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
Expand All @@ -604,7 +604,8 @@ on pu.ProviderId equals po.ProviderId
join ou in dbContext.OrganizationUsers
on p.OrganizationId equals ou.OrganizationId
let email = dbContext.Users.Find(userId).Email // Invited orgUsers do not have a UserId associated with them, so we have to match up their email
where ou.UserId == userId || ou.Email == email
where p.Type == policyType &&
(ou.UserId == userId || ou.Email == email)
select new OrganizationUserPolicyDetails
{
OrganizationUserId = ou.Id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CREATE PROCEDURE [dbo].[OrganizationUser_ReadByUserIdWithPolicyDetails]
@UserId UNIQUEIDENTIFIER
@UserId UNIQUEIDENTIFIER,
@PolicyType TINYINT
AS
BEGIN
SET NOCOUNT ON
Expand All @@ -12,19 +13,22 @@ SELECT
OU.[Type] AS OrganizationUserType,
OU.[Status] AS OrganizationUserStatus,
OU.[Permissions] AS OrganizationUserPermissionsData,
CASE WHEN PU.[ProviderId] IS NOT NULL THEN 1 ELSE 0 END AS IsProvider
CASE WHEN EXISTS (
SELECT 1
FROM [dbo].[ProviderUserView] PU
INNER JOIN [dbo].[ProviderOrganizationView] PO ON PO.[ProviderId] = PU.[ProviderId]
WHERE PU.[UserId] = OU.[UserId] AND PO.[OrganizationId] = P.[OrganizationId]
) THEN 1 ELSE 0 END AS IsProvider
FROM [dbo].[PolicyView] P
INNER JOIN [dbo].[OrganizationUserView] OU
ON P.[OrganizationId] = OU.[OrganizationId]
LEFT JOIN [dbo].[ProviderUserView] PU
ON PU.[UserId] = OU.[UserId]
LEFT JOIN [dbo].[ProviderOrganizationView] PO
ON PO.[ProviderId] = PU.[ProviderId] AND PO.[OrganizationId] = P.[OrganizationId]
WHERE
(OU.[Status] != 0 AND OU.[UserId] = @UserId) -- OrgUsers who have accepted their invite and are linked to a UserId
OR EXISTS (
SELECT 1
FROM [dbo].[UserView] U
WHERE U.[Id] = @UserId AND OU.[Email] = U.[Email] AND OU.[Status] = 0 -- 'Invited' OrgUsers are not linked to a UserId yet, so we have to look up their email
WHERE P.[Type] = @PolicyType AND
(
(OU.[Status] != 0 AND OU.[UserId] = @UserId) -- OrgUsers who have accepted their invite and are linked to a UserId
OR EXISTS (
SELECT 1
FROM [dbo].[UserView] U
WHERE U.[Id] = @UserId AND OU.[Email] = U.[Email] AND OU.[Status] = 0 -- 'Invited' OrgUsers are not linked to a UserId yet, so we have to look up their email
)
)
END
END
10 changes: 8 additions & 2 deletions test/Core.Test/Services/PolicyServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -624,12 +624,18 @@ private static void SetupOrg(SutProvider<PolicyService> sutProvider, Guid organi
private static void SetupUserPolicies(Guid userId, SutProvider<PolicyService> sutProvider)
{
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetByUserIdWithPolicyDetailsAsync(userId)
.GetByUserIdWithPolicyDetailsAsync(userId, PolicyType.RequireSso)
.Returns(new List<OrganizationUserPolicyDetails>
{
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.RequireSso, PolicyEnabled = false, OrganizationUserType = OrganizationUserType.Owner, OrganizationUserStatus = OrganizationUserStatusType.Confirmed, IsProvider = false},
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.RequireSso, PolicyEnabled = true, OrganizationUserType = OrganizationUserType.Owner, OrganizationUserStatus = OrganizationUserStatusType.Confirmed, IsProvider = false },
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.RequireSso, PolicyEnabled = true, OrganizationUserType = OrganizationUserType.Owner, OrganizationUserStatus = OrganizationUserStatusType.Confirmed, IsProvider = true },
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.RequireSso, PolicyEnabled = true, OrganizationUserType = OrganizationUserType.Owner, OrganizationUserStatus = OrganizationUserStatusType.Confirmed, IsProvider = true }
});

sutProvider.GetDependency<IOrganizationUserRepository>()
.GetByUserIdWithPolicyDetailsAsync(userId, PolicyType.DisableSend)
.Returns(new List<OrganizationUserPolicyDetails>
{
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.DisableSend, PolicyEnabled = true, OrganizationUserType = OrganizationUserType.User, OrganizationUserStatus = OrganizationUserStatusType.Invited, IsProvider = false },
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.DisableSend, PolicyEnabled = true, OrganizationUserType = OrganizationUserType.User, OrganizationUserStatus = OrganizationUserStatusType.Invited, IsProvider = true }
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ SqlRepo.ProviderUserRepository sqlProviderUserRepo
}

// Act
var result = await orgUserRepos[i].GetByUserIdWithPolicyDetailsAsync(savedUser.Id);
var result = await orgUserRepos[i].GetByUserIdWithPolicyDetailsAsync(savedUser.Id, policy.Type);
results.Add(result.FirstOrDefault());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
CREATE OR ALTER PROCEDURE [dbo].[OrganizationUser_ReadByUserIdWithPolicyDetails]
@UserId UNIQUEIDENTIFIER,
@PolicyType TINYINT
AS
BEGIN
SET NOCOUNT ON
SELECT
OU.[Id] AS OrganizationUserId,
P.[OrganizationId],
P.[Type] AS PolicyType,
P.[Enabled] AS PolicyEnabled,
P.[Data] AS PolicyData,
OU.[Type] AS OrganizationUserType,
OU.[Status] AS OrganizationUserStatus,
OU.[Permissions] AS OrganizationUserPermissionsData,
CASE WHEN EXISTS (
SELECT 1
FROM [dbo].[ProviderUserView] PU
INNER JOIN [dbo].[ProviderOrganizationView] PO ON PO.[ProviderId] = PU.[ProviderId]
WHERE PU.[UserId] = OU.[UserId] AND PO.[OrganizationId] = P.[OrganizationId]
) THEN 1 ELSE 0 END AS IsProvider
FROM [dbo].[PolicyView] P
INNER JOIN [dbo].[OrganizationUserView] OU
ON P.[OrganizationId] = OU.[OrganizationId]
WHERE P.[Type] = @PolicyType AND
(
(OU.[Status] != 0 AND OU.[UserId] = @UserId) -- OrgUsers who have accepted their invite and are linked to a UserId
OR EXISTS (
SELECT 1
FROM [dbo].[UserView] U
WHERE U.[Id] = @UserId AND OU.[Email] = U.[Email] AND OU.[Status] = 0 -- 'Invited' OrgUsers are not linked to a UserId yet, so we have to look up their email
)
)
END
GO

0 comments on commit 3af60f1

Please sign in to comment.