mirror of
https://github.com/bitwarden/server.git
synced 2024-11-21 12:05:42 +01:00
[PM-12684] Remove Members Bulk 2FA feature flag logic (#4864)
This commit is contained in:
parent
6c807d800e
commit
58c6f09629
@ -17,7 +17,6 @@ namespace Bit.Scim.Controllers.v2;
|
|||||||
[ExceptionHandlerFilter]
|
[ExceptionHandlerFilter]
|
||||||
public class UsersController : Controller
|
public class UsersController : Controller
|
||||||
{
|
{
|
||||||
private readonly IUserService _userService;
|
|
||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly IGetUsersListQuery _getUsersListQuery;
|
private readonly IGetUsersListQuery _getUsersListQuery;
|
||||||
@ -27,7 +26,6 @@ public class UsersController : Controller
|
|||||||
private readonly ILogger<UsersController> _logger;
|
private readonly ILogger<UsersController> _logger;
|
||||||
|
|
||||||
public UsersController(
|
public UsersController(
|
||||||
IUserService userService,
|
|
||||||
IOrganizationUserRepository organizationUserRepository,
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
IGetUsersListQuery getUsersListQuery,
|
IGetUsersListQuery getUsersListQuery,
|
||||||
@ -36,7 +34,6 @@ public class UsersController : Controller
|
|||||||
IPostUserCommand postUserCommand,
|
IPostUserCommand postUserCommand,
|
||||||
ILogger<UsersController> logger)
|
ILogger<UsersController> logger)
|
||||||
{
|
{
|
||||||
_userService = userService;
|
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
_organizationService = organizationService;
|
_organizationService = organizationService;
|
||||||
_getUsersListQuery = getUsersListQuery;
|
_getUsersListQuery = getUsersListQuery;
|
||||||
@ -98,7 +95,7 @@ public class UsersController : Controller
|
|||||||
|
|
||||||
if (model.Active && orgUser.Status == OrganizationUserStatusType.Revoked)
|
if (model.Active && orgUser.Status == OrganizationUserStatusType.Revoked)
|
||||||
{
|
{
|
||||||
await _organizationService.RestoreUserAsync(orgUser, EventSystemUser.SCIM, _userService);
|
await _organizationService.RestoreUserAsync(orgUser, EventSystemUser.SCIM);
|
||||||
}
|
}
|
||||||
else if (!model.Active && orgUser.Status != OrganizationUserStatusType.Revoked)
|
else if (!model.Active && orgUser.Status != OrganizationUserStatusType.Revoked)
|
||||||
{
|
{
|
||||||
|
@ -9,18 +9,15 @@ namespace Bit.Scim.Users;
|
|||||||
|
|
||||||
public class PatchUserCommand : IPatchUserCommand
|
public class PatchUserCommand : IPatchUserCommand
|
||||||
{
|
{
|
||||||
private readonly IUserService _userService;
|
|
||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly ILogger<PatchUserCommand> _logger;
|
private readonly ILogger<PatchUserCommand> _logger;
|
||||||
|
|
||||||
public PatchUserCommand(
|
public PatchUserCommand(
|
||||||
IUserService userService,
|
|
||||||
IOrganizationUserRepository organizationUserRepository,
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
ILogger<PatchUserCommand> logger)
|
ILogger<PatchUserCommand> logger)
|
||||||
{
|
{
|
||||||
_userService = userService;
|
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
_organizationService = organizationService;
|
_organizationService = organizationService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@ -74,7 +71,7 @@ public class PatchUserCommand : IPatchUserCommand
|
|||||||
{
|
{
|
||||||
if (active && orgUser.Status == OrganizationUserStatusType.Revoked)
|
if (active && orgUser.Status == OrganizationUserStatusType.Revoked)
|
||||||
{
|
{
|
||||||
await _organizationService.RestoreUserAsync(orgUser, EventSystemUser.SCIM, _userService);
|
await _organizationService.RestoreUserAsync(orgUser, EventSystemUser.SCIM);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (!active && orgUser.Status != OrganizationUserStatusType.Revoked)
|
else if (!active && orgUser.Status != OrganizationUserStatusType.Revoked)
|
||||||
|
@ -43,7 +43,7 @@ public class PatchUserCommandTests
|
|||||||
|
|
||||||
await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel);
|
await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel);
|
||||||
|
|
||||||
await sutProvider.GetDependency<IOrganizationService>().Received(1).RestoreUserAsync(organizationUser, EventSystemUser.SCIM, Arg.Any<IUserService>());
|
await sutProvider.GetDependency<IOrganizationService>().Received(1).RestoreUserAsync(organizationUser, EventSystemUser.SCIM);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@ -71,7 +71,7 @@ public class PatchUserCommandTests
|
|||||||
|
|
||||||
await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel);
|
await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel);
|
||||||
|
|
||||||
await sutProvider.GetDependency<IOrganizationService>().Received(1).RestoreUserAsync(organizationUser, EventSystemUser.SCIM, Arg.Any<IUserService>());
|
await sutProvider.GetDependency<IOrganizationService>().Received(1).RestoreUserAsync(organizationUser, EventSystemUser.SCIM);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@ -147,7 +147,7 @@ public class PatchUserCommandTests
|
|||||||
|
|
||||||
await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel);
|
await sutProvider.Sut.PatchUserAsync(organizationUser.OrganizationId, organizationUser.Id, scimPatchModel);
|
||||||
|
|
||||||
await sutProvider.GetDependency<IOrganizationService>().DidNotReceiveWithAnyArgs().RestoreUserAsync(default, EventSystemUser.SCIM, default);
|
await sutProvider.GetDependency<IOrganizationService>().DidNotReceiveWithAnyArgs().RestoreUserAsync(default, EventSystemUser.SCIM);
|
||||||
await sutProvider.GetDependency<IOrganizationService>().DidNotReceiveWithAnyArgs().RevokeUserAsync(default, EventSystemUser.SCIM);
|
await sutProvider.GetDependency<IOrganizationService>().DidNotReceiveWithAnyArgs().RevokeUserAsync(default, EventSystemUser.SCIM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ public class OrganizationsController : Controller
|
|||||||
await Task.WhenAll(policies.Select(async policy =>
|
await Task.WhenAll(policies.Select(async policy =>
|
||||||
{
|
{
|
||||||
policy.Enabled = false;
|
policy.Enabled = false;
|
||||||
await _policyService.SaveAsync(policy, _userService, _organizationService, null);
|
await _policyService.SaveAsync(policy, _organizationService, null);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ using Bit.Admin.Enums;
|
|||||||
using Bit.Admin.Models;
|
using Bit.Admin.Models;
|
||||||
using Bit.Admin.Services;
|
using Bit.Admin.Services;
|
||||||
using Bit.Admin.Utilities;
|
using Bit.Admin.Utilities;
|
||||||
using Bit.Core;
|
|
||||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
@ -25,8 +24,6 @@ public class UsersController : Controller
|
|||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly IAccessControlService _accessControlService;
|
private readonly IAccessControlService _accessControlService;
|
||||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
||||||
private readonly IFeatureService _featureService;
|
|
||||||
private readonly IUserService _userService;
|
|
||||||
|
|
||||||
public UsersController(
|
public UsersController(
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
@ -34,9 +31,7 @@ public class UsersController : Controller
|
|||||||
IPaymentService paymentService,
|
IPaymentService paymentService,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
IAccessControlService accessControlService,
|
IAccessControlService accessControlService,
|
||||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery)
|
||||||
IFeatureService featureService,
|
|
||||||
IUserService userService)
|
|
||||||
{
|
{
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_cipherRepository = cipherRepository;
|
_cipherRepository = cipherRepository;
|
||||||
@ -44,8 +39,6 @@ public class UsersController : Controller
|
|||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
_accessControlService = accessControlService;
|
_accessControlService = accessControlService;
|
||||||
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
||||||
_featureService = featureService;
|
|
||||||
_userService = userService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[RequirePermission(Permission.User_List_View)]
|
[RequirePermission(Permission.User_List_View)]
|
||||||
@ -64,22 +57,8 @@ public class UsersController : Controller
|
|||||||
var skip = (page - 1) * count;
|
var skip = (page - 1) * count;
|
||||||
var users = await _userRepository.SearchAsync(email, skip, count);
|
var users = await _userRepository.SearchAsync(email, skip, count);
|
||||||
|
|
||||||
var userModels = new List<UserViewModel>();
|
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization))
|
|
||||||
{
|
|
||||||
var twoFactorAuthLookup = (await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(users.Select(u => u.Id))).ToList();
|
var twoFactorAuthLookup = (await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(users.Select(u => u.Id))).ToList();
|
||||||
|
var userModels = UserViewModel.MapViewModels(users, twoFactorAuthLookup).ToList();
|
||||||
userModels = UserViewModel.MapViewModels(users, twoFactorAuthLookup).ToList();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var user in users)
|
|
||||||
{
|
|
||||||
var isTwoFactorEnabled = await _userService.TwoFactorIsEnabledAsync(user);
|
|
||||||
userModels.Add(UserViewModel.MapViewModel(user, isTwoFactorEnabled));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return View(new UsersModel
|
return View(new UsersModel
|
||||||
{
|
{
|
||||||
|
@ -48,13 +48,11 @@ public class OrganizationUsersController : Controller
|
|||||||
private readonly IAcceptOrgUserCommand _acceptOrgUserCommand;
|
private readonly IAcceptOrgUserCommand _acceptOrgUserCommand;
|
||||||
private readonly IAuthorizationService _authorizationService;
|
private readonly IAuthorizationService _authorizationService;
|
||||||
private readonly IApplicationCacheService _applicationCacheService;
|
private readonly IApplicationCacheService _applicationCacheService;
|
||||||
private readonly IFeatureService _featureService;
|
|
||||||
private readonly ISsoConfigRepository _ssoConfigRepository;
|
private readonly ISsoConfigRepository _ssoConfigRepository;
|
||||||
private readonly IOrganizationUserUserDetailsQuery _organizationUserUserDetailsQuery;
|
private readonly IOrganizationUserUserDetailsQuery _organizationUserUserDetailsQuery;
|
||||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
||||||
private readonly IDeleteManagedOrganizationUserAccountCommand _deleteManagedOrganizationUserAccountCommand;
|
private readonly IDeleteManagedOrganizationUserAccountCommand _deleteManagedOrganizationUserAccountCommand;
|
||||||
|
|
||||||
|
|
||||||
public OrganizationUsersController(
|
public OrganizationUsersController(
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
IOrganizationUserRepository organizationUserRepository,
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
@ -70,7 +68,6 @@ public class OrganizationUsersController : Controller
|
|||||||
IAcceptOrgUserCommand acceptOrgUserCommand,
|
IAcceptOrgUserCommand acceptOrgUserCommand,
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
IApplicationCacheService applicationCacheService,
|
IApplicationCacheService applicationCacheService,
|
||||||
IFeatureService featureService,
|
|
||||||
ISsoConfigRepository ssoConfigRepository,
|
ISsoConfigRepository ssoConfigRepository,
|
||||||
IOrganizationUserUserDetailsQuery organizationUserUserDetailsQuery,
|
IOrganizationUserUserDetailsQuery organizationUserUserDetailsQuery,
|
||||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
||||||
@ -90,7 +87,6 @@ public class OrganizationUsersController : Controller
|
|||||||
_acceptOrgUserCommand = acceptOrgUserCommand;
|
_acceptOrgUserCommand = acceptOrgUserCommand;
|
||||||
_authorizationService = authorizationService;
|
_authorizationService = authorizationService;
|
||||||
_applicationCacheService = applicationCacheService;
|
_applicationCacheService = applicationCacheService;
|
||||||
_featureService = featureService;
|
|
||||||
_ssoConfigRepository = ssoConfigRepository;
|
_ssoConfigRepository = ssoConfigRepository;
|
||||||
_organizationUserUserDetailsQuery = organizationUserUserDetailsQuery;
|
_organizationUserUserDetailsQuery = organizationUserUserDetailsQuery;
|
||||||
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
||||||
@ -142,11 +138,6 @@ public class OrganizationUsersController : Controller
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization))
|
|
||||||
{
|
|
||||||
return await Get_vNext(orgId, includeGroups, includeCollections);
|
|
||||||
}
|
|
||||||
|
|
||||||
var organizationUsers = await _organizationUserUserDetailsQuery.GetOrganizationUserUserDetails(
|
var organizationUsers = await _organizationUserUserDetailsQuery.GetOrganizationUserUserDetails(
|
||||||
new OrganizationUserUserDetailsQueryRequest
|
new OrganizationUserUserDetailsQueryRequest
|
||||||
{
|
{
|
||||||
@ -155,17 +146,15 @@ public class OrganizationUsersController : Controller
|
|||||||
IncludeCollections = includeCollections
|
IncludeCollections = includeCollections
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
var organizationUsersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(organizationUsers);
|
||||||
var responseTasks = organizationUsers
|
var responses = organizationUsers
|
||||||
.Select(async o =>
|
.Select(o =>
|
||||||
{
|
{
|
||||||
var orgUser = new OrganizationUserUserDetailsResponseModel(o,
|
var userTwoFactorEnabled = organizationUsersTwoFactorEnabled.FirstOrDefault(u => u.user.Id == o.Id).twoFactorIsEnabled;
|
||||||
await _userService.TwoFactorIsEnabledAsync(o));
|
var orgUser = new OrganizationUserUserDetailsResponseModel(o, userTwoFactorEnabled);
|
||||||
|
|
||||||
return orgUser;
|
return orgUser;
|
||||||
});
|
});
|
||||||
var responses = await Task.WhenAll(responseTasks);
|
|
||||||
|
|
||||||
return new ListResponseModel<OrganizationUserUserDetailsResponseModel>(responses);
|
return new ListResponseModel<OrganizationUserUserDetailsResponseModel>(responses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +285,7 @@ public class OrganizationUsersController : Controller
|
|||||||
|
|
||||||
await _organizationService.InitPendingOrganization(user.Id, orgId, organizationUserId, model.Keys.PublicKey, model.Keys.EncryptedPrivateKey, model.CollectionName);
|
await _organizationService.InitPendingOrganization(user.Id, orgId, organizationUserId, model.Keys.PublicKey, model.Keys.EncryptedPrivateKey, model.CollectionName);
|
||||||
await _acceptOrgUserCommand.AcceptOrgUserByEmailTokenAsync(organizationUserId, user, model.Token, _userService);
|
await _acceptOrgUserCommand.AcceptOrgUserByEmailTokenAsync(organizationUserId, user, model.Token, _userService);
|
||||||
await _organizationService.ConfirmUserAsync(orgId, organizationUserId, model.Key, user.Id, _userService);
|
await _organizationService.ConfirmUserAsync(orgId, organizationUserId, model.Key, user.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{organizationUserId}/accept")]
|
[HttpPost("{organizationUserId}/accept")]
|
||||||
@ -335,8 +324,7 @@ public class OrganizationUsersController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
var userId = _userService.GetProperUserId(User);
|
var userId = _userService.GetProperUserId(User);
|
||||||
var result = await _organizationService.ConfirmUserAsync(orgGuidId, new Guid(id), model.Key, userId.Value,
|
var result = await _organizationService.ConfirmUserAsync(orgGuidId, new Guid(id), model.Key, userId.Value);
|
||||||
_userService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("confirm")]
|
[HttpPost("confirm")]
|
||||||
@ -350,10 +338,7 @@ public class OrganizationUsersController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
var userId = _userService.GetProperUserId(User);
|
var userId = _userService.GetProperUserId(User);
|
||||||
var results = _featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization)
|
var results = await _organizationService.ConfirmUsersAsync(orgGuidId, model.ToDictionary(), userId.Value);
|
||||||
? await _organizationService.ConfirmUsersAsync_vNext(orgGuidId, model.ToDictionary(), userId.Value)
|
|
||||||
: await _organizationService.ConfirmUsersAsync(orgGuidId, model.ToDictionary(), userId.Value,
|
|
||||||
_userService);
|
|
||||||
|
|
||||||
return new ListResponseModel<OrganizationUserBulkResponseModel>(results.Select(r =>
|
return new ListResponseModel<OrganizationUserBulkResponseModel>(results.Select(r =>
|
||||||
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
||||||
@ -616,7 +601,7 @@ public class OrganizationUsersController : Controller
|
|||||||
[HttpPut("{id}/restore")]
|
[HttpPut("{id}/restore")]
|
||||||
public async Task RestoreAsync(Guid orgId, Guid id)
|
public async Task RestoreAsync(Guid orgId, Guid id)
|
||||||
{
|
{
|
||||||
await RestoreOrRevokeUserAsync(orgId, id, (orgUser, userId) => _organizationService.RestoreUserAsync(orgUser, userId, _userService));
|
await RestoreOrRevokeUserAsync(orgId, id, (orgUser, userId) => _organizationService.RestoreUserAsync(orgUser, userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPatch("restore")]
|
[HttpPatch("restore")]
|
||||||
@ -696,27 +681,4 @@ public class OrganizationUsersController : Controller
|
|||||||
return new ListResponseModel<OrganizationUserBulkResponseModel>(result.Select(r =>
|
return new ListResponseModel<OrganizationUserBulkResponseModel>(result.Select(r =>
|
||||||
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ListResponseModel<OrganizationUserUserDetailsResponseModel>> Get_vNext(Guid orgId,
|
|
||||||
bool includeGroups = false, bool includeCollections = false)
|
|
||||||
{
|
|
||||||
var organizationUsers = await _organizationUserUserDetailsQuery.GetOrganizationUserUserDetails(
|
|
||||||
new OrganizationUserUserDetailsQueryRequest
|
|
||||||
{
|
|
||||||
OrganizationId = orgId,
|
|
||||||
IncludeGroups = includeGroups,
|
|
||||||
IncludeCollections = includeCollections
|
|
||||||
}
|
|
||||||
);
|
|
||||||
var organizationUsersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(organizationUsers);
|
|
||||||
var responses = organizationUsers
|
|
||||||
.Select(o =>
|
|
||||||
{
|
|
||||||
var userTwoFactorEnabled = organizationUsersTwoFactorEnabled.FirstOrDefault(u => u.user.Id == o.Id).twoFactorIsEnabled;
|
|
||||||
var orgUser = new OrganizationUserUserDetailsResponseModel(o, userTwoFactorEnabled);
|
|
||||||
|
|
||||||
return orgUser;
|
|
||||||
});
|
|
||||||
return new ListResponseModel<OrganizationUserUserDetailsResponseModel>(responses);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ public class PoliciesController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
var userId = _userService.GetProperUserId(User);
|
var userId = _userService.GetProperUserId(User);
|
||||||
await _policyService.SaveAsync(policy, _userService, _organizationService, userId);
|
await _policyService.SaveAsync(policy, _organizationService, userId);
|
||||||
return new PolicyResponseModel(policy);
|
return new PolicyResponseModel(policy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,10 @@
|
|||||||
using Bit.Api.AdminConsole.Public.Models.Request;
|
using Bit.Api.AdminConsole.Public.Models.Request;
|
||||||
using Bit.Api.AdminConsole.Public.Models.Response;
|
using Bit.Api.AdminConsole.Public.Models.Response;
|
||||||
using Bit.Api.Models.Public.Response;
|
using Bit.Api.Models.Public.Response;
|
||||||
using Bit.Core;
|
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -29,7 +27,6 @@ public class MembersController : Controller
|
|||||||
private readonly IApplicationCacheService _applicationCacheService;
|
private readonly IApplicationCacheService _applicationCacheService;
|
||||||
private readonly IPaymentService _paymentService;
|
private readonly IPaymentService _paymentService;
|
||||||
private readonly IOrganizationRepository _organizationRepository;
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
private readonly IFeatureService _featureService;
|
|
||||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
||||||
|
|
||||||
public MembersController(
|
public MembersController(
|
||||||
@ -43,7 +40,6 @@ public class MembersController : Controller
|
|||||||
IApplicationCacheService applicationCacheService,
|
IApplicationCacheService applicationCacheService,
|
||||||
IPaymentService paymentService,
|
IPaymentService paymentService,
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
IFeatureService featureService,
|
|
||||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery)
|
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery)
|
||||||
{
|
{
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
@ -56,7 +52,6 @@ public class MembersController : Controller
|
|||||||
_applicationCacheService = applicationCacheService;
|
_applicationCacheService = applicationCacheService;
|
||||||
_paymentService = paymentService;
|
_paymentService = paymentService;
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
_featureService = featureService;
|
|
||||||
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,16 +115,11 @@ public class MembersController : Controller
|
|||||||
var organizationUserUserDetails = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(_currentContext.OrganizationId.Value);
|
var organizationUserUserDetails = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(_currentContext.OrganizationId.Value);
|
||||||
// TODO: Get all CollectionUser associations for the organization and marry them up here for the response.
|
// TODO: Get all CollectionUser associations for the organization and marry them up here for the response.
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization))
|
var orgUsersTwoFactorIsEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(organizationUserUserDetails);
|
||||||
|
var memberResponses = organizationUserUserDetails.Select(u =>
|
||||||
{
|
{
|
||||||
return await List_vNext(organizationUserUserDetails);
|
return new MemberResponseModel(u, orgUsersTwoFactorIsEnabled.FirstOrDefault(tuple => tuple.user == u).twoFactorIsEnabled, null);
|
||||||
}
|
|
||||||
|
|
||||||
var memberResponsesTasks = organizationUserUserDetails.Select(async u =>
|
|
||||||
{
|
|
||||||
return new MemberResponseModel(u, await _userService.TwoFactorIsEnabledAsync(u), null);
|
|
||||||
});
|
});
|
||||||
var memberResponses = await Task.WhenAll(memberResponsesTasks);
|
|
||||||
var response = new ListResponseModel<MemberResponseModel>(memberResponses);
|
var response = new ListResponseModel<MemberResponseModel>(memberResponses);
|
||||||
return new JsonResult(response);
|
return new JsonResult(response);
|
||||||
}
|
}
|
||||||
@ -268,15 +258,4 @@ public class MembersController : Controller
|
|||||||
await _organizationService.ResendInviteAsync(_currentContext.OrganizationId.Value, null, id);
|
await _organizationService.ResendInviteAsync(_currentContext.OrganizationId.Value, null, id);
|
||||||
return new OkResult();
|
return new OkResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<JsonResult> List_vNext(ICollection<OrganizationUserUserDetails> organizationUserUserDetails)
|
|
||||||
{
|
|
||||||
var orgUsersTwoFactorIsEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(organizationUserUserDetails);
|
|
||||||
var memberResponses = organizationUserUserDetails.Select(u =>
|
|
||||||
{
|
|
||||||
return new MemberResponseModel(u, orgUsersTwoFactorIsEnabled.FirstOrDefault(tuple => tuple.user == u).twoFactorIsEnabled, null);
|
|
||||||
});
|
|
||||||
var response = new ListResponseModel<MemberResponseModel>(memberResponses);
|
|
||||||
return new JsonResult(response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,20 +18,17 @@ public class PoliciesController : Controller
|
|||||||
{
|
{
|
||||||
private readonly IPolicyRepository _policyRepository;
|
private readonly IPolicyRepository _policyRepository;
|
||||||
private readonly IPolicyService _policyService;
|
private readonly IPolicyService _policyService;
|
||||||
private readonly IUserService _userService;
|
|
||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly ICurrentContext _currentContext;
|
private readonly ICurrentContext _currentContext;
|
||||||
|
|
||||||
public PoliciesController(
|
public PoliciesController(
|
||||||
IPolicyRepository policyRepository,
|
IPolicyRepository policyRepository,
|
||||||
IPolicyService policyService,
|
IPolicyService policyService,
|
||||||
IUserService userService,
|
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
ICurrentContext currentContext)
|
ICurrentContext currentContext)
|
||||||
{
|
{
|
||||||
_policyRepository = policyRepository;
|
_policyRepository = policyRepository;
|
||||||
_policyService = policyService;
|
_policyService = policyService;
|
||||||
_userService = userService;
|
|
||||||
_organizationService = organizationService;
|
_organizationService = organizationService;
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
}
|
}
|
||||||
@ -99,7 +96,7 @@ public class PoliciesController : Controller
|
|||||||
{
|
{
|
||||||
policy = model.ToPolicy(policy);
|
policy = model.ToPolicy(policy);
|
||||||
}
|
}
|
||||||
await _policyService.SaveAsync(policy, _userService, _organizationService, null);
|
await _policyService.SaveAsync(policy, _organizationService, null);
|
||||||
var response = new PolicyResponseModel(policy);
|
var response = new PolicyResponseModel(policy);
|
||||||
return new JsonResult(response);
|
return new JsonResult(response);
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,8 @@ public interface IOrganizationService
|
|||||||
IEnumerable<(OrganizationUserInvite invite, string externalId)> invites);
|
IEnumerable<(OrganizationUserInvite invite, string externalId)> invites);
|
||||||
Task<IEnumerable<Tuple<OrganizationUser, string>>> ResendInvitesAsync(Guid organizationId, Guid? invitingUserId, IEnumerable<Guid> organizationUsersId);
|
Task<IEnumerable<Tuple<OrganizationUser, string>>> ResendInvitesAsync(Guid organizationId, Guid? invitingUserId, IEnumerable<Guid> organizationUsersId);
|
||||||
Task ResendInviteAsync(Guid organizationId, Guid? invitingUserId, Guid organizationUserId, bool initOrganization = false);
|
Task ResendInviteAsync(Guid organizationId, Guid? invitingUserId, Guid organizationUserId, bool initOrganization = false);
|
||||||
Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key,
|
Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key, Guid confirmingUserId);
|
||||||
Guid confirmingUserId, IUserService userService);
|
|
||||||
Task<List<Tuple<OrganizationUser, string>>> ConfirmUsersAsync(Guid organizationId, Dictionary<Guid, string> keys,
|
Task<List<Tuple<OrganizationUser, string>>> ConfirmUsersAsync(Guid organizationId, Dictionary<Guid, string> keys,
|
||||||
Guid confirmingUserId, IUserService userService);
|
|
||||||
Task<List<Tuple<OrganizationUser, string>>> ConfirmUsersAsync_vNext(Guid organizationId, Dictionary<Guid, string> keys,
|
|
||||||
Guid confirmingUserId);
|
Guid confirmingUserId);
|
||||||
[Obsolete("IRemoveOrganizationUserCommand should be used instead. To be removed by EC-607.")]
|
[Obsolete("IRemoveOrganizationUserCommand should be used instead. To be removed by EC-607.")]
|
||||||
Task RemoveUserAsync(Guid organizationId, Guid organizationUserId, Guid? deletingUserId);
|
Task RemoveUserAsync(Guid organizationId, Guid organizationUserId, Guid? deletingUserId);
|
||||||
@ -73,8 +70,8 @@ public interface IOrganizationService
|
|||||||
Task RevokeUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser);
|
Task RevokeUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser);
|
||||||
Task<List<Tuple<OrganizationUser, string>>> RevokeUsersAsync(Guid organizationId,
|
Task<List<Tuple<OrganizationUser, string>>> RevokeUsersAsync(Guid organizationId,
|
||||||
IEnumerable<Guid> organizationUserIds, Guid? revokingUserId);
|
IEnumerable<Guid> organizationUserIds, Guid? revokingUserId);
|
||||||
Task RestoreUserAsync(OrganizationUser organizationUser, Guid? restoringUserId, IUserService userService);
|
Task RestoreUserAsync(OrganizationUser organizationUser, Guid? restoringUserId);
|
||||||
Task RestoreUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser, IUserService userService);
|
Task RestoreUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser);
|
||||||
Task<List<Tuple<OrganizationUser, string>>> RestoreUsersAsync(Guid organizationId,
|
Task<List<Tuple<OrganizationUser, string>>> RestoreUsersAsync(Guid organizationId,
|
||||||
IEnumerable<Guid> organizationUserIds, Guid? restoringUserId, IUserService userService);
|
IEnumerable<Guid> organizationUserIds, Guid? restoringUserId, IUserService userService);
|
||||||
Task CreatePendingOrganization(Organization organization, string ownerEmail, ClaimsPrincipal user, IUserService userService, bool salesAssistedTrialStarted);
|
Task CreatePendingOrganization(Organization organization, string ownerEmail, ClaimsPrincipal user, IUserService userService, bool salesAssistedTrialStarted);
|
||||||
|
@ -10,8 +10,7 @@ namespace Bit.Core.AdminConsole.Services;
|
|||||||
|
|
||||||
public interface IPolicyService
|
public interface IPolicyService
|
||||||
{
|
{
|
||||||
Task SaveAsync(Policy policy, IUserService userService, IOrganizationService organizationService,
|
Task SaveAsync(Policy policy, IOrganizationService organizationService, Guid? savingUserId);
|
||||||
Guid? savingUserId);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the combined master password policy options for the specified user.
|
/// Get the combined master password policy options for the specified user.
|
||||||
|
@ -1323,13 +1323,12 @@ public class OrganizationService : IOrganizationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key,
|
public async Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key,
|
||||||
Guid confirmingUserId, IUserService userService)
|
Guid confirmingUserId)
|
||||||
{
|
{
|
||||||
var result = _featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization)
|
var result = await ConfirmUsersAsync(
|
||||||
? await ConfirmUsersAsync_vNext(organizationId, new Dictionary<Guid, string>() { { organizationUserId, key } },
|
organizationId,
|
||||||
confirmingUserId)
|
new Dictionary<Guid, string>() { { organizationUserId, key } },
|
||||||
: await ConfirmUsersAsync(organizationId, new Dictionary<Guid, string>() { { organizationUserId, key } },
|
confirmingUserId);
|
||||||
confirmingUserId, userService);
|
|
||||||
|
|
||||||
if (!result.Any())
|
if (!result.Any())
|
||||||
{
|
{
|
||||||
@ -1345,75 +1344,6 @@ public class OrganizationService : IOrganizationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Tuple<OrganizationUser, string>>> ConfirmUsersAsync(Guid organizationId, Dictionary<Guid, string> keys,
|
public async Task<List<Tuple<OrganizationUser, string>>> ConfirmUsersAsync(Guid organizationId, Dictionary<Guid, string> keys,
|
||||||
Guid confirmingUserId, IUserService userService)
|
|
||||||
{
|
|
||||||
var organizationUsers = await _organizationUserRepository.GetManyAsync(keys.Keys);
|
|
||||||
var validOrganizationUsers = organizationUsers
|
|
||||||
.Where(u => u.Status == OrganizationUserStatusType.Accepted && u.OrganizationId == organizationId && u.UserId != null)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (!validOrganizationUsers.Any())
|
|
||||||
{
|
|
||||||
return new List<Tuple<OrganizationUser, string>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var validOrganizationUserIds = validOrganizationUsers.Select(u => u.UserId.Value).ToList();
|
|
||||||
|
|
||||||
var organization = await GetOrgById(organizationId);
|
|
||||||
var usersOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(validOrganizationUserIds);
|
|
||||||
var users = await _userRepository.GetManyAsync(validOrganizationUserIds);
|
|
||||||
|
|
||||||
var keyedFilteredUsers = validOrganizationUsers.ToDictionary(u => u.UserId.Value, u => u);
|
|
||||||
var keyedOrganizationUsers = usersOrgs.GroupBy(u => u.UserId.Value)
|
|
||||||
.ToDictionary(u => u.Key, u => u.ToList());
|
|
||||||
|
|
||||||
var succeededUsers = new List<OrganizationUser>();
|
|
||||||
var result = new List<Tuple<OrganizationUser, string>>();
|
|
||||||
|
|
||||||
foreach (var user in users)
|
|
||||||
{
|
|
||||||
if (!keyedFilteredUsers.ContainsKey(user.Id))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var orgUser = keyedFilteredUsers[user.Id];
|
|
||||||
var orgUsers = keyedOrganizationUsers.GetValueOrDefault(user.Id, new List<OrganizationUser>());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (organization.PlanType == PlanType.Free && (orgUser.Type == OrganizationUserType.Admin
|
|
||||||
|| orgUser.Type == OrganizationUserType.Owner))
|
|
||||||
{
|
|
||||||
// Since free organizations only supports a few users there is not much point in avoiding N+1 queries for this.
|
|
||||||
var adminCount = await _organizationUserRepository.GetCountByFreeOrganizationAdminUserAsync(user.Id);
|
|
||||||
if (adminCount > 0)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("User can only be an admin of one free organization.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await CheckPolicies(organizationId, user, orgUsers, userService);
|
|
||||||
orgUser.Status = OrganizationUserStatusType.Confirmed;
|
|
||||||
orgUser.Key = keys[orgUser.Id];
|
|
||||||
orgUser.Email = null;
|
|
||||||
|
|
||||||
await _eventService.LogOrganizationUserEventAsync(orgUser, EventType.OrganizationUser_Confirmed);
|
|
||||||
await _mailService.SendOrganizationConfirmedEmailAsync(organization.DisplayName(), user.Email, orgUser.AccessSecretsManager);
|
|
||||||
await DeleteAndPushUserRegistrationAsync(organizationId, user.Id);
|
|
||||||
succeededUsers.Add(orgUser);
|
|
||||||
result.Add(Tuple.Create(orgUser, ""));
|
|
||||||
}
|
|
||||||
catch (BadRequestException e)
|
|
||||||
{
|
|
||||||
result.Add(Tuple.Create(orgUser, e.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await _organizationUserRepository.ReplaceManyAsync(succeededUsers);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<Tuple<OrganizationUser, string>>> ConfirmUsersAsync_vNext(Guid organizationId, Dictionary<Guid, string> keys,
|
|
||||||
Guid confirmingUserId)
|
Guid confirmingUserId)
|
||||||
{
|
{
|
||||||
var selectedOrganizationUsers = await _organizationUserRepository.GetManyAsync(keys.Keys);
|
var selectedOrganizationUsers = await _organizationUserRepository.GetManyAsync(keys.Keys);
|
||||||
@ -1430,7 +1360,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
|
|
||||||
var organization = await GetOrgById(organizationId);
|
var organization = await GetOrgById(organizationId);
|
||||||
var allUsersOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(validSelectedUserIds);
|
var allUsersOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(validSelectedUserIds);
|
||||||
var users = await _userRepository.GetManyWithCalculatedPremiumAsync(validSelectedUserIds);
|
var users = await _userRepository.GetManyAsync(validSelectedUserIds);
|
||||||
var usersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(validSelectedUserIds);
|
var usersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(validSelectedUserIds);
|
||||||
|
|
||||||
var keyedFilteredUsers = validSelectedOrganizationUsers.ToDictionary(u => u.UserId.Value, u => u);
|
var keyedFilteredUsers = validSelectedOrganizationUsers.ToDictionary(u => u.UserId.Value, u => u);
|
||||||
@ -1462,7 +1392,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var twoFactorEnabled = usersTwoFactorEnabled.FirstOrDefault(tuple => tuple.userId == user.Id).twoFactorIsEnabled;
|
var twoFactorEnabled = usersTwoFactorEnabled.FirstOrDefault(tuple => tuple.userId == user.Id).twoFactorIsEnabled;
|
||||||
await CheckPolicies_vNext(organizationId, user, orgUsers, twoFactorEnabled);
|
await CheckPoliciesAsync(organizationId, user, orgUsers, twoFactorEnabled);
|
||||||
orgUser.Status = OrganizationUserStatusType.Confirmed;
|
orgUser.Status = OrganizationUserStatusType.Confirmed;
|
||||||
orgUser.Key = keys[orgUser.Id];
|
orgUser.Key = keys[orgUser.Id];
|
||||||
orgUser.Email = null;
|
orgUser.Email = null;
|
||||||
@ -1567,33 +1497,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckPolicies(Guid organizationId, User user,
|
private async Task CheckPoliciesAsync(Guid organizationId, User user,
|
||||||
ICollection<OrganizationUser> userOrgs, IUserService userService)
|
|
||||||
{
|
|
||||||
// Enforce Two Factor Authentication Policy for this organization
|
|
||||||
var orgRequiresTwoFactor = (await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication)).Any(p => p.OrganizationId == organizationId);
|
|
||||||
if (orgRequiresTwoFactor && !await userService.TwoFactorIsEnabledAsync(user))
|
|
||||||
{
|
|
||||||
throw new BadRequestException("User does not have two-step login enabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasOtherOrgs = userOrgs.Any(ou => ou.OrganizationId != organizationId);
|
|
||||||
var singleOrgPolicies = await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg);
|
|
||||||
var otherSingleOrgPolicies =
|
|
||||||
singleOrgPolicies.Where(p => p.OrganizationId != organizationId);
|
|
||||||
// Enforce Single Organization Policy for this organization
|
|
||||||
if (hasOtherOrgs && singleOrgPolicies.Any(p => p.OrganizationId == organizationId))
|
|
||||||
{
|
|
||||||
throw new BadRequestException("Cannot confirm this member to the organization until they leave or remove all other organizations.");
|
|
||||||
}
|
|
||||||
// Enforce Single Organization Policy of other organizations user is a member of
|
|
||||||
if (otherSingleOrgPolicies.Any())
|
|
||||||
{
|
|
||||||
throw new BadRequestException("Cannot confirm this member to the organization because they are in another organization which forbids it.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CheckPolicies_vNext(Guid organizationId, UserWithCalculatedPremium user,
|
|
||||||
ICollection<OrganizationUser> userOrgs, bool twoFactorEnabled)
|
ICollection<OrganizationUser> userOrgs, bool twoFactorEnabled)
|
||||||
{
|
{
|
||||||
// Enforce Two Factor Authentication Policy for this organization
|
// Enforce Two Factor Authentication Policy for this organization
|
||||||
@ -2438,8 +2342,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RestoreUserAsync(OrganizationUser organizationUser, Guid? restoringUserId,
|
public async Task RestoreUserAsync(OrganizationUser organizationUser, Guid? restoringUserId)
|
||||||
IUserService userService)
|
|
||||||
{
|
{
|
||||||
if (restoringUserId.HasValue && organizationUser.UserId == restoringUserId.Value)
|
if (restoringUserId.HasValue && organizationUser.UserId == restoringUserId.Value)
|
||||||
{
|
{
|
||||||
@ -2452,18 +2355,17 @@ public class OrganizationService : IOrganizationService
|
|||||||
throw new BadRequestException("Only owners can restore other owners.");
|
throw new BadRequestException("Only owners can restore other owners.");
|
||||||
}
|
}
|
||||||
|
|
||||||
await RepositoryRestoreUserAsync(organizationUser, userService);
|
await RepositoryRestoreUserAsync(organizationUser);
|
||||||
await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored);
|
await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RestoreUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser,
|
public async Task RestoreUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser)
|
||||||
IUserService userService)
|
|
||||||
{
|
{
|
||||||
await RepositoryRestoreUserAsync(organizationUser, userService);
|
await RepositoryRestoreUserAsync(organizationUser);
|
||||||
await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored, systemUser);
|
await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored, systemUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RepositoryRestoreUserAsync(OrganizationUser organizationUser, IUserService userService)
|
private async Task RepositoryRestoreUserAsync(OrganizationUser organizationUser)
|
||||||
{
|
{
|
||||||
if (organizationUser.Status != OrganizationUserStatusType.Revoked)
|
if (organizationUser.Status != OrganizationUserStatusType.Revoked)
|
||||||
{
|
{
|
||||||
@ -2478,8 +2380,6 @@ public class OrganizationService : IOrganizationService
|
|||||||
await AutoAddSeatsAsync(organization, 1);
|
await AutoAddSeatsAsync(organization, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization))
|
|
||||||
{
|
|
||||||
var userTwoFactorIsEnabled = false;
|
var userTwoFactorIsEnabled = false;
|
||||||
// Only check Two Factor Authentication status if the user is linked to a user account
|
// Only check Two Factor Authentication status if the user is linked to a user account
|
||||||
if (organizationUser.UserId.HasValue)
|
if (organizationUser.UserId.HasValue)
|
||||||
@ -2487,12 +2387,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
userTwoFactorIsEnabled = (await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(new[] { organizationUser.UserId.Value })).FirstOrDefault().twoFactorIsEnabled;
|
userTwoFactorIsEnabled = (await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(new[] { organizationUser.UserId.Value })).FirstOrDefault().twoFactorIsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
await CheckPoliciesBeforeRestoreAsync_vNext(organizationUser, userTwoFactorIsEnabled);
|
await CheckPoliciesBeforeRestoreAsync(organizationUser, userTwoFactorIsEnabled);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await CheckPoliciesBeforeRestoreAsync(organizationUser, userService);
|
|
||||||
}
|
|
||||||
|
|
||||||
var status = GetPriorActiveOrganizationUserStatusType(organizationUser);
|
var status = GetPriorActiveOrganizationUserStatusType(organizationUser);
|
||||||
|
|
||||||
@ -2526,11 +2421,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
|
|
||||||
// Query Two Factor Authentication status for all users in the organization
|
// Query Two Factor Authentication status for all users in the organization
|
||||||
// This is an optimization to avoid querying the Two Factor Authentication status for each user individually
|
// This is an optimization to avoid querying the Two Factor Authentication status for each user individually
|
||||||
IEnumerable<(Guid userId, bool twoFactorIsEnabled)> organizationUsersTwoFactorEnabled = null;
|
var organizationUsersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(filteredUsers.Select(ou => ou.UserId.Value));
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization))
|
|
||||||
{
|
|
||||||
organizationUsersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(filteredUsers.Select(ou => ou.UserId.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = new List<Tuple<OrganizationUser, string>>();
|
var result = new List<Tuple<OrganizationUser, string>>();
|
||||||
|
|
||||||
@ -2553,15 +2444,8 @@ public class OrganizationService : IOrganizationService
|
|||||||
throw new BadRequestException("Only owners can restore other owners.");
|
throw new BadRequestException("Only owners can restore other owners.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization))
|
|
||||||
{
|
|
||||||
var twoFactorIsEnabled = organizationUsersTwoFactorEnabled.FirstOrDefault(ou => ou.userId == organizationUser.UserId.Value).twoFactorIsEnabled;
|
var twoFactorIsEnabled = organizationUsersTwoFactorEnabled.FirstOrDefault(ou => ou.userId == organizationUser.UserId.Value).twoFactorIsEnabled;
|
||||||
await CheckPoliciesBeforeRestoreAsync_vNext(organizationUser, twoFactorIsEnabled);
|
await CheckPoliciesBeforeRestoreAsync(organizationUser, twoFactorIsEnabled);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await CheckPoliciesBeforeRestoreAsync(organizationUser, userService);
|
|
||||||
}
|
|
||||||
|
|
||||||
var status = GetPriorActiveOrganizationUserStatusType(organizationUser);
|
var status = GetPriorActiveOrganizationUserStatusType(organizationUser);
|
||||||
|
|
||||||
@ -2580,54 +2464,7 @@ public class OrganizationService : IOrganizationService
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckPoliciesBeforeRestoreAsync(OrganizationUser orgUser, IUserService userService)
|
private async Task CheckPoliciesBeforeRestoreAsync(OrganizationUser orgUser, bool userHasTwoFactorEnabled)
|
||||||
{
|
|
||||||
// An invited OrganizationUser isn't linked with a user account yet, so these checks are irrelevant
|
|
||||||
// The user will be subject to the same checks when they try to accept the invite
|
|
||||||
if (GetPriorActiveOrganizationUserStatusType(orgUser) == OrganizationUserStatusType.Invited)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var userId = orgUser.UserId.Value;
|
|
||||||
|
|
||||||
// Enforce Single Organization Policy of organization user is being restored to
|
|
||||||
var allOrgUsers = await _organizationUserRepository.GetManyByUserAsync(userId);
|
|
||||||
var hasOtherOrgs = allOrgUsers.Any(ou => ou.OrganizationId != orgUser.OrganizationId);
|
|
||||||
var singleOrgPoliciesApplyingToRevokedUsers = await _policyService.GetPoliciesApplicableToUserAsync(userId,
|
|
||||||
PolicyType.SingleOrg, OrganizationUserStatusType.Revoked);
|
|
||||||
var singleOrgPolicyApplies = singleOrgPoliciesApplyingToRevokedUsers.Any(p => p.OrganizationId == orgUser.OrganizationId);
|
|
||||||
|
|
||||||
if (hasOtherOrgs && singleOrgPolicyApplies)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("You cannot restore this user until " +
|
|
||||||
"they leave or remove all other organizations.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enforce Single Organization Policy of other organizations user is a member of
|
|
||||||
var anySingleOrgPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(userId,
|
|
||||||
PolicyType.SingleOrg);
|
|
||||||
if (anySingleOrgPolicies)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("You cannot restore this user because they are a member of " +
|
|
||||||
"another organization which forbids it");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enforce Two Factor Authentication Policy of organization user is trying to join
|
|
||||||
var user = await _userRepository.GetByIdAsync(userId);
|
|
||||||
if (!await userService.TwoFactorIsEnabledAsync(user))
|
|
||||||
{
|
|
||||||
var invitedTwoFactorPolicies = await _policyService.GetPoliciesApplicableToUserAsync(userId,
|
|
||||||
PolicyType.TwoFactorAuthentication, OrganizationUserStatusType.Invited);
|
|
||||||
if (invitedTwoFactorPolicies.Any(p => p.OrganizationId == orgUser.OrganizationId))
|
|
||||||
{
|
|
||||||
throw new BadRequestException("You cannot restore this user until they enable " +
|
|
||||||
"two-step login on their user account.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CheckPoliciesBeforeRestoreAsync_vNext(OrganizationUser orgUser, bool userHasTwoFactorEnabled)
|
|
||||||
{
|
{
|
||||||
// An invited OrganizationUser isn't linked with a user account yet, so these checks are irrelevant
|
// An invited OrganizationUser isn't linked with a user account yet, so these checks are irrelevant
|
||||||
// The user will be subject to the same checks when they try to accept the invite
|
// The user will be subject to the same checks when they try to accept the invite
|
||||||
|
@ -25,7 +25,6 @@ public class PolicyService : IPolicyService
|
|||||||
private readonly ISsoConfigRepository _ssoConfigRepository;
|
private readonly ISsoConfigRepository _ssoConfigRepository;
|
||||||
private readonly IMailService _mailService;
|
private readonly IMailService _mailService;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly IFeatureService _featureService;
|
|
||||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
||||||
|
|
||||||
public PolicyService(
|
public PolicyService(
|
||||||
@ -37,7 +36,6 @@ public class PolicyService : IPolicyService
|
|||||||
ISsoConfigRepository ssoConfigRepository,
|
ISsoConfigRepository ssoConfigRepository,
|
||||||
IMailService mailService,
|
IMailService mailService,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
IFeatureService featureService,
|
|
||||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery)
|
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery)
|
||||||
{
|
{
|
||||||
_applicationCacheService = applicationCacheService;
|
_applicationCacheService = applicationCacheService;
|
||||||
@ -48,12 +46,10 @@ public class PolicyService : IPolicyService
|
|||||||
_ssoConfigRepository = ssoConfigRepository;
|
_ssoConfigRepository = ssoConfigRepository;
|
||||||
_mailService = mailService;
|
_mailService = mailService;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
_featureService = featureService;
|
|
||||||
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveAsync(Policy policy, IUserService userService, IOrganizationService organizationService,
|
public async Task SaveAsync(Policy policy, IOrganizationService organizationService, Guid? savingUserId)
|
||||||
Guid? savingUserId)
|
|
||||||
{
|
{
|
||||||
var org = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
|
var org = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
|
||||||
if (org == null)
|
if (org == null)
|
||||||
@ -88,14 +84,7 @@ public class PolicyService : IPolicyService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization))
|
await EnablePolicyAsync(policy, org, organizationService, savingUserId);
|
||||||
{
|
|
||||||
await EnablePolicy_vNext(policy, org, organizationService, savingUserId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await EnablePolicy(policy, org, userService, organizationService, savingUserId);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user)
|
public async Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user)
|
||||||
@ -269,62 +258,7 @@ public class PolicyService : IPolicyService
|
|||||||
await _eventService.LogPolicyEventAsync(policy, EventType.Policy_Updated);
|
await _eventService.LogPolicyEventAsync(policy, EventType.Policy_Updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task EnablePolicy(Policy policy, Organization org, IUserService userService, IOrganizationService organizationService, Guid? savingUserId)
|
private async Task EnablePolicyAsync(Policy policy, Organization org, IOrganizationService organizationService, Guid? savingUserId)
|
||||||
{
|
|
||||||
var currentPolicy = await _policyRepository.GetByIdAsync(policy.Id);
|
|
||||||
if (!currentPolicy?.Enabled ?? true)
|
|
||||||
{
|
|
||||||
var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(policy.OrganizationId);
|
|
||||||
var removableOrgUsers = orgUsers.Where(ou =>
|
|
||||||
ou.Status != OrganizationUserStatusType.Invited && ou.Status != OrganizationUserStatusType.Revoked &&
|
|
||||||
ou.Type != OrganizationUserType.Owner && ou.Type != OrganizationUserType.Admin &&
|
|
||||||
ou.UserId != savingUserId);
|
|
||||||
switch (policy.Type)
|
|
||||||
{
|
|
||||||
case PolicyType.TwoFactorAuthentication:
|
|
||||||
// Reorder by HasMasterPassword to prioritize checking users without a master if they have 2FA enabled
|
|
||||||
foreach (var orgUser in removableOrgUsers.OrderBy(ou => ou.HasMasterPassword))
|
|
||||||
{
|
|
||||||
if (!await userService.TwoFactorIsEnabledAsync(orgUser))
|
|
||||||
{
|
|
||||||
if (!orgUser.HasMasterPassword)
|
|
||||||
{
|
|
||||||
throw new BadRequestException(
|
|
||||||
"Policy could not be enabled. Non-compliant members will lose access to their accounts. Identify members without two-step login from the policies column in the members page.");
|
|
||||||
}
|
|
||||||
|
|
||||||
await organizationService.RemoveUserAsync(policy.OrganizationId, orgUser.Id,
|
|
||||||
savingUserId);
|
|
||||||
await _mailService.SendOrganizationUserRemovedForPolicyTwoStepEmailAsync(
|
|
||||||
org.DisplayName(), orgUser.Email);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PolicyType.SingleOrg:
|
|
||||||
var userOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(
|
|
||||||
removableOrgUsers.Select(ou => ou.UserId.Value));
|
|
||||||
foreach (var orgUser in removableOrgUsers)
|
|
||||||
{
|
|
||||||
if (userOrgs.Any(ou => ou.UserId == orgUser.UserId
|
|
||||||
&& ou.OrganizationId != org.Id
|
|
||||||
&& ou.Status != OrganizationUserStatusType.Invited))
|
|
||||||
{
|
|
||||||
await organizationService.RemoveUserAsync(policy.OrganizationId, orgUser.Id,
|
|
||||||
savingUserId);
|
|
||||||
await _mailService.SendOrganizationUserRemovedForPolicySingleOrgEmailAsync(
|
|
||||||
org.DisplayName(), orgUser.Email);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await SetPolicyConfiguration(policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task EnablePolicy_vNext(Policy policy, Organization org, IOrganizationService organizationService, Guid? savingUserId)
|
|
||||||
{
|
{
|
||||||
var currentPolicy = await _policyRepository.GetByIdAsync(policy.Id);
|
var currentPolicy = await _policyRepository.GetByIdAsync(policy.Id);
|
||||||
if (!currentPolicy?.Enabled ?? true)
|
if (!currentPolicy?.Enabled ?? true)
|
||||||
|
@ -20,7 +20,6 @@ public class SsoConfigService : ISsoConfigService
|
|||||||
private readonly IPolicyService _policyService;
|
private readonly IPolicyService _policyService;
|
||||||
private readonly IOrganizationRepository _organizationRepository;
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private readonly IUserService _userService;
|
|
||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly IEventService _eventService;
|
private readonly IEventService _eventService;
|
||||||
|
|
||||||
@ -30,7 +29,6 @@ public class SsoConfigService : ISsoConfigService
|
|||||||
IPolicyService policyService,
|
IPolicyService policyService,
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
IOrganizationUserRepository organizationUserRepository,
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
IUserService userService,
|
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
IEventService eventService)
|
IEventService eventService)
|
||||||
{
|
{
|
||||||
@ -39,7 +37,6 @@ public class SsoConfigService : ISsoConfigService
|
|||||||
_policyService = policyService;
|
_policyService = policyService;
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
_userService = userService;
|
|
||||||
_organizationService = organizationService;
|
_organizationService = organizationService;
|
||||||
_eventService = eventService;
|
_eventService = eventService;
|
||||||
}
|
}
|
||||||
@ -74,20 +71,20 @@ public class SsoConfigService : ISsoConfigService
|
|||||||
|
|
||||||
singleOrgPolicy.Enabled = true;
|
singleOrgPolicy.Enabled = true;
|
||||||
|
|
||||||
await _policyService.SaveAsync(singleOrgPolicy, _userService, _organizationService, null);
|
await _policyService.SaveAsync(singleOrgPolicy, _organizationService, null);
|
||||||
|
|
||||||
var resetPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(config.OrganizationId, PolicyType.ResetPassword) ??
|
var resetPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(config.OrganizationId, PolicyType.ResetPassword) ??
|
||||||
new Policy { OrganizationId = config.OrganizationId, Type = PolicyType.ResetPassword, };
|
new Policy { OrganizationId = config.OrganizationId, Type = PolicyType.ResetPassword, };
|
||||||
|
|
||||||
resetPolicy.Enabled = true;
|
resetPolicy.Enabled = true;
|
||||||
resetPolicy.SetDataModel(new ResetPasswordDataModel { AutoEnrollEnabled = true });
|
resetPolicy.SetDataModel(new ResetPasswordDataModel { AutoEnrollEnabled = true });
|
||||||
await _policyService.SaveAsync(resetPolicy, _userService, _organizationService, null);
|
await _policyService.SaveAsync(resetPolicy, _organizationService, null);
|
||||||
|
|
||||||
var ssoRequiredPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(config.OrganizationId, PolicyType.RequireSso) ??
|
var ssoRequiredPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(config.OrganizationId, PolicyType.RequireSso) ??
|
||||||
new Policy { OrganizationId = config.OrganizationId, Type = PolicyType.RequireSso, };
|
new Policy { OrganizationId = config.OrganizationId, Type = PolicyType.RequireSso, };
|
||||||
|
|
||||||
ssoRequiredPolicy.Enabled = true;
|
ssoRequiredPolicy.Enabled = true;
|
||||||
await _policyService.SaveAsync(ssoRequiredPolicy, _userService, _organizationService, null);
|
await _policyService.SaveAsync(ssoRequiredPolicy, _organizationService, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
await LogEventsAsync(config, oldConfig);
|
await LogEventsAsync(config, oldConfig);
|
||||||
|
@ -7,7 +7,6 @@ using Bit.Core.AdminConsole.Repositories;
|
|||||||
using Bit.Core.AdminConsole.Services;
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models;
|
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Auth.Models.Data;
|
using Bit.Core.Auth.Models.Data;
|
||||||
using Bit.Core.Auth.Repositories;
|
using Bit.Core.Auth.Repositories;
|
||||||
@ -1378,12 +1377,11 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
SutProvider<OrganizationService> sutProvider)
|
SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
|
|
||||||
organizationUserRepository.GetByIdAsync(orgUser.Id).Returns(orgUser);
|
organizationUserRepository.GetByIdAsync(orgUser.Id).Returns(orgUser);
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService));
|
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id));
|
||||||
Assert.Contains("User not valid.", exception.Message);
|
Assert.Contains("User not valid.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1393,12 +1391,11 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
SutProvider<OrganizationService> sutProvider)
|
SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
|
|
||||||
organizationUserRepository.GetByIdAsync(orgUser.Id).Returns(orgUser);
|
organizationUserRepository.GetByIdAsync(orgUser.Id).Returns(orgUser);
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.ConfirmUserAsync(confirmingUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService));
|
() => sutProvider.Sut.ConfirmUserAsync(confirmingUser.OrganizationId, orgUser.Id, key, confirmingUser.Id));
|
||||||
Assert.Contains("User not valid.", exception.Message);
|
Assert.Contains("User not valid.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1411,7 +1408,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
{
|
{
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
|
|
||||||
org.PlanType = PlanType.Free;
|
org.PlanType = PlanType.Free;
|
||||||
@ -1424,7 +1420,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService));
|
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id));
|
||||||
Assert.Contains("User can only be an admin of one free organization.", exception.Message);
|
Assert.Contains("User can only be an admin of one free organization.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1465,7 +1461,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
{
|
{
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
|
|
||||||
org.PlanType = planType;
|
org.PlanType = planType;
|
||||||
@ -1478,7 +1473,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
|
|
||||||
await sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService);
|
await sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id);
|
||||||
|
|
||||||
await sutProvider.GetDependency<IEventService>().Received(1).LogOrganizationUserEventAsync(orgUser, EventType.OrganizationUser_Confirmed);
|
await sutProvider.GetDependency<IEventService>().Received(1).LogOrganizationUserEventAsync(orgUser, EventType.OrganizationUser_Confirmed);
|
||||||
await sutProvider.GetDependency<IMailService>().Received(1).SendOrganizationConfirmedEmailAsync(org.DisplayName(), user.Email);
|
await sutProvider.GetDependency<IMailService>().Received(1).SendOrganizationConfirmedEmailAsync(org.DisplayName(), user.Email);
|
||||||
@ -1496,7 +1491,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
var policyService = sutProvider.GetDependency<IPolicyService>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
org.PlanType = PlanType.EnterpriseAnnually;
|
||||||
orgUser.Status = OrganizationUserStatusType.Accepted;
|
orgUser.Status = OrganizationUserStatusType.Accepted;
|
||||||
@ -1510,7 +1504,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg).Returns(new[] { singleOrgPolicy });
|
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg).Returns(new[] { singleOrgPolicy });
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService));
|
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id));
|
||||||
Assert.Contains("Cannot confirm this member to the organization until they leave or remove all other organizations.", exception.Message);
|
Assert.Contains("Cannot confirm this member to the organization until they leave or remove all other organizations.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1524,7 +1518,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
var policyService = sutProvider.GetDependency<IPolicyService>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
org.PlanType = PlanType.EnterpriseAnnually;
|
||||||
orgUser.Status = OrganizationUserStatusType.Accepted;
|
orgUser.Status = OrganizationUserStatusType.Accepted;
|
||||||
@ -1538,7 +1531,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg).Returns(new[] { singleOrgPolicy });
|
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg).Returns(new[] { singleOrgPolicy });
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService));
|
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id));
|
||||||
Assert.Contains("Cannot confirm this member to the organization because they are in another organization which forbids it.", exception.Message);
|
Assert.Contains("Cannot confirm this member to the organization because they are in another organization which forbids it.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1554,7 +1547,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
org.PlanType = PlanType.EnterpriseAnnually;
|
||||||
orgUser.Type = userType;
|
orgUser.Type = userType;
|
||||||
@ -1567,7 +1559,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
|
|
||||||
await sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService);
|
await sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id);
|
||||||
|
|
||||||
await sutProvider.GetDependency<IEventService>().Received(1).LogOrganizationUserEventAsync(orgUser, EventType.OrganizationUser_Confirmed);
|
await sutProvider.GetDependency<IEventService>().Received(1).LogOrganizationUserEventAsync(orgUser, EventType.OrganizationUser_Confirmed);
|
||||||
await sutProvider.GetDependency<IMailService>().Received(1).SendOrganizationConfirmedEmailAsync(org.DisplayName(), user.Email, true);
|
await sutProvider.GetDependency<IMailService>().Received(1).SendOrganizationConfirmedEmailAsync(org.DisplayName(), user.Email, true);
|
||||||
@ -1585,7 +1577,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
var policyService = sutProvider.GetDependency<IPolicyService>();
|
||||||
var userService = Substitute.For<IUserService>();
|
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
org.PlanType = PlanType.EnterpriseAnnually;
|
||||||
orgUser.OrganizationId = confirmingUser.OrganizationId = org.Id;
|
orgUser.OrganizationId = confirmingUser.OrganizationId = org.Id;
|
||||||
@ -1596,9 +1588,11 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
twoFactorPolicy.OrganizationId = org.Id;
|
twoFactorPolicy.OrganizationId = org.Id;
|
||||||
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
||||||
|
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
||||||
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, false) });
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService));
|
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id));
|
||||||
Assert.Contains("User does not have two-step login enabled.", exception.Message);
|
Assert.Contains("User does not have two-step login enabled.", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1612,7 +1606,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
var policyService = sutProvider.GetDependency<IPolicyService>();
|
||||||
var userService = Substitute.For<IUserService>();
|
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
org.PlanType = PlanType.EnterpriseAnnually;
|
||||||
orgUser.OrganizationId = confirmingUser.OrganizationId = org.Id;
|
orgUser.OrganizationId = confirmingUser.OrganizationId = org.Id;
|
||||||
@ -1622,71 +1616,10 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
twoFactorPolicy.OrganizationId = org.Id;
|
twoFactorPolicy.OrganizationId = org.Id;
|
||||||
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
||||||
userService.TwoFactorIsEnabledAsync(user).Returns(true);
|
|
||||||
|
|
||||||
await sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task ConfirmUser_vNext_TwoFactorPolicy_NotEnabled_Throws(Organization org, OrganizationUser confirmingUser,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser, UserWithCalculatedPremium user,
|
|
||||||
OrganizationUser orgUserAnotherOrg,
|
|
||||||
[OrganizationUserPolicyDetails(PolicyType.TwoFactorAuthentication)] OrganizationUserPolicyDetails twoFactorPolicy,
|
|
||||||
string key, SutProvider<OrganizationService> sutProvider)
|
|
||||||
{
|
|
||||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization).Returns(true);
|
|
||||||
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
|
||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
|
||||||
orgUser.OrganizationId = confirmingUser.OrganizationId = org.Id;
|
|
||||||
orgUser.UserId = orgUserAnotherOrg.UserId = user.Id;
|
|
||||||
organizationUserRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { orgUser });
|
|
||||||
organizationUserRepository.GetManyByManyUsersAsync(default).ReturnsForAnyArgs(new[] { orgUserAnotherOrg });
|
|
||||||
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
|
||||||
userRepository.GetManyWithCalculatedPremiumAsync(default).ReturnsForAnyArgs(new[] { user });
|
|
||||||
twoFactorPolicy.OrganizationId = org.Id;
|
|
||||||
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
|
||||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
|
||||||
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, false) });
|
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
|
||||||
() => sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService));
|
|
||||||
Assert.Contains("User does not have two-step login enabled.", exception.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task ConfirmUser_vNext_TwoFactorPolicy_Enabled_Success(Organization org, OrganizationUser confirmingUser,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser, UserWithCalculatedPremium user,
|
|
||||||
[OrganizationUserPolicyDetails(PolicyType.TwoFactorAuthentication)] OrganizationUserPolicyDetails twoFactorPolicy,
|
|
||||||
string key, SutProvider<OrganizationService> sutProvider)
|
|
||||||
{
|
|
||||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization).Returns(true);
|
|
||||||
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
|
||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
|
||||||
orgUser.OrganizationId = confirmingUser.OrganizationId = org.Id;
|
|
||||||
orgUser.UserId = user.Id;
|
|
||||||
organizationUserRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { orgUser });
|
|
||||||
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
|
||||||
userRepository.GetManyWithCalculatedPremiumAsync(default).ReturnsForAnyArgs(new[] { user });
|
|
||||||
twoFactorPolicy.OrganizationId = org.Id;
|
|
||||||
policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
|
||||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
||||||
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, true) });
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, true) });
|
||||||
|
|
||||||
await sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id, userService);
|
await sutProvider.Sut.ConfirmUserAsync(orgUser.OrganizationId, orgUser.Id, key, confirmingUser.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
@ -1704,52 +1637,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
var policyService = sutProvider.GetDependency<IPolicyService>();
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
|
||||||
orgUser1.OrganizationId = orgUser2.OrganizationId = orgUser3.OrganizationId = confirmingUser.OrganizationId = org.Id;
|
|
||||||
orgUser1.UserId = user1.Id;
|
|
||||||
orgUser2.UserId = user2.Id;
|
|
||||||
orgUser3.UserId = user3.Id;
|
|
||||||
anotherOrgUser.UserId = user3.Id;
|
|
||||||
var orgUsers = new[] { orgUser1, orgUser2, orgUser3 };
|
|
||||||
organizationUserRepository.GetManyAsync(default).ReturnsForAnyArgs(orgUsers);
|
|
||||||
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
|
||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user1, user2, user3 });
|
|
||||||
twoFactorPolicy.OrganizationId = org.Id;
|
|
||||||
policyService.GetPoliciesApplicableToUserAsync(Arg.Any<Guid>(), PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
|
||||||
userService.TwoFactorIsEnabledAsync(user1).Returns(true);
|
|
||||||
userService.TwoFactorIsEnabledAsync(user2).Returns(false);
|
|
||||||
userService.TwoFactorIsEnabledAsync(user3).Returns(true);
|
|
||||||
singleOrgPolicy.OrganizationId = org.Id;
|
|
||||||
policyService.GetPoliciesApplicableToUserAsync(user3.Id, PolicyType.SingleOrg)
|
|
||||||
.Returns(new[] { singleOrgPolicy });
|
|
||||||
organizationUserRepository.GetManyByManyUsersAsync(default)
|
|
||||||
.ReturnsForAnyArgs(new[] { orgUser1, orgUser2, orgUser3, anotherOrgUser });
|
|
||||||
|
|
||||||
var keys = orgUsers.ToDictionary(ou => ou.Id, _ => key);
|
|
||||||
var result = await sutProvider.Sut.ConfirmUsersAsync(confirmingUser.OrganizationId, keys, confirmingUser.Id, userService);
|
|
||||||
Assert.Contains("", result[0].Item2);
|
|
||||||
Assert.Contains("User does not have two-step login enabled.", result[1].Item2);
|
|
||||||
Assert.Contains("Cannot confirm this member to the organization until they leave or remove all other organizations.", result[2].Item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task ConfirmUsers_vNext_Success(Organization org,
|
|
||||||
OrganizationUser confirmingUser,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser1,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser2,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser3,
|
|
||||||
OrganizationUser anotherOrgUser, UserWithCalculatedPremium user1, UserWithCalculatedPremium user2, UserWithCalculatedPremium user3,
|
|
||||||
[OrganizationUserPolicyDetails(PolicyType.TwoFactorAuthentication)] OrganizationUserPolicyDetails twoFactorPolicy,
|
|
||||||
[OrganizationUserPolicyDetails(PolicyType.SingleOrg)] OrganizationUserPolicyDetails singleOrgPolicy,
|
|
||||||
string key, SutProvider<OrganizationService> sutProvider)
|
|
||||||
{
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
|
||||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
|
||||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
|
||||||
var policyService = sutProvider.GetDependency<IPolicyService>();
|
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||||
|
|
||||||
org.PlanType = PlanType.EnterpriseAnnually;
|
org.PlanType = PlanType.EnterpriseAnnually;
|
||||||
@ -1761,7 +1648,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
var orgUsers = new[] { orgUser1, orgUser2, orgUser3 };
|
var orgUsers = new[] { orgUser1, orgUser2, orgUser3 };
|
||||||
organizationUserRepository.GetManyAsync(default).ReturnsForAnyArgs(orgUsers);
|
organizationUserRepository.GetManyAsync(default).ReturnsForAnyArgs(orgUsers);
|
||||||
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
organizationRepository.GetByIdAsync(org.Id).Returns(org);
|
||||||
userRepository.GetManyWithCalculatedPremiumAsync(default).ReturnsForAnyArgs(new[] { user1, user2, user3 });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user1, user2, user3 });
|
||||||
twoFactorPolicy.OrganizationId = org.Id;
|
twoFactorPolicy.OrganizationId = org.Id;
|
||||||
policyService.GetPoliciesApplicableToUserAsync(Arg.Any<Guid>(), PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
policyService.GetPoliciesApplicableToUserAsync(Arg.Any<Guid>(), PolicyType.TwoFactorAuthentication).Returns(new[] { twoFactorPolicy });
|
||||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user1.Id) && ids.Contains(user2.Id) && ids.Contains(user3.Id)))
|
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user1.Id) && ids.Contains(user2.Id) && ids.Contains(user3.Id)))
|
||||||
@ -1778,7 +1665,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
.ReturnsForAnyArgs(new[] { orgUser1, orgUser2, orgUser3, anotherOrgUser });
|
.ReturnsForAnyArgs(new[] { orgUser1, orgUser2, orgUser3, anotherOrgUser });
|
||||||
|
|
||||||
var keys = orgUsers.ToDictionary(ou => ou.Id, _ => key);
|
var keys = orgUsers.ToDictionary(ou => ou.Id, _ => key);
|
||||||
var result = await sutProvider.Sut.ConfirmUsersAsync_vNext(confirmingUser.OrganizationId, keys, confirmingUser.Id);
|
var result = await sutProvider.Sut.ConfirmUsersAsync(confirmingUser.OrganizationId, keys, confirmingUser.Id);
|
||||||
Assert.Contains("", result[0].Item2);
|
Assert.Contains("", result[0].Item2);
|
||||||
Assert.Contains("User does not have two-step login enabled.", result[1].Item2);
|
Assert.Contains("User does not have two-step login enabled.", result[1].Item2);
|
||||||
Assert.Contains("Cannot confirm this member to the organization until they leave or remove all other organizations.", result[2].Item2);
|
Assert.Contains("Cannot confirm this member to the organization until they leave or remove all other organizations.", result[2].Item2);
|
||||||
@ -2019,11 +1906,10 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, SutProvider<OrganizationService> sutProvider)
|
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService);
|
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id);
|
||||||
|
|
||||||
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);
|
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);
|
||||||
await eventService.Received()
|
await eventService.Received()
|
||||||
@ -2035,11 +1921,10 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider<OrganizationService> sutProvider)
|
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
await sutProvider.Sut.RestoreUserAsync(organizationUser, eventSystemUser, userService);
|
await sutProvider.Sut.RestoreUserAsync(organizationUser, eventSystemUser);
|
||||||
|
|
||||||
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);
|
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);
|
||||||
await eventService.Received()
|
await eventService.Received()
|
||||||
@ -2052,12 +1937,11 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
{
|
{
|
||||||
organizationUser.UserId = owner.Id;
|
organizationUser.UserId = owner.Id;
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id));
|
||||||
|
|
||||||
Assert.Contains("you cannot restore yourself", exception.Message.ToLowerInvariant());
|
Assert.Contains("you cannot restore yourself", exception.Message.ToLowerInvariant());
|
||||||
|
|
||||||
@ -2074,12 +1958,11 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
{
|
{
|
||||||
restoringUser.Type = restoringUserType;
|
restoringUser.Type = restoringUserType;
|
||||||
RestoreRevokeUser_Setup(organization, restoringUser, organizationUser, sutProvider, OrganizationUserType.Admin);
|
RestoreRevokeUser_Setup(organization, restoringUser, organizationUser, sutProvider, OrganizationUserType.Admin);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, restoringUser.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, restoringUser.Id));
|
||||||
|
|
||||||
Assert.Contains("only owners can restore other owners", exception.Message.ToLowerInvariant());
|
Assert.Contains("only owners can restore other owners", exception.Message.ToLowerInvariant());
|
||||||
|
|
||||||
@ -2097,12 +1980,11 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
{
|
{
|
||||||
organizationUser.Status = userStatus;
|
organizationUser.Status = userStatus;
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id));
|
||||||
|
|
||||||
Assert.Contains("already active", exception.Message.ToLowerInvariant());
|
Assert.Contains("already active", exception.Message.ToLowerInvariant());
|
||||||
|
|
||||||
@ -2111,37 +1993,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
.LogOrganizationUserEventAsync(Arg.Any<OrganizationUser>(), Arg.Any<EventType>(), Arg.Any<EventSystemUser>());
|
.LogOrganizationUserEventAsync(Arg.Any<OrganizationUser>(), Arg.Any<EventType>(), Arg.Any<EventSystemUser>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task RestoreUser_WithSingleOrgPolicyEnabled_Fails(
|
|
||||||
Organization organization,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser,
|
|
||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser secondOrganizationUser,
|
|
||||||
SutProvider<OrganizationService> sutProvider)
|
|
||||||
{
|
|
||||||
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
|
||||||
secondOrganizationUser.UserId = organizationUser.UserId;
|
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
|
||||||
|
|
||||||
organizationUserRepository.GetManyByUserAsync(organizationUser.UserId.Value).Returns(new[] { organizationUser, secondOrganizationUser });
|
|
||||||
sutProvider.GetDependency<IPolicyService>()
|
|
||||||
.GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.SingleOrg, Arg.Any<OrganizationUserStatusType>())
|
|
||||||
.Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.SingleOrg } });
|
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
|
||||||
|
|
||||||
Assert.Contains("you cannot restore this user until " +
|
|
||||||
"they leave or remove all other organizations.", exception.Message.ToLowerInvariant());
|
|
||||||
|
|
||||||
await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any<Guid>(), Arg.Any<OrganizationUserStatusType>());
|
|
||||||
await eventService.DidNotReceiveWithAnyArgs()
|
|
||||||
.LogOrganizationUserEventAsync(Arg.Any<OrganizationUser>(), Arg.Any<EventType>(), Arg.Any<EventSystemUser>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task RestoreUser_WithOtherOrganizationSingleOrgPolicyEnabled_Fails(
|
public async Task RestoreUser_WithOtherOrganizationSingleOrgPolicyEnabled_Fails(
|
||||||
Organization organization,
|
Organization organization,
|
||||||
@ -2151,7 +2002,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
{
|
{
|
||||||
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
@ -2160,7 +2010,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id));
|
||||||
|
|
||||||
Assert.Contains("you cannot restore this user because they are a member of " +
|
Assert.Contains("you cannot restore this user because they are a member of " +
|
||||||
"another organization which forbids it", exception.Message.ToLowerInvariant());
|
"another organization which forbids it", exception.Message.ToLowerInvariant());
|
||||||
@ -2182,16 +2032,16 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
.GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any<OrganizationUserStatusType>())
|
.GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any<OrganizationUserStatusType>())
|
||||||
.Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.TwoFactorAuthentication } });
|
.Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.TwoFactorAuthentication } });
|
||||||
|
|
||||||
|
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
|
||||||
|
.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(organizationUser.UserId.Value)))
|
||||||
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (organizationUser.UserId.Value, false) });
|
||||||
|
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
|
|
||||||
userService.TwoFactorIsEnabledAsync(Arg.Any<ITwoFactorProvidersUser>()).Returns(false);
|
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id));
|
||||||
|
|
||||||
Assert.Contains("you cannot restore this user until they enable " +
|
Assert.Contains("you cannot restore this user until they enable " +
|
||||||
"two-step login on their user account.", exception.Message.ToLowerInvariant());
|
"two-step login on their user account.", exception.Message.ToLowerInvariant());
|
||||||
@ -2210,16 +2060,17 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
{
|
{
|
||||||
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
sutProvider.GetDependency<IPolicyService>()
|
sutProvider.GetDependency<IPolicyService>()
|
||||||
.GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any<OrganizationUserStatusType>())
|
.GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any<OrganizationUserStatusType>())
|
||||||
.Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.TwoFactorAuthentication } });
|
.Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.TwoFactorAuthentication } });
|
||||||
userService.TwoFactorIsEnabledAsync(Arg.Any<ITwoFactorProvidersUser>()).Returns(true);
|
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
|
||||||
|
.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(organizationUser.UserId.Value)))
|
||||||
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (organizationUser.UserId.Value, true) });
|
||||||
|
|
||||||
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService);
|
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id);
|
||||||
|
|
||||||
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed);
|
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed);
|
||||||
await eventService.Received()
|
await eventService.Received()
|
||||||
@ -2227,19 +2078,16 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task RestoreUser_vNext_WithSingleOrgPolicyEnabled_Fails(
|
public async Task RestoreUser_WithSingleOrgPolicyEnabled_Fails(
|
||||||
Organization organization,
|
Organization organization,
|
||||||
[OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner,
|
[OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner,
|
||||||
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser,
|
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser,
|
||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser secondOrganizationUser,
|
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser secondOrganizationUser,
|
||||||
SutProvider<OrganizationService> sutProvider)
|
SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization).Returns(true);
|
|
||||||
|
|
||||||
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
||||||
secondOrganizationUser.UserId = organizationUser.UserId;
|
secondOrganizationUser.UserId = organizationUser.UserId;
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
@ -2252,7 +2100,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
});
|
});
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id));
|
||||||
|
|
||||||
Assert.Contains("you cannot restore this user until " +
|
Assert.Contains("you cannot restore this user until " +
|
||||||
"they leave or remove all other organizations.", exception.Message.ToLowerInvariant());
|
"they leave or remove all other organizations.", exception.Message.ToLowerInvariant());
|
||||||
@ -2270,12 +2118,9 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser secondOrganizationUser,
|
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser secondOrganizationUser,
|
||||||
SutProvider<OrganizationService> sutProvider)
|
SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization).Returns(true);
|
|
||||||
|
|
||||||
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
||||||
secondOrganizationUser.UserId = organizationUser.UserId;
|
secondOrganizationUser.UserId = organizationUser.UserId;
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||||
@ -2289,7 +2134,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
.Returns(true);
|
.Returns(true);
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id));
|
||||||
|
|
||||||
Assert.Contains("you cannot restore this user because they are a member of " +
|
Assert.Contains("you cannot restore this user because they are a member of " +
|
||||||
"another organization which forbids it", exception.Message.ToLowerInvariant());
|
"another organization which forbids it", exception.Message.ToLowerInvariant());
|
||||||
@ -2306,20 +2151,17 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser,
|
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser,
|
||||||
SutProvider<OrganizationService> sutProvider)
|
SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization).Returns(true);
|
|
||||||
|
|
||||||
organizationUser.Email = null;
|
organizationUser.Email = null;
|
||||||
sutProvider.GetDependency<IPolicyService>()
|
sutProvider.GetDependency<IPolicyService>()
|
||||||
.GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any<OrganizationUserStatusType>())
|
.GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any<OrganizationUserStatusType>())
|
||||||
.Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.TwoFactorAuthentication } });
|
.Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.TwoFactorAuthentication } });
|
||||||
|
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService));
|
() => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id));
|
||||||
|
|
||||||
Assert.Contains("you cannot restore this user until they enable " +
|
Assert.Contains("you cannot restore this user until they enable " +
|
||||||
"two-step login on their user account.", exception.Message.ToLowerInvariant());
|
"two-step login on their user account.", exception.Message.ToLowerInvariant());
|
||||||
@ -2336,11 +2178,8 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser,
|
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser,
|
||||||
SutProvider<OrganizationService> sutProvider)
|
SutProvider<OrganizationService> sutProvider)
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.MembersTwoFAQueryOptimization).Returns(true);
|
|
||||||
|
|
||||||
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke
|
||||||
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
|
||||||
var userService = Substitute.For<IUserService>();
|
|
||||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||||
var eventService = sutProvider.GetDependency<IEventService>();
|
var eventService = sutProvider.GetDependency<IEventService>();
|
||||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||||
@ -2353,7 +2192,7 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
|
|||||||
.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(organizationUser.UserId.Value)))
|
.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(organizationUser.UserId.Value)))
|
||||||
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (organizationUser.UserId.Value, true) });
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (organizationUser.UserId.Value, true) });
|
||||||
|
|
||||||
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id, userService);
|
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id);
|
||||||
|
|
||||||
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed);
|
await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed);
|
||||||
await eventService.Received()
|
await eventService.Received()
|
||||||
|
@ -7,6 +7,7 @@ using Bit.Core.Auth.Entities;
|
|||||||
using Bit.Core.Auth.Enums;
|
using Bit.Core.Auth.Enums;
|
||||||
using Bit.Core.Auth.Models.Data;
|
using Bit.Core.Auth.Models.Data;
|
||||||
using Bit.Core.Auth.Repositories;
|
using Bit.Core.Auth.Repositories;
|
||||||
|
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||||
@ -32,7 +33,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -60,7 +60,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -93,7 +92,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -125,7 +123,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -163,7 +160,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -192,7 +188,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -226,7 +221,7 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var utcNow = DateTime.UtcNow;
|
var utcNow = DateTime.UtcNow;
|
||||||
|
|
||||||
await sutProvider.Sut.SaveAsync(policy, Substitute.For<IUserService>(), Substitute.For<IOrganizationService>(), Guid.NewGuid());
|
await sutProvider.Sut.SaveAsync(policy, Substitute.For<IOrganizationService>(), Guid.NewGuid());
|
||||||
|
|
||||||
await sutProvider.GetDependency<IEventService>().Received()
|
await sutProvider.GetDependency<IEventService>().Received()
|
||||||
.LogPolicyEventAsync(policy, EventType.Policy_Updated);
|
.LogPolicyEventAsync(policy, EventType.Policy_Updated);
|
||||||
@ -256,7 +251,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -348,19 +342,23 @@ public class PolicyServiceTests
|
|||||||
orgUserDetailAdmin
|
orgUserDetailAdmin
|
||||||
});
|
});
|
||||||
|
|
||||||
var userService = Substitute.For<IUserService>();
|
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
|
||||||
var organizationService = Substitute.For<IOrganizationService>();
|
.TwoFactorIsEnabledAsync(Arg.Any<IEnumerable<OrganizationUserUserDetails>>())
|
||||||
|
.Returns(new List<(OrganizationUserUserDetails user, bool hasTwoFactor)>()
|
||||||
|
{
|
||||||
|
(orgUserDetailUserInvited, false),
|
||||||
|
(orgUserDetailUserAcceptedWith2FA, true),
|
||||||
|
(orgUserDetailUserAcceptedWithout2FA, false),
|
||||||
|
(orgUserDetailAdmin, false),
|
||||||
|
});
|
||||||
|
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetailUserInvited).Returns(false);
|
var organizationService = Substitute.For<IOrganizationService>();
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetailUserAcceptedWith2FA).Returns(true);
|
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetailUserAcceptedWithout2FA).Returns(false);
|
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetailAdmin).Returns(false);
|
|
||||||
|
|
||||||
var utcNow = DateTime.UtcNow;
|
var utcNow = DateTime.UtcNow;
|
||||||
|
|
||||||
var savingUserId = Guid.NewGuid();
|
var savingUserId = Guid.NewGuid();
|
||||||
|
|
||||||
await sutProvider.Sut.SaveAsync(policy, userService, organizationService, savingUserId);
|
await sutProvider.Sut.SaveAsync(policy, organizationService, savingUserId);
|
||||||
|
|
||||||
await organizationService.Received()
|
await organizationService.Received()
|
||||||
.RemoveUserAsync(policy.OrganizationId, orgUserDetailUserAcceptedWithout2FA.Id, savingUserId);
|
.RemoveUserAsync(policy.OrganizationId, orgUserDetailUserAcceptedWithout2FA.Id, savingUserId);
|
||||||
@ -456,17 +454,24 @@ public class PolicyServiceTests
|
|||||||
orgUserDetailAdmin
|
orgUserDetailAdmin
|
||||||
});
|
});
|
||||||
|
|
||||||
var userService = Substitute.For<IUserService>();
|
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
|
||||||
var organizationService = Substitute.For<IOrganizationService>();
|
.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids =>
|
||||||
|
ids.Contains(orgUserDetailUserWith2FANoMP.UserId.Value)
|
||||||
|
&& ids.Contains(orgUserDetailUserWithout2FA.UserId.Value)
|
||||||
|
&& ids.Contains(orgUserDetailAdmin.UserId.Value)))
|
||||||
|
.Returns(new List<(Guid userId, bool hasTwoFactor)>()
|
||||||
|
{
|
||||||
|
(orgUserDetailUserWith2FANoMP.UserId.Value, true),
|
||||||
|
(orgUserDetailUserWithout2FA.UserId.Value, false),
|
||||||
|
(orgUserDetailAdmin.UserId.Value, false),
|
||||||
|
});
|
||||||
|
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetailUserWith2FANoMP).Returns(true);
|
var organizationService = Substitute.For<IOrganizationService>();
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetailUserWithout2FA).Returns(false);
|
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetailAdmin).Returns(false);
|
|
||||||
|
|
||||||
var savingUserId = Guid.NewGuid();
|
var savingUserId = Guid.NewGuid();
|
||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy, userService, organizationService, savingUserId));
|
() => sutProvider.Sut.SaveAsync(policy, organizationService, savingUserId));
|
||||||
|
|
||||||
Assert.Contains("Policy could not be enabled. Non-compliant members will lose access to their accounts. Identify members without two-step login from the policies column in the members page.", badRequestException.Message, StringComparison.OrdinalIgnoreCase);
|
Assert.Contains("Policy could not be enabled. Non-compliant members will lose access to their accounts. Identify members without two-step login from the policies column in the members page.", badRequestException.Message, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
@ -526,17 +531,20 @@ public class PolicyServiceTests
|
|||||||
orgUserDetail,
|
orgUserDetail,
|
||||||
});
|
});
|
||||||
|
|
||||||
var userService = Substitute.For<IUserService>();
|
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
|
||||||
var organizationService = Substitute.For<IOrganizationService>();
|
.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(orgUserDetail.UserId.Value)))
|
||||||
|
.Returns(new List<(Guid userId, bool hasTwoFactor)>()
|
||||||
|
{
|
||||||
|
(orgUserDetail.UserId.Value, false),
|
||||||
|
});
|
||||||
|
|
||||||
userService.TwoFactorIsEnabledAsync(orgUserDetail)
|
var organizationService = Substitute.For<IOrganizationService>();
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
var utcNow = DateTime.UtcNow;
|
var utcNow = DateTime.UtcNow;
|
||||||
|
|
||||||
var savingUserId = Guid.NewGuid();
|
var savingUserId = Guid.NewGuid();
|
||||||
|
|
||||||
await sutProvider.Sut.SaveAsync(policy, userService, organizationService, savingUserId);
|
await sutProvider.Sut.SaveAsync(policy, organizationService, savingUserId);
|
||||||
|
|
||||||
await sutProvider.GetDependency<IEventService>().Received()
|
await sutProvider.GetDependency<IEventService>().Received()
|
||||||
.LogPolicyEventAsync(policy, EventType.Policy_Updated);
|
.LogPolicyEventAsync(policy, EventType.Policy_Updated);
|
||||||
@ -579,7 +587,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -616,7 +623,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -650,7 +656,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
@ -684,7 +689,6 @@ public class PolicyServiceTests
|
|||||||
|
|
||||||
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => sutProvider.Sut.SaveAsync(policy,
|
() => sutProvider.Sut.SaveAsync(policy,
|
||||||
Substitute.For<IUserService>(),
|
|
||||||
Substitute.For<IOrganizationService>(),
|
Substitute.For<IOrganizationService>(),
|
||||||
Guid.NewGuid()));
|
Guid.NewGuid()));
|
||||||
|
|
||||||
|
@ -342,7 +342,6 @@ public class SsoConfigServiceTests
|
|||||||
await sutProvider.GetDependency<IPolicyService>().Received(1)
|
await sutProvider.GetDependency<IPolicyService>().Received(1)
|
||||||
.SaveAsync(
|
.SaveAsync(
|
||||||
Arg.Is<Policy>(t => t.Type == PolicyType.SingleOrg),
|
Arg.Is<Policy>(t => t.Type == PolicyType.SingleOrg),
|
||||||
Arg.Any<IUserService>(),
|
|
||||||
Arg.Any<IOrganizationService>(),
|
Arg.Any<IOrganizationService>(),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
@ -350,7 +349,6 @@ public class SsoConfigServiceTests
|
|||||||
await sutProvider.GetDependency<IPolicyService>().Received(1)
|
await sutProvider.GetDependency<IPolicyService>().Received(1)
|
||||||
.SaveAsync(
|
.SaveAsync(
|
||||||
Arg.Is<Policy>(t => t.Type == PolicyType.ResetPassword && t.GetDataModel<ResetPasswordDataModel>().AutoEnrollEnabled),
|
Arg.Is<Policy>(t => t.Type == PolicyType.ResetPassword && t.GetDataModel<ResetPasswordDataModel>().AutoEnrollEnabled),
|
||||||
Arg.Any<IUserService>(),
|
|
||||||
Arg.Any<IOrganizationService>(),
|
Arg.Any<IOrganizationService>(),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user