mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 07:36:14 -05:00
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537)
* [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
This commit is contained in:
@ -5,12 +5,14 @@ using Bit.Core.Auth.Repositories;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
using GlobalSettings = Bit.Core.Settings.GlobalSettings;
|
||||
using PolicyFixtures = Bit.Core.Test.AutoFixture.PolicyFixtures;
|
||||
|
||||
namespace Bit.Core.Test.Services;
|
||||
@ -394,10 +396,132 @@ public class PolicyServiceTests
|
||||
Assert.True(policy.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetPoliciesApplicableToUserAsync_WithRequireSsoTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsNoPolicies(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.GetPoliciesApplicableToUserAsync(userId, PolicyType.RequireSso);
|
||||
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetPoliciesApplicableToUserAsync_WithRequireSsoTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsOnePolicy(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
sutProvider.GetDependency<GlobalSettings>().Sso.EnforceSsoPolicyForAllUsers.Returns(true);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.GetPoliciesApplicableToUserAsync(userId, PolicyType.RequireSso);
|
||||
|
||||
Assert.Single(result);
|
||||
Assert.True(result.All(details => details.PolicyEnabled));
|
||||
Assert.True(result.All(details => details.PolicyType == PolicyType.RequireSso));
|
||||
Assert.True(result.All(details => details.OrganizationUserType == OrganizationUserType.Owner));
|
||||
Assert.True(result.All(details => details.OrganizationUserStatus == OrganizationUserStatusType.Confirmed));
|
||||
Assert.True(result.All(details => !details.IsProvider));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetPoliciesApplicableToUserAsync_WithDisableTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsNoPolicies(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.GetPoliciesApplicableToUserAsync(userId, PolicyType.DisableSend);
|
||||
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetPoliciesApplicableToUserAsync_WithDisableSendTypeFilter_WithInvitedUserStatusFilter_ReturnsOnePolicy(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.GetPoliciesApplicableToUserAsync(userId, PolicyType.DisableSend, OrganizationUserStatusType.Invited);
|
||||
|
||||
Assert.Single(result);
|
||||
Assert.True(result.All(details => details.PolicyEnabled));
|
||||
Assert.True(result.All(details => details.PolicyType == PolicyType.DisableSend));
|
||||
Assert.True(result.All(details => details.OrganizationUserType == OrganizationUserType.User));
|
||||
Assert.True(result.All(details => details.OrganizationUserStatus == OrganizationUserStatusType.Invited));
|
||||
Assert.True(result.All(details => !details.IsProvider));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task AnyPoliciesApplicableToUserAsync_WithRequireSsoTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsFalse(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.AnyPoliciesApplicableToUserAsync(userId, PolicyType.RequireSso);
|
||||
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task AnyPoliciesApplicableToUserAsync_WithRequireSsoTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsTrue(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
sutProvider.GetDependency<GlobalSettings>().Sso.EnforceSsoPolicyForAllUsers.Returns(true);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.AnyPoliciesApplicableToUserAsync(userId, PolicyType.RequireSso);
|
||||
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task AnyPoliciesApplicableToUserAsync_WithDisableTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsFalse(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.AnyPoliciesApplicableToUserAsync(userId, PolicyType.DisableSend);
|
||||
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task AnyPoliciesApplicableToUserAsync_WithDisableSendTypeFilter_WithInvitedUserStatusFilter_ReturnsTrue(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(userId, sutProvider);
|
||||
|
||||
var result = await sutProvider.Sut
|
||||
.AnyPoliciesApplicableToUserAsync(userId, PolicyType.DisableSend, OrganizationUserStatusType.Invited);
|
||||
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
private static void SetupOrg(SutProvider<PolicyService> sutProvider, Guid organizationId, Organization organization)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
.GetByIdAsync(organizationId)
|
||||
.Returns(Task.FromResult(organization));
|
||||
}
|
||||
|
||||
private static void SetupUserPolicies(Guid userId, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.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 }
|
||||
});
|
||||
|
||||
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 }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
@ -33,8 +34,8 @@ public class SendServiceTests
|
||||
send.Id = default;
|
||||
send.Type = sendType;
|
||||
|
||||
sutProvider.GetDependency<IPolicyRepository>().GetCountByTypeApplicableToUserIdAsync(
|
||||
Arg.Any<Guid>(), PolicyType.DisableSend).Returns(disableSendPolicyAppliesToUser ? 1 : 0);
|
||||
sutProvider.GetDependency<IPolicyService>().AnyPoliciesApplicableToUserAsync(
|
||||
Arg.Any<Guid>(), PolicyType.DisableSend).Returns(disableSendPolicyAppliesToUser);
|
||||
}
|
||||
|
||||
// Disable Send policy check
|
||||
@ -79,10 +80,10 @@ public class SendServiceTests
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
});
|
||||
|
||||
sutProvider.GetDependency<IPolicyRepository>().GetManyByTypeApplicableToUserIdAsync(
|
||||
Arg.Any<Guid>(), PolicyType.SendOptions).Returns(new List<Policy>
|
||||
sutProvider.GetDependency<IPolicyService>().GetPoliciesApplicableToUserAsync(
|
||||
Arg.Any<Guid>(), PolicyType.SendOptions).Returns(new List<OrganizationUserPolicyDetails>()
|
||||
{
|
||||
policy,
|
||||
new() { PolicyType = policy.Type, PolicyData = policy.Data, OrganizationId = policy.OrganizationId, PolicyEnabled = policy.Enabled }
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
|
||||
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
|
||||
|
||||
public class OrganizationUserPolicyDetailsCompare : IEqualityComparer<OrganizationUserPolicyDetails>
|
||||
{
|
||||
public bool Equals(OrganizationUserPolicyDetails x, OrganizationUserPolicyDetails y)
|
||||
{
|
||||
if (ReferenceEquals(x, y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(x, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(y, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x.GetType() != y.GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return x.OrganizationId.Equals(y.OrganizationId) &&
|
||||
x.PolicyType == y.PolicyType &&
|
||||
x.PolicyEnabled == y.PolicyEnabled &&
|
||||
x.PolicyData == y.PolicyData &&
|
||||
x.OrganizationUserType == y.OrganizationUserType &&
|
||||
x.OrganizationUserStatus == y.OrganizationUserStatus &&
|
||||
x.OrganizationUserPermissionsData == y.OrganizationUserPermissionsData &&
|
||||
x.IsProvider == y.IsProvider;
|
||||
}
|
||||
|
||||
public int GetHashCode(OrganizationUserPolicyDetails obj)
|
||||
{
|
||||
return HashCode.Combine(obj.OrganizationId, (int)obj.PolicyType, obj.PolicyEnabled, obj.PolicyData, (int)obj.OrganizationUserType, (int)obj.OrganizationUserStatus, obj.OrganizationUserPermissionsData, obj.IsProvider);
|
||||
}
|
||||
}
|
@ -1,4 +1,10 @@
|
||||
using Bit.Core.Entities;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Entities.Provider;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Test.AutoFixture.Attributes;
|
||||
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
|
||||
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
|
||||
@ -144,4 +150,137 @@ public class OrganizationUserRepositoryTests
|
||||
savedSqlOrgUser = await sqlOrgUserRepo.GetByIdAsync(postSqlOrgUser.Id);
|
||||
Assert.True(savedSqlOrgUser == null);
|
||||
}
|
||||
|
||||
[CiSkippedTheory]
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, true, false)] // Ordinary user
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Invited, true, false)] // Invited user
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.Owner, false, OrganizationUserStatusType.Confirmed, true, false)] // Owner
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.Admin, false, OrganizationUserStatusType.Confirmed, true, false)] // Admin
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, true, OrganizationUserStatusType.Confirmed, true, false)] // canManagePolicies
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, true, true)] // Provider
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, false)] // Policy disabled
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, true, false)] // No policy of Type
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Invited, true, false)] // User not minStatus
|
||||
public async void GetByUserIdWithPolicyDetailsAsync_Works_DataMatches(
|
||||
// Inline data
|
||||
OrganizationUserType userType,
|
||||
bool canManagePolicies,
|
||||
OrganizationUserStatusType orgUserStatus,
|
||||
bool policyEnabled,
|
||||
bool isProvider,
|
||||
|
||||
// Auto data - models
|
||||
Policy policy,
|
||||
User user,
|
||||
Organization organization,
|
||||
OrganizationUser orgUser,
|
||||
Provider provider,
|
||||
ProviderOrganization providerOrganization,
|
||||
ProviderUser providerUser,
|
||||
OrganizationUserPolicyDetailsCompare equalityComparer,
|
||||
|
||||
// Auto data - EF repos
|
||||
List<EfRepo.PolicyRepository> efPolicyRepository,
|
||||
List<EfRepo.UserRepository> efUserRepository,
|
||||
List<EfRepo.OrganizationRepository> efOrganizationRepository,
|
||||
List<EfRepo.OrganizationUserRepository> suts,
|
||||
List<EfRepo.ProviderRepository> efProviderRepository,
|
||||
List<EfRepo.ProviderOrganizationRepository> efProviderOrganizationRepository,
|
||||
List<EfRepo.ProviderUserRepository> efProviderUserRepository,
|
||||
|
||||
// Auto data - SQL repos
|
||||
SqlRepo.PolicyRepository sqlPolicyRepo,
|
||||
SqlRepo.UserRepository sqlUserRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo,
|
||||
SqlRepo.ProviderRepository sqlProviderRepo,
|
||||
SqlRepo.OrganizationUserRepository sqlOrganizationUserRepo,
|
||||
SqlRepo.ProviderOrganizationRepository sqlProviderOrganizationRepo,
|
||||
SqlRepo.ProviderUserRepository sqlProviderUserRepo
|
||||
)
|
||||
{
|
||||
// Combine EF and SQL repos into one list per type
|
||||
var policyRepos = efPolicyRepository.ToList<IPolicyRepository>();
|
||||
policyRepos.Add(sqlPolicyRepo);
|
||||
var userRepos = efUserRepository.ToList<IUserRepository>();
|
||||
userRepos.Add(sqlUserRepo);
|
||||
var orgRepos = efOrganizationRepository.ToList<IOrganizationRepository>();
|
||||
orgRepos.Add(sqlOrganizationRepo);
|
||||
var orgUserRepos = suts.ToList<IOrganizationUserRepository>();
|
||||
orgUserRepos.Add(sqlOrganizationUserRepo);
|
||||
var providerRepos = efProviderRepository.ToList<IProviderRepository>();
|
||||
providerRepos.Add(sqlProviderRepo);
|
||||
var providerOrgRepos = efProviderOrganizationRepository.ToList<IProviderOrganizationRepository>();
|
||||
providerOrgRepos.Add(sqlProviderOrganizationRepo);
|
||||
var providerUserRepos = efProviderUserRepository.ToList<IProviderUserRepository>();
|
||||
providerUserRepos.Add(sqlProviderUserRepo);
|
||||
|
||||
// Arrange data
|
||||
var savedPolicyType = PolicyType.SingleOrg;
|
||||
|
||||
orgUser.Type = userType;
|
||||
orgUser.Status = orgUserStatus;
|
||||
var permissionsData = new Permissions { ManagePolicies = canManagePolicies };
|
||||
orgUser.Permissions = JsonSerializer.Serialize(permissionsData, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
});
|
||||
|
||||
policy.Enabled = policyEnabled;
|
||||
policy.Type = savedPolicyType;
|
||||
|
||||
var results = new List<OrganizationUserPolicyDetails>();
|
||||
|
||||
foreach (var policyRepo in policyRepos)
|
||||
{
|
||||
var i = policyRepos.IndexOf(policyRepo);
|
||||
|
||||
// Seed database
|
||||
user.CreationDate = user.RevisionDate = DateTime.Now;
|
||||
var savedUser = await userRepos[i].CreateAsync(user);
|
||||
var savedOrg = await orgRepos[i].CreateAsync(organization);
|
||||
|
||||
// Invited orgUsers are not associated with an account yet, so they are identified by Email not UserId
|
||||
if (orgUserStatus == OrganizationUserStatusType.Invited)
|
||||
{
|
||||
orgUser.Email = savedUser.Email;
|
||||
orgUser.UserId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
orgUser.UserId = savedUser.Id;
|
||||
}
|
||||
|
||||
orgUser.OrganizationId = savedOrg.Id;
|
||||
await orgUserRepos[i].CreateAsync(orgUser);
|
||||
|
||||
if (isProvider)
|
||||
{
|
||||
var savedProvider = await providerRepos[i].CreateAsync(provider);
|
||||
|
||||
providerOrganization.OrganizationId = savedOrg.Id;
|
||||
providerOrganization.ProviderId = savedProvider.Id;
|
||||
await providerOrgRepos[i].CreateAsync(providerOrganization);
|
||||
|
||||
providerUser.UserId = savedUser.Id;
|
||||
providerUser.ProviderId = savedProvider.Id;
|
||||
await providerUserRepos[i].CreateAsync(providerUser);
|
||||
}
|
||||
|
||||
policy.OrganizationId = savedOrg.Id;
|
||||
await policyRepo.CreateAsync(policy);
|
||||
if (efPolicyRepository.Contains(policyRepo))
|
||||
{
|
||||
(policyRepo as EfRepo.BaseEntityFrameworkRepository).ClearChangeTracking();
|
||||
}
|
||||
|
||||
// Act
|
||||
var result = await orgUserRepos[i].GetByUserIdWithPolicyDetailsAsync(savedUser.Id, policy.Type);
|
||||
results.Add(result.FirstOrDefault());
|
||||
}
|
||||
|
||||
// Assert
|
||||
var distinctItems = results.Distinct(equalityComparer);
|
||||
|
||||
Assert.Single(distinctItems);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,4 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Entities.Provider;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Test.AutoFixture.Attributes;
|
||||
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
|
||||
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
|
||||
@ -53,143 +48,4 @@ public class PolicyRepositoryTests
|
||||
var distinctItems = savedPolicys.Distinct(equalityComparer);
|
||||
Assert.True(!distinctItems.Skip(1).Any());
|
||||
}
|
||||
|
||||
[CiSkippedTheory]
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, true, true, false)] // Ordinary user
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Invited, true, true, true, false)] // Invited user
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.Owner, false, OrganizationUserStatusType.Confirmed, false, true, true, false)] // Owner
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.Admin, false, OrganizationUserStatusType.Confirmed, false, true, true, false)] // Admin
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, true, OrganizationUserStatusType.Confirmed, false, true, true, false)] // canManagePolicies
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, true, true, true)] // Provider
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, false, true, false)] // Policy disabled
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, true, false, false)] // No policy of Type
|
||||
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Invited, false, true, true, false)] // User not minStatus
|
||||
|
||||
public async void GetManyByTypeApplicableToUser_Works_DataMatches(
|
||||
// Inline data
|
||||
OrganizationUserType userType,
|
||||
bool canManagePolicies,
|
||||
OrganizationUserStatusType orgUserStatus,
|
||||
bool includeInvited,
|
||||
bool policyEnabled,
|
||||
bool policySameType,
|
||||
bool isProvider,
|
||||
|
||||
// Auto data - models
|
||||
Policy policy,
|
||||
User user,
|
||||
Organization organization,
|
||||
OrganizationUser orgUser,
|
||||
Provider provider,
|
||||
ProviderOrganization providerOrganization,
|
||||
ProviderUser providerUser,
|
||||
PolicyCompareIncludingOrganization equalityComparer,
|
||||
|
||||
// Auto data - EF repos
|
||||
List<EfRepo.PolicyRepository> suts,
|
||||
List<EfRepo.UserRepository> efUserRepository,
|
||||
List<EfRepo.OrganizationRepository> efOrganizationRepository,
|
||||
List<EfRepo.OrganizationUserRepository> efOrganizationUserRepository,
|
||||
List<EfRepo.ProviderRepository> efProviderRepository,
|
||||
List<EfRepo.ProviderOrganizationRepository> efProviderOrganizationRepository,
|
||||
List<EfRepo.ProviderUserRepository> efProviderUserRepository,
|
||||
|
||||
// Auto data - SQL repos
|
||||
SqlRepo.PolicyRepository sqlPolicyRepo,
|
||||
SqlRepo.UserRepository sqlUserRepo,
|
||||
SqlRepo.OrganizationRepository sqlOrganizationRepo,
|
||||
SqlRepo.ProviderRepository sqlProviderRepo,
|
||||
SqlRepo.OrganizationUserRepository sqlOrganizationUserRepo,
|
||||
SqlRepo.ProviderOrganizationRepository sqlProviderOrganizationRepo,
|
||||
SqlRepo.ProviderUserRepository sqlProviderUserRepo
|
||||
)
|
||||
{
|
||||
// Combine EF and SQL repos into one list per type
|
||||
var policyRepos = suts.ToList<IPolicyRepository>();
|
||||
policyRepos.Add(sqlPolicyRepo);
|
||||
var userRepos = efUserRepository.ToList<IUserRepository>();
|
||||
userRepos.Add(sqlUserRepo);
|
||||
var orgRepos = efOrganizationRepository.ToList<IOrganizationRepository>();
|
||||
orgRepos.Add(sqlOrganizationRepo);
|
||||
var orgUserRepos = efOrganizationUserRepository.ToList<IOrganizationUserRepository>();
|
||||
orgUserRepos.Add(sqlOrganizationUserRepo);
|
||||
var providerRepos = efProviderRepository.ToList<IProviderRepository>();
|
||||
providerRepos.Add(sqlProviderRepo);
|
||||
var providerOrgRepos = efProviderOrganizationRepository.ToList<IProviderOrganizationRepository>();
|
||||
providerOrgRepos.Add(sqlProviderOrganizationRepo);
|
||||
var providerUserRepos = efProviderUserRepository.ToList<IProviderUserRepository>();
|
||||
providerUserRepos.Add(sqlProviderUserRepo);
|
||||
|
||||
// Arrange data
|
||||
var savedPolicyType = PolicyType.SingleOrg;
|
||||
var queriedPolicyType = policySameType ? savedPolicyType : PolicyType.DisableSend;
|
||||
|
||||
orgUser.Type = userType;
|
||||
orgUser.Status = orgUserStatus;
|
||||
var permissionsData = new Permissions { ManagePolicies = canManagePolicies };
|
||||
orgUser.Permissions = JsonSerializer.Serialize(permissionsData, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
});
|
||||
|
||||
policy.Enabled = policyEnabled;
|
||||
policy.Type = savedPolicyType;
|
||||
|
||||
var results = new List<Policy>();
|
||||
|
||||
foreach (var policyRepo in policyRepos)
|
||||
{
|
||||
var i = policyRepos.IndexOf(policyRepo);
|
||||
|
||||
// Seed database
|
||||
var savedUser = await userRepos[i].CreateAsync(user);
|
||||
var savedOrg = await orgRepos[i].CreateAsync(organization);
|
||||
|
||||
// Invited orgUsers are not associated with an account yet, so they are identified by Email not UserId
|
||||
if (orgUserStatus == OrganizationUserStatusType.Invited)
|
||||
{
|
||||
orgUser.Email = savedUser.Email;
|
||||
orgUser.UserId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
orgUser.UserId = savedUser.Id;
|
||||
}
|
||||
|
||||
orgUser.OrganizationId = savedOrg.Id;
|
||||
await orgUserRepos[i].CreateAsync(orgUser);
|
||||
|
||||
if (isProvider)
|
||||
{
|
||||
var savedProvider = await providerRepos[i].CreateAsync(provider);
|
||||
|
||||
providerOrganization.OrganizationId = savedOrg.Id;
|
||||
providerOrganization.ProviderId = savedProvider.Id;
|
||||
await providerOrgRepos[i].CreateAsync(providerOrganization);
|
||||
|
||||
providerUser.UserId = savedUser.Id;
|
||||
providerUser.ProviderId = savedProvider.Id;
|
||||
await providerUserRepos[i].CreateAsync(providerUser);
|
||||
}
|
||||
|
||||
policy.OrganizationId = savedOrg.Id;
|
||||
await policyRepo.CreateAsync(policy);
|
||||
if (suts.Contains(policyRepo))
|
||||
{
|
||||
(policyRepo as EfRepo.BaseEntityFrameworkRepository).ClearChangeTracking();
|
||||
}
|
||||
|
||||
var minStatus = includeInvited ? OrganizationUserStatusType.Invited : OrganizationUserStatusType.Accepted;
|
||||
|
||||
// Act
|
||||
var result = await policyRepo.GetManyByTypeApplicableToUserIdAsync(savedUser.Id, queriedPolicyType, minStatus);
|
||||
results.Add(result.FirstOrDefault());
|
||||
}
|
||||
|
||||
// Assert
|
||||
var distinctItems = results.Distinct(equalityComparer);
|
||||
|
||||
Assert.True(results.All(r => r == null) ||
|
||||
!distinctItems.Skip(1).Any());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user