mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 07:36:14 -05:00
Merge branch 'main' into ac/pm-19145-refactor-OrganizationService.ImportAsync
This commit is contained in:
@ -0,0 +1,39 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using Bit.Api.IntegrationTest.Factories;
|
||||
using Bit.Seeder.Recipes;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Bit.Api.IntegrationTest.AdminConsole.Controllers;
|
||||
|
||||
public class OrganizationUsersControllerPerformanceTest(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
[Theory(Skip = "Performance test")]
|
||||
[InlineData(100)]
|
||||
[InlineData(60000)]
|
||||
public async Task GetAsync(int seats)
|
||||
{
|
||||
await using var factory = new ApiApplicationFactory();
|
||||
var client = factory.CreateClient();
|
||||
|
||||
var db = factory.GetDatabaseContext();
|
||||
var seeder = new OrganizationWithUsersRecipe(db);
|
||||
|
||||
var orgId = seeder.Seed("Org", seats, "large.test");
|
||||
|
||||
var tokens = await factory.LoginAsync("admin@large.test", "c55hlJ/cfdvTd4awTXUqow6X3cOQCfGwn11o3HblnPs=");
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokens.Token);
|
||||
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
var response = await client.GetAsync($"/organizations/{orgId}/users?includeCollections=true");
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
Assert.NotEmpty(result);
|
||||
|
||||
stopwatch.Stop();
|
||||
testOutputHelper.WriteLine($"Seed: {seats}; Request duration: {stopwatch.ElapsedMilliseconds} ms");
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Api\Api.csproj" />
|
||||
<ProjectReference Include="..\..\util\Seeder\Seeder.csproj" />
|
||||
<ProjectReference Include="..\IntegrationTestCommon\IntegrationTestCommon.csproj" />
|
||||
|
||||
<Content Include="..\..\src\Api\appsettings.*.json">
|
||||
|
@ -304,7 +304,7 @@ public class GroupsControllerPutTests
|
||||
// Arrange repositories
|
||||
sutProvider.GetDependency<IGroupRepository>().GetManyUserIdsByIdAsync(group.Id).Returns(currentGroupUsers ?? []);
|
||||
sutProvider.GetDependency<IGroupRepository>().GetByIdWithCollectionsAsync(group.Id)
|
||||
.Returns(new Tuple<Group, ICollection<CollectionAccessSelection>>(group, currentCollectionAccess ?? []));
|
||||
.Returns(new Tuple<Group?, ICollection<CollectionAccessSelection>>(group, currentCollectionAccess ?? []));
|
||||
if (savingUser != null)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>().GetByOrganizationAsync(orgId, savingUser.UserId!.Value)
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<!-- Temp exclusions until warnings are fixed -->
|
||||
<WarningsNotAsErrors>$(WarningsNotAsErrors);CS8620;CS0169</WarningsNotAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -14,6 +14,7 @@ using Bit.Core.Auth.Entities;
|
||||
using Bit.Core.Auth.Models.Api.Request.Accounts;
|
||||
using Bit.Core.Auth.Models.Data;
|
||||
using Bit.Core.Auth.UserFeatures.TdeOffboardingPassword.Interfaces;
|
||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||
using Bit.Core.Auth.UserFeatures.UserMasterPassword.Interfaces;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Exceptions;
|
||||
@ -40,6 +41,7 @@ public class AccountsControllerTests : IDisposable
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly ISetInitialMasterPasswordCommand _setInitialMasterPasswordCommand;
|
||||
private readonly IRotateUserKeyCommand _rotateUserKeyCommand;
|
||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
||||
private readonly ITdeOffboardingPasswordCommand _tdeOffboardingPasswordCommand;
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
@ -64,6 +66,7 @@ public class AccountsControllerTests : IDisposable
|
||||
_policyService = Substitute.For<IPolicyService>();
|
||||
_setInitialMasterPasswordCommand = Substitute.For<ISetInitialMasterPasswordCommand>();
|
||||
_rotateUserKeyCommand = Substitute.For<IRotateUserKeyCommand>();
|
||||
_twoFactorIsEnabledQuery = Substitute.For<ITwoFactorIsEnabledQuery>();
|
||||
_tdeOffboardingPasswordCommand = Substitute.For<ITdeOffboardingPasswordCommand>();
|
||||
_featureService = Substitute.For<IFeatureService>();
|
||||
_cipherValidator =
|
||||
@ -87,6 +90,7 @@ public class AccountsControllerTests : IDisposable
|
||||
_setInitialMasterPasswordCommand,
|
||||
_tdeOffboardingPasswordCommand,
|
||||
_rotateUserKeyCommand,
|
||||
_twoFactorIsEnabledQuery,
|
||||
_featureService,
|
||||
_cipherValidator,
|
||||
_folderValidator,
|
||||
|
@ -8,7 +8,6 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
@ -23,7 +22,6 @@ public class DevicesControllerTest
|
||||
private readonly IUntrustDevicesCommand _untrustDevicesCommand;
|
||||
private readonly IUserRepository _userRepositoryMock;
|
||||
private readonly ICurrentContext _currentContextMock;
|
||||
private readonly IGlobalSettings _globalSettingsMock;
|
||||
private readonly ILogger<DevicesController> _loggerMock;
|
||||
private readonly DevicesController _sut;
|
||||
|
||||
|
@ -216,6 +216,12 @@ public class OrganizationSponsorshipsControllerTests
|
||||
sutProvider.GetDependency<IOrganizationSponsorshipRepository>()
|
||||
.GetManyBySponsoringOrganizationAsync(sponsoringOrg.Id).Returns(sponsorships);
|
||||
|
||||
// Set IsAdminInitiated to true for all test sponsorships
|
||||
foreach (var sponsorship in sponsorships)
|
||||
{
|
||||
sponsorship.IsAdminInitiated = true;
|
||||
}
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.GetSponsoredOrganizations(sponsoringOrg.Id);
|
||||
|
||||
|
@ -1,107 +0,0 @@
|
||||
using Bit.Api.Utilities;
|
||||
using Bit.Core.Models.Commands;
|
||||
using Bit.Core.Vault.Entities;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Api.Test.Utilities;
|
||||
|
||||
public class CommandResultExtensionTests
|
||||
{
|
||||
public static IEnumerable<object[]> WithGenericTypeTestCases()
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
new NoRecordFoundFailure<Cipher>(new[] { "Error 1", "Error 2" }),
|
||||
new ObjectResult(new[] { "Error 1", "Error 2" }) { StatusCode = StatusCodes.Status404NotFound }
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new BadRequestFailure<Cipher>("Error 3"),
|
||||
new ObjectResult(new[] { "Error 3" }) { StatusCode = StatusCodes.Status400BadRequest }
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new Failure<Cipher>("Error 4"),
|
||||
new ObjectResult(new[] { "Error 4" }) { StatusCode = StatusCodes.Status400BadRequest }
|
||||
};
|
||||
var cipher = new Cipher() { Id = Guid.NewGuid() };
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
new Success<Cipher>(cipher),
|
||||
new ObjectResult(cipher) { StatusCode = StatusCodes.Status200OK }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(WithGenericTypeTestCases))]
|
||||
public void MapToActionResult_WithGenericType_ShouldMapToHttpResponse(CommandResult<Cipher> input, ObjectResult expected)
|
||||
{
|
||||
var result = input.MapToActionResult();
|
||||
|
||||
Assert.Equivalent(expected, result);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void MapToActionResult_WithGenericType_ShouldThrowExceptionForUnhandledCommandResult()
|
||||
{
|
||||
var result = new NotImplementedCommandResult();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => result.MapToActionResult());
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> TestCases()
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
new NoRecordFoundFailure(new[] { "Error 1", "Error 2" }),
|
||||
new ObjectResult(new[] { "Error 1", "Error 2" }) { StatusCode = StatusCodes.Status404NotFound }
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new BadRequestFailure("Error 3"),
|
||||
new ObjectResult(new[] { "Error 3" }) { StatusCode = StatusCodes.Status400BadRequest }
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new Failure("Error 4"),
|
||||
new ObjectResult(new[] { "Error 4" }) { StatusCode = StatusCodes.Status400BadRequest }
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new Success(),
|
||||
new ObjectResult(new { }) { StatusCode = StatusCodes.Status200OK }
|
||||
};
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TestCases))]
|
||||
public void MapToActionResult_ShouldMapToHttpResponse(CommandResult input, ObjectResult expected)
|
||||
{
|
||||
var result = input.MapToActionResult();
|
||||
|
||||
Assert.Equivalent(expected, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapToActionResult_ShouldThrowExceptionForUnhandledCommandResult()
|
||||
{
|
||||
var result = new NotImplementedCommandResult<Cipher>();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => result.MapToActionResult());
|
||||
}
|
||||
}
|
||||
|
||||
public class NotImplementedCommandResult<T> : CommandResult<T>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class NotImplementedCommandResult : CommandResult
|
||||
{
|
||||
|
||||
}
|
@ -8,6 +8,7 @@ using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.AdminConsole.Models.Data.Provider;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Auth.Models;
|
||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
@ -64,6 +65,7 @@ public class SyncControllerTests
|
||||
{
|
||||
// Get dependencies
|
||||
var userService = sutProvider.GetDependency<IUserService>();
|
||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
|
||||
var folderRepository = sutProvider.GetDependency<IFolderRepository>();
|
||||
@ -119,7 +121,7 @@ public class SyncControllerTests
|
||||
collectionRepository.GetManyByUserIdAsync(user.Id).Returns(collections);
|
||||
collectionCipherRepository.GetManyByUserIdAsync(user.Id).Returns(new List<CollectionCipher>());
|
||||
// Back to standard test setup
|
||||
userService.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
userService.HasPremiumFromOrganization(user).Returns(false);
|
||||
|
||||
// Execute GET
|
||||
@ -129,7 +131,7 @@ public class SyncControllerTests
|
||||
// Asserts
|
||||
// Assert that methods are called
|
||||
var hasEnabledOrgs = organizationUserDetails.Any(o => o.Enabled);
|
||||
await this.AssertMethodsCalledAsync(userService, organizationUserRepository, providerUserRepository, folderRepository,
|
||||
await this.AssertMethodsCalledAsync(userService, twoFactorIsEnabledQuery, organizationUserRepository, providerUserRepository, folderRepository,
|
||||
cipherRepository, sendRepository, collectionRepository, collectionCipherRepository, hasEnabledOrgs);
|
||||
|
||||
Assert.IsType<SyncResponseModel>(result);
|
||||
@ -155,6 +157,7 @@ public class SyncControllerTests
|
||||
{
|
||||
// Get dependencies
|
||||
var userService = sutProvider.GetDependency<IUserService>();
|
||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
|
||||
var folderRepository = sutProvider.GetDependency<IFolderRepository>();
|
||||
@ -205,7 +208,7 @@ public class SyncControllerTests
|
||||
|
||||
policyRepository.GetManyByUserIdAsync(user.Id).Returns(policies);
|
||||
|
||||
userService.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
userService.HasPremiumFromOrganization(user).Returns(false);
|
||||
|
||||
// Execute GET
|
||||
@ -216,7 +219,7 @@ public class SyncControllerTests
|
||||
// Assert that methods are called
|
||||
|
||||
var hasEnabledOrgs = organizationUserDetails.Any(o => o.Enabled);
|
||||
await this.AssertMethodsCalledAsync(userService, organizationUserRepository, providerUserRepository, folderRepository,
|
||||
await this.AssertMethodsCalledAsync(userService, twoFactorIsEnabledQuery, organizationUserRepository, providerUserRepository, folderRepository,
|
||||
cipherRepository, sendRepository, collectionRepository, collectionCipherRepository, hasEnabledOrgs);
|
||||
|
||||
Assert.IsType<SyncResponseModel>(result);
|
||||
@ -244,6 +247,7 @@ public class SyncControllerTests
|
||||
{
|
||||
// Get dependencies
|
||||
var userService = sutProvider.GetDependency<IUserService>();
|
||||
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
|
||||
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
|
||||
var folderRepository = sutProvider.GetDependency<IFolderRepository>();
|
||||
@ -283,7 +287,7 @@ public class SyncControllerTests
|
||||
collectionRepository.GetManyByUserIdAsync(user.Id).Returns(collections);
|
||||
collectionCipherRepository.GetManyByUserIdAsync(user.Id).Returns(new List<CollectionCipher>());
|
||||
// Back to standard test setup
|
||||
userService.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
userService.HasPremiumFromOrganization(user).Returns(false);
|
||||
|
||||
// Execute GET
|
||||
@ -293,7 +297,7 @@ public class SyncControllerTests
|
||||
// Assert that methods are called
|
||||
|
||||
var hasEnabledOrgs = organizationUserDetails.Any(o => o.Enabled);
|
||||
await this.AssertMethodsCalledAsync(userService, organizationUserRepository, providerUserRepository, folderRepository,
|
||||
await this.AssertMethodsCalledAsync(userService, twoFactorIsEnabledQuery, organizationUserRepository, providerUserRepository, folderRepository,
|
||||
cipherRepository, sendRepository, collectionRepository, collectionCipherRepository, hasEnabledOrgs);
|
||||
|
||||
Assert.IsType<SyncResponseModel>(result);
|
||||
@ -315,6 +319,7 @@ public class SyncControllerTests
|
||||
|
||||
|
||||
private async Task AssertMethodsCalledAsync(IUserService userService,
|
||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IProviderUserRepository providerUserRepository, IFolderRepository folderRepository,
|
||||
ICipherRepository cipherRepository, ISendRepository sendRepository,
|
||||
@ -356,7 +361,7 @@ public class SyncControllerTests
|
||||
.GetManyByUserIdAsync(default);
|
||||
}
|
||||
|
||||
await userService.ReceivedWithAnyArgs(1)
|
||||
await twoFactorIsEnabledQuery.ReceivedWithAnyArgs(1)
|
||||
.TwoFactorIsEnabledAsync(default(ITwoFactorProvidersUser));
|
||||
await userService.ReceivedWithAnyArgs(1)
|
||||
.HasPremiumFromOrganization(default);
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Services;
|
||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
@ -28,6 +29,7 @@ namespace Bit.Core.Test.OrganizationFeatures.OrganizationUsers;
|
||||
public class AcceptOrgUserCommandTests
|
||||
{
|
||||
private readonly IUserService _userService = Substitute.For<IUserService>();
|
||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery = Substitute.For<ITwoFactorIsEnabledQuery>();
|
||||
private readonly IOrgUserInviteTokenableFactory _orgUserInviteTokenableFactory = Substitute.For<IOrgUserInviteTokenableFactory>();
|
||||
private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory = new FakeDataProtectorTokenFactory<OrgUserInviteTokenable>();
|
||||
|
||||
@ -165,7 +167,7 @@ public class AcceptOrgUserCommandTests
|
||||
SetupCommonAcceptOrgUserMocks(sutProvider, user, org, orgUser, adminUserDetails);
|
||||
|
||||
// User doesn't have 2FA enabled
|
||||
_userService.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
_twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
|
||||
// Organization they are trying to join requires 2FA
|
||||
var twoFactorPolicy = new OrganizationUserPolicyDetails { OrganizationId = orgUser.OrganizationId };
|
||||
@ -646,7 +648,7 @@ public class AcceptOrgUserCommandTests
|
||||
.Returns(false);
|
||||
|
||||
// User doesn't have 2FA enabled
|
||||
_userService.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
_twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
|
||||
|
||||
// Org does not require 2FA
|
||||
sutProvider.GetDependency<IPolicyService>().GetPoliciesApplicableToUserAsync(user.Id,
|
||||
|
@ -2,7 +2,6 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.AdminConsole.Errors;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.Models.Data.Provider;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
||||
@ -11,12 +10,13 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.M
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
using Bit.Core.AdminConsole.Utilities.Commands;
|
||||
using Bit.Core.AdminConsole.Utilities.Errors;
|
||||
using Bit.Core.AdminConsole.Utilities.Validation;
|
||||
using Bit.Core.Billing.Models.StaticStore.Plans;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Commands;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Models.StaticStore;
|
||||
@ -79,7 +79,7 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
// Assert
|
||||
Assert.IsType<Failure<ScimInviteOrganizationUsersResponse>>(result);
|
||||
Assert.Equal(NoUsersToInviteError.Code, (result as Failure<ScimInviteOrganizationUsersResponse>).ErrorMessage);
|
||||
Assert.Equal(NoUsersToInviteError.Code, (result as Failure<ScimInviteOrganizationUsersResponse>)!.Error.Message);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
@ -208,7 +208,7 @@ public class InviteOrganizationUserCommandTests
|
||||
Assert.IsType<Failure<ScimInviteOrganizationUsersResponse>>(result);
|
||||
var failure = result as Failure<ScimInviteOrganizationUsersResponse>;
|
||||
|
||||
Assert.Equal(errorMessage, failure!.ErrorMessage);
|
||||
Assert.Equal(errorMessage, failure!.Error.Message);
|
||||
|
||||
await sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.DidNotReceive()
|
||||
@ -570,7 +570,7 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
// Assert
|
||||
Assert.IsType<Failure<ScimInviteOrganizationUsersResponse>>(result);
|
||||
Assert.Equal(FailedToInviteUsersError.Code, (result as Failure<ScimInviteOrganizationUsersResponse>)!.ErrorMessage);
|
||||
Assert.Equal(FailedToInviteUsersError.Code, (result as Failure<ScimInviteOrganizationUsersResponse>)!.Error.Message);
|
||||
|
||||
// org user revert
|
||||
await orgUserRepository.Received(1).DeleteManyAsync(Arg.Is<IEnumerable<Guid>>(x => x.Count() == 1));
|
||||
|
@ -2,7 +2,7 @@
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
using Bit.Core.AdminConsole.Utilities.Validation;
|
||||
using Bit.Core.Billing.Models.StaticStore.Plans;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
@ -155,6 +155,6 @@ public class InviteOrganizationUsersValidatorTests
|
||||
var result = await sutProvider.Sut.ValidateAsync(request);
|
||||
|
||||
Assert.IsType<Invalid<InviteOrganizationUsersValidationRequest>>(result);
|
||||
Assert.Equal("Some Secrets Manager Failure", (result as Invalid<InviteOrganizationUsersValidationRequest>)!.ErrorMessageString);
|
||||
Assert.Equal("Some Secrets Manager Failure", (result as Invalid<InviteOrganizationUsersValidationRequest>)!.Error.Message);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Organization;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
using Bit.Core.AdminConsole.Utilities.Validation;
|
||||
using Bit.Core.Billing.Models.StaticStore.Plans;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@ -36,7 +36,7 @@ public class InviteUserOrganizationValidationTests
|
||||
var result = await sutProvider.Sut.ValidateAsync(inviteOrganization);
|
||||
|
||||
Assert.IsType<Invalid<InviteOrganization>>(result);
|
||||
Assert.Equal(OrganizationNoPaymentMethodFoundError.Code, (result as Invalid<InviteOrganization>)!.ErrorMessageString);
|
||||
Assert.Equal(OrganizationNoPaymentMethodFoundError.Code, (result as Invalid<InviteOrganization>)!.Error.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -53,6 +53,6 @@ public class InviteUserOrganizationValidationTests
|
||||
var result = await sutProvider.Sut.ValidateAsync(inviteOrganization);
|
||||
|
||||
Assert.IsType<Invalid<InviteOrganization>>(result);
|
||||
Assert.Equal(OrganizationNoSubscriptionFoundError.Code, (result as Invalid<InviteOrganization>)!.ErrorMessageString);
|
||||
Assert.Equal(OrganizationNoSubscriptionFoundError.Code, (result as Invalid<InviteOrganization>)!.Error.Message);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Payments;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
using Bit.Core.AdminConsole.Utilities.Validation;
|
||||
using Bit.Core.Billing.Constants;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Models.StaticStore.Plans;
|
||||
@ -39,7 +39,7 @@ public class InviteUserPaymentValidationTests
|
||||
});
|
||||
|
||||
Assert.IsType<Invalid<PaymentsSubscription>>(result);
|
||||
Assert.Equal(PaymentCancelledSubscriptionError.Code, (result as Invalid<PaymentsSubscription>)!.ErrorMessageString);
|
||||
Assert.Equal(PaymentCancelledSubscriptionError.Code, (result as Invalid<PaymentsSubscription>)!.Error.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
using Bit.Core.AdminConsole.Utilities.Validation;
|
||||
using Bit.Core.Billing.Enums;
|
||||
using Bit.Core.Billing.Models.StaticStore.Plans;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
@ -67,7 +67,7 @@ public class InviteUsersPasswordManagerValidatorTests
|
||||
var result = await sutProvider.Sut.ValidateAsync(subscriptionUpdate);
|
||||
|
||||
Assert.IsType<Invalid<PasswordManagerSubscriptionUpdate>>(result);
|
||||
Assert.Equal(PasswordManagerSeatLimitHasBeenReachedError.Code, (result as Invalid<PasswordManagerSubscriptionUpdate>)!.ErrorMessageString);
|
||||
Assert.Equal(PasswordManagerSeatLimitHasBeenReachedError.Code, (result as Invalid<PasswordManagerSubscriptionUpdate>)!.Error.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -88,6 +88,6 @@ public class InviteUsersPasswordManagerValidatorTests
|
||||
var result = await sutProvider.Sut.ValidateAsync(subscriptionUpdate);
|
||||
|
||||
Assert.IsType<Invalid<PasswordManagerSubscriptionUpdate>>(result);
|
||||
Assert.Equal(PasswordManagerPlanDoesNotAllowAdditionalSeatsError.Code, (result as Invalid<PasswordManagerSubscriptionUpdate>)!.ErrorMessageString);
|
||||
Assert.Equal(PasswordManagerPlanDoesNotAllowAdditionalSeatsError.Code, (result as Invalid<PasswordManagerSubscriptionUpdate>)!.Error.Message);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Requests;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Models;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyValidators;
|
||||
using Bit.Core.AdminConsole.Utilities.Commands;
|
||||
using Bit.Core.Auth.Entities;
|
||||
using Bit.Core.Auth.Enums;
|
||||
using Bit.Core.Auth.Models.Data;
|
||||
@ -11,7 +12,6 @@ using Bit.Core.Auth.Repositories;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Commands;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
|
@ -4,11 +4,11 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Requests;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Models;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyValidators;
|
||||
using Bit.Core.AdminConsole.Utilities.Commands;
|
||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Commands;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
|
@ -26,8 +26,8 @@ public class EventRouteServiceTests
|
||||
|
||||
await Subject.CreateAsync(eventMessage);
|
||||
|
||||
_broadcastEventWriteService.DidNotReceiveWithAnyArgs().CreateAsync(Arg.Any<EventMessage>());
|
||||
_storageEventWriteService.Received(1).CreateAsync(eventMessage);
|
||||
await _broadcastEventWriteService.DidNotReceiveWithAnyArgs().CreateAsync(Arg.Any<EventMessage>());
|
||||
await _storageEventWriteService.Received(1).CreateAsync(eventMessage);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@ -37,8 +37,8 @@ public class EventRouteServiceTests
|
||||
|
||||
await Subject.CreateAsync(eventMessage);
|
||||
|
||||
_broadcastEventWriteService.Received(1).CreateAsync(eventMessage);
|
||||
_storageEventWriteService.DidNotReceiveWithAnyArgs().CreateAsync(Arg.Any<EventMessage>());
|
||||
await _broadcastEventWriteService.Received(1).CreateAsync(eventMessage);
|
||||
await _storageEventWriteService.DidNotReceiveWithAnyArgs().CreateAsync(Arg.Any<EventMessage>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@ -48,8 +48,8 @@ public class EventRouteServiceTests
|
||||
|
||||
await Subject.CreateManyAsync(eventMessages);
|
||||
|
||||
_broadcastEventWriteService.DidNotReceiveWithAnyArgs().CreateManyAsync(Arg.Any<IEnumerable<EventMessage>>());
|
||||
_storageEventWriteService.Received(1).CreateManyAsync(eventMessages);
|
||||
await _broadcastEventWriteService.DidNotReceiveWithAnyArgs().CreateManyAsync(Arg.Any<IEnumerable<EventMessage>>());
|
||||
await _storageEventWriteService.Received(1).CreateManyAsync(eventMessages);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@ -59,7 +59,7 @@ public class EventRouteServiceTests
|
||||
|
||||
await Subject.CreateManyAsync(eventMessages);
|
||||
|
||||
_broadcastEventWriteService.Received(1).CreateManyAsync(eventMessages);
|
||||
_storageEventWriteService.DidNotReceiveWithAnyArgs().CreateManyAsync(Arg.Any<IEnumerable<EventMessage>>());
|
||||
await _broadcastEventWriteService.Received(1).CreateManyAsync(eventMessages);
|
||||
await _storageEventWriteService.DidNotReceiveWithAnyArgs().CreateManyAsync(Arg.Any<IEnumerable<EventMessage>>());
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public class SlackEventHandlerTests
|
||||
var sutProvider = GetSutProvider(OneConfiguration());
|
||||
|
||||
await sutProvider.Sut.HandleEventAsync(eventMessage);
|
||||
sutProvider.GetDependency<ISlackService>().Received(1).SendSlackMessageByChannelIdAsync(
|
||||
await sutProvider.GetDependency<ISlackService>().Received(1).SendSlackMessageByChannelIdAsync(
|
||||
Arg.Is(AssertHelper.AssertPropertyEqual(_token)),
|
||||
Arg.Is(AssertHelper.AssertPropertyEqual(
|
||||
$"Date: {eventMessage.Date}, Type: {eventMessage.Type}, UserId: {eventMessage.UserId}")),
|
||||
@ -103,13 +103,13 @@ public class SlackEventHandlerTests
|
||||
var sutProvider = GetSutProvider(TwoConfigurations());
|
||||
|
||||
await sutProvider.Sut.HandleEventAsync(eventMessage);
|
||||
sutProvider.GetDependency<ISlackService>().Received(1).SendSlackMessageByChannelIdAsync(
|
||||
await sutProvider.GetDependency<ISlackService>().Received(1).SendSlackMessageByChannelIdAsync(
|
||||
Arg.Is(AssertHelper.AssertPropertyEqual(_token)),
|
||||
Arg.Is(AssertHelper.AssertPropertyEqual(
|
||||
$"Date: {eventMessage.Date}, Type: {eventMessage.Type}, UserId: {eventMessage.UserId}")),
|
||||
Arg.Is(AssertHelper.AssertPropertyEqual(_channelId))
|
||||
);
|
||||
sutProvider.GetDependency<ISlackService>().Received(1).SendSlackMessageByChannelIdAsync(
|
||||
await sutProvider.GetDependency<ISlackService>().Received(1).SendSlackMessageByChannelIdAsync(
|
||||
Arg.Is(AssertHelper.AssertPropertyEqual(_token2)),
|
||||
Arg.Is(AssertHelper.AssertPropertyEqual(
|
||||
$"Date: {eventMessage.Date}, Type: {eventMessage.Type}, UserId: {eventMessage.UserId}")),
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Bit.Core.AdminConsole.Errors;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
using Bit.Core.AdminConsole.Utilities.Errors;
|
||||
using Bit.Core.AdminConsole.Utilities.Validation;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.AdminConsole.Shared;
|
||||
@ -22,13 +22,11 @@ public class IValidatorTests
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value.Name))
|
||||
{
|
||||
return Task.FromResult<ValidationResult<TestClass>>(new Invalid<TestClass>
|
||||
{
|
||||
Errors = [new InvalidRequestError<TestClass>(value)]
|
||||
});
|
||||
return Task.FromResult<ValidationResult<TestClass>>(
|
||||
new Invalid<TestClass>(new InvalidRequestError<TestClass>(value)));
|
||||
}
|
||||
|
||||
return Task.FromResult<ValidationResult<TestClass>>(new Valid<TestClass> { Value = value });
|
||||
return Task.FromResult<ValidationResult<TestClass>>(new Valid<TestClass>(value));
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +39,7 @@ public class IValidatorTests
|
||||
|
||||
Assert.IsType<Invalid<TestClass>>(result);
|
||||
var invalidResult = result as Invalid<TestClass>;
|
||||
Assert.Equal(InvalidRequestError<TestClass>.Code, invalidResult.Errors.First().Message);
|
||||
Assert.Equal(InvalidRequestError<TestClass>.Code, invalidResult!.Error.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1,9 +1,9 @@
|
||||
using Bit.Core.AdminConsole.Errors;
|
||||
using Bit.Core.Models.Commands;
|
||||
using Bit.Core.AdminConsole.Utilities.Commands;
|
||||
using Bit.Core.AdminConsole.Utilities.Errors;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Models.Commands;
|
||||
namespace Bit.Core.Test.AdminConsole.Utilities.Commands;
|
||||
|
||||
public class CommandResultTests
|
||||
{
|
@ -44,9 +44,6 @@ public abstract class BaseTokenProviderTests<T>
|
||||
|
||||
protected virtual void SetupUserService(IUserService userService, User user)
|
||||
{
|
||||
userService
|
||||
.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType, user)
|
||||
.Returns(true);
|
||||
userService
|
||||
.CanAccessPremium(user)
|
||||
.Returns(true);
|
||||
@ -85,8 +82,6 @@ public abstract class BaseTokenProviderTests<T>
|
||||
var userManager = SubstituteUserManager();
|
||||
MockDatabase(user, metaData);
|
||||
|
||||
AdditionalSetup(sutProvider, user);
|
||||
|
||||
var response = await sutProvider.Sut.CanGenerateTwoFactorTokenAsync(userManager, user);
|
||||
Assert.Equal(expectedResponse, response);
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ public class DuoUniversalTwoFactorTokenProviderTests : BaseTokenProviderTests<Du
|
||||
User user, SutProvider<DuoUniversalTokenProvider> sutProvider)
|
||||
{
|
||||
// Arrange
|
||||
AdditionalSetup(sutProvider, user);
|
||||
user.Premium = true;
|
||||
user.PremiumExpirationDate = DateTime.UtcNow.AddDays(1);
|
||||
|
||||
@ -100,6 +101,8 @@ public class DuoUniversalTwoFactorTokenProviderTests : BaseTokenProviderTests<Du
|
||||
User user, SutProvider<DuoUniversalTokenProvider> sutProvider)
|
||||
{
|
||||
// Arrange
|
||||
AdditionalSetup(sutProvider, user);
|
||||
|
||||
user.Premium = false;
|
||||
|
||||
sutProvider.GetDependency<IDuoUniversalTokenService>()
|
||||
|
@ -1,87 +0,0 @@
|
||||
using AutoFixture.Xunit2;
|
||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Tokens;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Auth.Models.Business.Tokenables;
|
||||
|
||||
public class HCaptchaTokenableTests
|
||||
{
|
||||
[Fact]
|
||||
public void CanHandleNullUser()
|
||||
{
|
||||
var token = new HCaptchaTokenable(null);
|
||||
|
||||
Assert.Equal(default, token.Id);
|
||||
Assert.Equal(default, token.Email);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TokenWithNullUserIsInvalid()
|
||||
{
|
||||
var token = new HCaptchaTokenable(null)
|
||||
{
|
||||
ExpirationDate = DateTime.UtcNow + TimeSpan.FromDays(1)
|
||||
};
|
||||
|
||||
Assert.False(token.Valid);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void TokenValidityCheckNullUserIdIsInvalid(User user)
|
||||
{
|
||||
var token = new HCaptchaTokenable(user)
|
||||
{
|
||||
ExpirationDate = DateTime.UtcNow + TimeSpan.FromDays(1)
|
||||
};
|
||||
|
||||
Assert.False(token.TokenIsValid(null));
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void CanUpdateExpirationToNonStandard(User user)
|
||||
{
|
||||
var token = new HCaptchaTokenable(user)
|
||||
{
|
||||
ExpirationDate = DateTime.MinValue
|
||||
};
|
||||
|
||||
Assert.Equal(DateTime.MinValue, token.ExpirationDate, TimeSpan.FromMilliseconds(10));
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void SetsDataFromUser(User user)
|
||||
{
|
||||
var token = new HCaptchaTokenable(user);
|
||||
|
||||
Assert.Equal(user.Id, token.Id);
|
||||
Assert.Equal(user.Email, token.Email);
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void SerializationSetsCorrectDateTime(User user)
|
||||
{
|
||||
var expectedDateTime = DateTime.UtcNow.AddHours(-5);
|
||||
var token = new HCaptchaTokenable(user)
|
||||
{
|
||||
ExpirationDate = expectedDateTime
|
||||
};
|
||||
|
||||
var result = Tokenable.FromToken<HCaptchaTokenable>(token.ToToken());
|
||||
|
||||
Assert.Equal(expectedDateTime, result.ExpirationDate, TimeSpan.FromMilliseconds(10));
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void IsInvalidIfIdentifierIsWrong(User user)
|
||||
{
|
||||
var token = new HCaptchaTokenable(user)
|
||||
{
|
||||
Identifier = "not correct"
|
||||
};
|
||||
|
||||
Assert.False(token.Valid);
|
||||
}
|
||||
}
|
@ -67,7 +67,7 @@ public class SsoTokenableTests
|
||||
ExpirationDate = expectedDateTime
|
||||
};
|
||||
|
||||
var result = Tokenable.FromToken<HCaptchaTokenable>(token.ToToken());
|
||||
var result = Tokenable.FromToken<SsoTokenable>(token.ToToken());
|
||||
|
||||
Assert.Equal(expectedDateTime, result.ExpirationDate, TimeSpan.FromMilliseconds(10));
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
@ -53,6 +54,39 @@ public class TwoFactorIsEnabledQueryTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_DatabaseReturnsEmpty_ResultEmpty(
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider,
|
||||
List<UserWithCalculatedPremium> usersWithCalculatedPremium)
|
||||
{
|
||||
// Arrange
|
||||
var userIds = usersWithCalculatedPremium.Select(u => u.Id).ToList();
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetManyWithCalculatedPremiumAsync(Arg.Any<IEnumerable<Guid>>())
|
||||
.Returns([]);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(userIds);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData((IEnumerable<Guid>)null)]
|
||||
[BitAutoData([])]
|
||||
public async Task TwoFactorIsEnabledQuery_UserIdsNullorEmpty_ResultEmpty(
|
||||
IEnumerable<Guid> userIds,
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider)
|
||||
{
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(userIds);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_WithNoTwoFactorEnabled_ReturnsAllTwoFactorDisabled(
|
||||
@ -122,8 +156,11 @@ public class TwoFactorIsEnabledQueryTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_WithNullTwoFactorProviders_ReturnsAllTwoFactorDisabled(
|
||||
[BitAutoData("")]
|
||||
[BitAutoData("{}")]
|
||||
[BitAutoData((string)null)]
|
||||
public async Task TwoFactorIsEnabledQuery_WithNullOrEmptyTwoFactorProviders_ReturnsAllTwoFactorDisabled(
|
||||
string twoFactorProviders,
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider,
|
||||
List<UserWithCalculatedPremium> usersWithCalculatedPremium)
|
||||
{
|
||||
@ -132,7 +169,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
foreach (var user in usersWithCalculatedPremium)
|
||||
{
|
||||
user.TwoFactorProviders = null; // No two-factor providers configured
|
||||
user.TwoFactorProviders = twoFactorProviders; // No two-factor providers configured
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
@ -176,6 +213,24 @@ public class TwoFactorIsEnabledQueryTests
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_UserIdNull_ReturnsFalse(
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider)
|
||||
{
|
||||
// Arrange
|
||||
var user = new TestTwoFactorProviderUser
|
||||
{
|
||||
Id = null
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(TwoFactorProviderType.Authenticator)]
|
||||
[BitAutoData(TwoFactorProviderType.Email)]
|
||||
@ -193,10 +248,8 @@ public class TwoFactorIsEnabledQueryTests
|
||||
{ freeProviderType, new TwoFactorProvider { Enabled = true } }
|
||||
};
|
||||
|
||||
user.Premium = false;
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
@ -205,7 +258,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -230,7 +283,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -252,14 +305,18 @@ public class TwoFactorIsEnabledQueryTests
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetManyWithCalculatedPremiumAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(user.Id)))
|
||||
.Returns(new List<UserWithCalculatedPremium> { user });
|
||||
.GetCalculatedPremiumAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.ReceivedWithAnyArgs(1)
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -268,7 +325,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
public async Task TwoFactorIsEnabledQuery_WithProviderTypeRequiringPremium_WithUserPremium_ReturnsTrue(
|
||||
TwoFactorProviderType premiumProviderType,
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider,
|
||||
User user)
|
||||
UserWithCalculatedPremium user)
|
||||
{
|
||||
// Arrange
|
||||
var twoFactorProviders = new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
@ -276,9 +333,14 @@ public class TwoFactorIsEnabledQueryTests
|
||||
{ premiumProviderType, new TwoFactorProvider { Enabled = true } }
|
||||
};
|
||||
|
||||
user.Premium = true;
|
||||
user.Premium = false;
|
||||
user.HasPremiumAccess = true;
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetCalculatedPremiumAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
@ -286,8 +348,8 @@ public class TwoFactorIsEnabledQueryTests
|
||||
Assert.True(result);
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
.ReceivedWithAnyArgs(1)
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -309,14 +371,18 @@ public class TwoFactorIsEnabledQueryTests
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetManyWithCalculatedPremiumAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(user.Id)))
|
||||
.Returns(new List<UserWithCalculatedPremium> { user });
|
||||
.GetCalculatedPremiumAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.ReceivedWithAnyArgs(1)
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -333,5 +399,29 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
private class TestTwoFactorProviderUser : ITwoFactorProvidersUser
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string TwoFactorProviders { get; set; }
|
||||
public bool Premium { get; set; }
|
||||
public Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders()
|
||||
{
|
||||
return JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(TwoFactorProviders);
|
||||
}
|
||||
|
||||
public Guid? GetUserId()
|
||||
{
|
||||
return Id;
|
||||
}
|
||||
|
||||
public bool GetPremium()
|
||||
{
|
||||
return Premium;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Models.BitStripe;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Stripe;
|
||||
using Xunit;
|
||||
@ -22,8 +21,7 @@ public class PaymentHistoryServiceTests
|
||||
var stripeAdapter = Substitute.For<IStripeAdapter>();
|
||||
stripeAdapter.InvoiceListAsync(Arg.Any<StripeInvoiceListOptions>()).Returns(invoices);
|
||||
var transactionRepository = Substitute.For<ITransactionRepository>();
|
||||
var logger = Substitute.For<ILogger<PaymentHistoryService>>();
|
||||
var paymentHistoryService = new PaymentHistoryService(stripeAdapter, transactionRepository, logger);
|
||||
var paymentHistoryService = new PaymentHistoryService(stripeAdapter, transactionRepository);
|
||||
|
||||
// Act
|
||||
var result = await paymentHistoryService.GetInvoiceHistoryAsync(subscriber);
|
||||
@ -40,8 +38,7 @@ public class PaymentHistoryServiceTests
|
||||
// Arrange
|
||||
var paymentHistoryService = new PaymentHistoryService(
|
||||
Substitute.For<IStripeAdapter>(),
|
||||
Substitute.For<ITransactionRepository>(),
|
||||
Substitute.For<ILogger<PaymentHistoryService>>());
|
||||
Substitute.For<ITransactionRepository>());
|
||||
|
||||
// Act
|
||||
var result = await paymentHistoryService.GetInvoiceHistoryAsync(null);
|
||||
@ -59,8 +56,7 @@ public class PaymentHistoryServiceTests
|
||||
var transactionRepository = Substitute.For<ITransactionRepository>();
|
||||
transactionRepository.GetManyByOrganizationIdAsync(subscriber.Id, Arg.Any<int>(), Arg.Any<DateTime?>()).Returns(transactions);
|
||||
var stripeAdapter = Substitute.For<IStripeAdapter>();
|
||||
var logger = Substitute.For<ILogger<PaymentHistoryService>>();
|
||||
var paymentHistoryService = new PaymentHistoryService(stripeAdapter, transactionRepository, logger);
|
||||
var paymentHistoryService = new PaymentHistoryService(stripeAdapter, transactionRepository);
|
||||
|
||||
// Act
|
||||
var result = await paymentHistoryService.GetTransactionHistoryAsync(subscriber);
|
||||
@ -77,8 +73,7 @@ public class PaymentHistoryServiceTests
|
||||
// Arrange
|
||||
var paymentHistoryService = new PaymentHistoryService(
|
||||
Substitute.For<IStripeAdapter>(),
|
||||
Substitute.For<ITransactionRepository>(),
|
||||
Substitute.For<ILogger<PaymentHistoryService>>());
|
||||
Substitute.For<ITransactionRepository>());
|
||||
|
||||
// Act
|
||||
var result = await paymentHistoryService.GetTransactionHistoryAsync(null);
|
||||
|
@ -2,8 +2,6 @@
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Bit.Core.Test</RootNamespace>
|
||||
<!-- Temp exclusions until warnings are fixed -->
|
||||
<WarningsNotAsErrors>$(WarningsNotAsErrors);CS4014</WarningsNotAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
|
||||
|
@ -9,6 +9,7 @@ using Bit.Core.AdminConsole.Services;
|
||||
using Bit.Core.Auth.Enums;
|
||||
using Bit.Core.Auth.Models;
|
||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
@ -324,6 +325,7 @@ public class UserServiceTests
|
||||
sutProvider.GetDependency<IPremiumUserBillingService>(),
|
||||
sutProvider.GetDependency<IRemoveOrganizationUserCommand>(),
|
||||
sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>(),
|
||||
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>(),
|
||||
sutProvider.GetDependency<IDistributedCache>()
|
||||
);
|
||||
|
||||
@ -476,6 +478,9 @@ public class UserServiceTests
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
.GetByIdAsync(organization.Id)
|
||||
.Returns(organization);
|
||||
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
|
||||
.TwoFactorIsEnabledAsync(user)
|
||||
.Returns(true);
|
||||
var expectedSavedProviders = JsonHelpers.LegacySerialize(new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
{
|
||||
[TwoFactorProviderType.Remember] = new() { Enabled = true }
|
||||
@ -911,6 +916,7 @@ public class UserServiceTests
|
||||
sutProvider.GetDependency<IPremiumUserBillingService>(),
|
||||
sutProvider.GetDependency<IRemoveOrganizationUserCommand>(),
|
||||
sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>(),
|
||||
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>(),
|
||||
sutProvider.GetDependency<IDistributedCache>()
|
||||
);
|
||||
}
|
||||
|
@ -40,12 +40,12 @@ public class GetTasksForOrganizationQueryTests
|
||||
var result = await sutProvider.Sut.GetTasksAsync(org.Id, status);
|
||||
|
||||
Assert.Equal(2, result.Count);
|
||||
sutProvider.GetDependency<IAuthorizationService>().Received(1).AuthorizeAsync(
|
||||
await sutProvider.GetDependency<IAuthorizationService>().Received(1).AuthorizeAsync(
|
||||
Arg.Any<ClaimsPrincipal>(), org, Arg.Is<IEnumerable<IAuthorizationRequirement>>(
|
||||
e => e.Contains(SecurityTaskOperations.ListAllForOrganization)
|
||||
)
|
||||
);
|
||||
sutProvider.GetDependency<ISecurityTaskRepository>().Received(1).GetManyByOrganizationIdStatusAsync(org.Id, SecurityTaskStatus.Pending);
|
||||
await sutProvider.GetDependency<ISecurityTaskRepository>().Received(1).GetManyByOrganizationIdStatusAsync(org.Id, SecurityTaskStatus.Pending);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@ -82,11 +82,11 @@ public class GetTasksForOrganizationQueryTests
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetTasksAsync(org.Id));
|
||||
|
||||
sutProvider.GetDependency<IAuthorizationService>().Received(1).AuthorizeAsync(
|
||||
await sutProvider.GetDependency<IAuthorizationService>().Received(1).AuthorizeAsync(
|
||||
Arg.Any<ClaimsPrincipal>(), org, Arg.Is<IEnumerable<IAuthorizationRequirement>>(
|
||||
e => e.Contains(SecurityTaskOperations.ListAllForOrganization)
|
||||
)
|
||||
);
|
||||
sutProvider.GetDependency<ISecurityTaskRepository>().Received(0).GetManyByOrganizationIdStatusAsync(org.Id, SecurityTaskStatus.Pending);
|
||||
await sutProvider.GetDependency<ISecurityTaskRepository>().Received(0).GetManyByOrganizationIdStatusAsync(org.Id, SecurityTaskStatus.Pending);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ using System.Text;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Auth.Models.Api.Request.Accounts;
|
||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||
using Bit.Core.Auth.Services;
|
||||
using Bit.Core.Auth.UserFeatures.Registration;
|
||||
using Bit.Core.Auth.UserFeatures.WebAuthnLogin;
|
||||
using Bit.Core.Context;
|
||||
@ -38,7 +37,6 @@ public class AccountsControllerTests : IDisposable
|
||||
private readonly ILogger<AccountsController> _logger;
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IRegisterUserCommand _registerUserCommand;
|
||||
private readonly ICaptchaValidationService _captchaValidationService;
|
||||
private readonly IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> _assertionOptionsDataProtector;
|
||||
private readonly IGetWebAuthnLoginCredentialAssertionOptionsCommand _getWebAuthnLoginCredentialAssertionOptionsCommand;
|
||||
private readonly ISendVerificationEmailForRegistrationCommand _sendVerificationEmailForRegistrationCommand;
|
||||
@ -54,7 +52,6 @@ public class AccountsControllerTests : IDisposable
|
||||
_logger = Substitute.For<ILogger<AccountsController>>();
|
||||
_userRepository = Substitute.For<IUserRepository>();
|
||||
_registerUserCommand = Substitute.For<IRegisterUserCommand>();
|
||||
_captchaValidationService = Substitute.For<ICaptchaValidationService>();
|
||||
_assertionOptionsDataProtector = Substitute.For<IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable>>();
|
||||
_getWebAuthnLoginCredentialAssertionOptionsCommand = Substitute.For<IGetWebAuthnLoginCredentialAssertionOptionsCommand>();
|
||||
_sendVerificationEmailForRegistrationCommand = Substitute.For<ISendVerificationEmailForRegistrationCommand>();
|
||||
@ -68,7 +65,6 @@ public class AccountsControllerTests : IDisposable
|
||||
_logger,
|
||||
_userRepository,
|
||||
_registerUserCommand,
|
||||
_captchaValidationService,
|
||||
_assertionOptionsDataProtector,
|
||||
_getWebAuthnLoginCredentialAssertionOptionsCommand,
|
||||
_sendVerificationEmailForRegistrationCommand,
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<!-- Temp exclusions until warnings are fixed -->
|
||||
<WarningsNotAsErrors>$(WarningsNotAsErrors);CS0672;CS1998</WarningsNotAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -33,7 +33,6 @@ public class BaseRequestValidatorTests
|
||||
private readonly IDeviceValidator _deviceValidator;
|
||||
private readonly ITwoFactorAuthenticationValidator _twoFactorAuthenticationValidator;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IMailService _mailService;
|
||||
private readonly ILogger<BaseRequestValidatorTests> _logger;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
@ -54,7 +53,6 @@ public class BaseRequestValidatorTests
|
||||
_deviceValidator = Substitute.For<IDeviceValidator>();
|
||||
_twoFactorAuthenticationValidator = Substitute.For<ITwoFactorAuthenticationValidator>();
|
||||
_organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
|
||||
_mailService = Substitute.For<IMailService>();
|
||||
_logger = Substitute.For<ILogger<BaseRequestValidatorTests>>();
|
||||
_currentContext = Substitute.For<ICurrentContext>();
|
||||
_globalSettings = Substitute.For<GlobalSettings>();
|
||||
@ -72,7 +70,6 @@ public class BaseRequestValidatorTests
|
||||
_deviceValidator,
|
||||
_twoFactorAuthenticationValidator,
|
||||
_organizationUserRepository,
|
||||
_mailService,
|
||||
_logger,
|
||||
_currentContext,
|
||||
_globalSettings,
|
||||
@ -84,36 +81,6 @@ public class BaseRequestValidatorTests
|
||||
_policyRequirementQuery);
|
||||
}
|
||||
|
||||
/* Logic path
|
||||
* ValidateAsync -> _Logger.LogInformation
|
||||
* |-> BuildErrorResultAsync -> _eventService.LogUserEventAsync
|
||||
* |-> SetErrorResult
|
||||
*/
|
||||
[Theory, BitAutoData]
|
||||
public async Task ValidateAsync_IsBot_UserNotNull_ShouldBuildErrorResult_ShouldLogFailedLoginEvent(
|
||||
[AuthFixtures.ValidatedTokenRequest] ValidatedTokenRequest tokenRequest,
|
||||
CustomValidatorRequestContext requestContext,
|
||||
GrantValidationResult grantResult)
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = true;
|
||||
_sut.isValid = true;
|
||||
|
||||
// Act
|
||||
await _sut.ValidateAsync(context);
|
||||
|
||||
var errorResponse = (ErrorResponseModel)context.GrantResult.CustomResponse["ErrorModel"];
|
||||
|
||||
// Assert
|
||||
await _eventService.Received(1)
|
||||
.LogUserEventAsync(context.CustomValidatorRequestContext.User.Id,
|
||||
EventType.User_FailedLogIn);
|
||||
Assert.True(context.GrantResult.IsError);
|
||||
Assert.Equal("Username or password is incorrect. Try again.", errorResponse.Message);
|
||||
}
|
||||
|
||||
/* Logic path
|
||||
* ValidateAsync -> UpdateFailedAuthDetailsAsync -> _mailService.SendFailedLoginAttemptsEmailAsync
|
||||
* |-> BuildErrorResultAsync -> _eventService.LogUserEventAsync
|
||||
@ -128,8 +95,6 @@ public class BaseRequestValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_globalSettings.Captcha.Returns(new GlobalSettings.CaptchaSettings());
|
||||
_globalSettings.SelfHosted = true;
|
||||
_sut.isValid = false;
|
||||
|
||||
@ -142,44 +107,6 @@ public class BaseRequestValidatorTests
|
||||
Assert.Equal("Username or password is incorrect. Try again.", errorResponse.Message);
|
||||
}
|
||||
|
||||
/* Logic path
|
||||
* ValidateAsync -> UpdateFailedAuthDetailsAsync -> _mailService.SendFailedLoginAttemptsEmailAsync
|
||||
* |-> BuildErrorResultAsync -> _eventService.LogUserEventAsync
|
||||
* |-> SetErrorResult
|
||||
*/
|
||||
[Theory, BitAutoData]
|
||||
public async Task ValidateAsync_ContextNotValid_MaxAttemptLogin_ShouldSendEmail(
|
||||
[AuthFixtures.ValidatedTokenRequest] ValidatedTokenRequest tokenRequest,
|
||||
CustomValidatorRequestContext requestContext,
|
||||
GrantValidationResult grantResult)
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
// This needs to be n-1 of the max failed login attempts
|
||||
context.CustomValidatorRequestContext.User.FailedLoginCount = 2;
|
||||
context.CustomValidatorRequestContext.KnownDevice = false;
|
||||
|
||||
_globalSettings.Captcha.Returns(
|
||||
new GlobalSettings.CaptchaSettings
|
||||
{
|
||||
MaximumFailedLoginAttempts = 3
|
||||
});
|
||||
_sut.isValid = false;
|
||||
|
||||
// Act
|
||||
await _sut.ValidateAsync(context);
|
||||
|
||||
// Assert
|
||||
await _mailService.Received(1)
|
||||
.SendFailedLoginAttemptsEmailAsync(
|
||||
Arg.Any<string>(), Arg.Any<DateTime>(), Arg.Any<string>());
|
||||
Assert.True(context.GrantResult.IsError);
|
||||
var errorResponse = (ErrorResponseModel)context.GrantResult.CustomResponse["ErrorModel"];
|
||||
Assert.Equal("Username or password is incorrect. Try again.", errorResponse.Message);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task ValidateAsync_DeviceNotValidated_ShouldLogError(
|
||||
[AuthFixtures.ValidatedTokenRequest] ValidatedTokenRequest tokenRequest,
|
||||
@ -189,7 +116,6 @@ public class BaseRequestValidatorTests
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
// 1 -> to pass
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_sut.isValid = true;
|
||||
|
||||
// 2 -> will result to false with no extra configuration
|
||||
@ -226,7 +152,6 @@ public class BaseRequestValidatorTests
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
// 1 -> to pass
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_sut.isValid = true;
|
||||
|
||||
// 2 -> will result to false with no extra configuration
|
||||
@ -263,7 +188,6 @@ public class BaseRequestValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_sut.isValid = true;
|
||||
|
||||
context.ValidatedTokenRequest.GrantType = grantType;
|
||||
@ -294,7 +218,6 @@ public class BaseRequestValidatorTests
|
||||
// Arrange
|
||||
_featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_sut.isValid = true;
|
||||
|
||||
context.ValidatedTokenRequest.GrantType = grantType;
|
||||
@ -326,7 +249,6 @@ public class BaseRequestValidatorTests
|
||||
// Arrange
|
||||
_featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_sut.isValid = true;
|
||||
|
||||
context.ValidatedTokenRequest.GrantType = grantType;
|
||||
@ -363,7 +285,6 @@ public class BaseRequestValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_sut.isValid = true;
|
||||
|
||||
context.ValidatedTokenRequest.GrantType = grantType;
|
||||
@ -401,7 +322,6 @@ public class BaseRequestValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(tokenRequest, requestContext, grantResult);
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
_sut.isValid = true;
|
||||
|
||||
context.ValidatedTokenRequest.GrantType = grantType;
|
||||
@ -439,7 +359,6 @@ public class BaseRequestValidatorTests
|
||||
var user = context.CustomValidatorRequestContext.User;
|
||||
user.Key = null;
|
||||
|
||||
context.CustomValidatorRequestContext.CaptchaResponse.IsBot = false;
|
||||
context.ValidatedTokenRequest.ClientId = "Not Web";
|
||||
_sut.isValid = true;
|
||||
_twoFactorAuthenticationValidator
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Bit.Core;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Api;
|
||||
@ -28,7 +27,7 @@ public class DeviceValidatorTests
|
||||
private readonly IUserService _userService;
|
||||
private readonly IDistributedCache _distributedCache;
|
||||
private readonly Logger<DeviceValidator> _logger;
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
private readonly DeviceValidator _sut;
|
||||
|
||||
public DeviceValidatorTests()
|
||||
@ -41,7 +40,6 @@ public class DeviceValidatorTests
|
||||
_userService = Substitute.For<IUserService>();
|
||||
_distributedCache = Substitute.For<IDistributedCache>();
|
||||
_logger = new Logger<DeviceValidator>(Substitute.For<ILoggerFactory>());
|
||||
_featureService = Substitute.For<IFeatureService>();
|
||||
_sut = new DeviceValidator(
|
||||
_deviceService,
|
||||
_deviceRepository,
|
||||
@ -50,8 +48,7 @@ public class DeviceValidatorTests
|
||||
_currentContext,
|
||||
_userService,
|
||||
_distributedCache,
|
||||
_logger,
|
||||
_featureService);
|
||||
_logger);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
@ -312,8 +309,6 @@ public class DeviceValidatorTests
|
||||
AddValidDeviceToRequest(request);
|
||||
_deviceRepository.GetByIdentifierAsync(context.Device.Identifier, context.User.Id)
|
||||
.Returns(null as Device);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification)
|
||||
.Returns(true);
|
||||
|
||||
request.GrantType = grantType;
|
||||
|
||||
@ -336,8 +331,6 @@ public class DeviceValidatorTests
|
||||
AddValidDeviceToRequest(request);
|
||||
_deviceRepository.GetByIdentifierAsync(context.Device.Identifier, context.User.Id)
|
||||
.Returns(null as Device);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification)
|
||||
.Returns(true);
|
||||
|
||||
request.Raw.Add("AuthRequest", "authRequest");
|
||||
|
||||
@ -360,8 +353,6 @@ public class DeviceValidatorTests
|
||||
AddValidDeviceToRequest(request);
|
||||
_deviceRepository.GetByIdentifierAsync(context.Device.Identifier, context.User.Id)
|
||||
.Returns(null as Device);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification)
|
||||
.Returns(true);
|
||||
|
||||
context.TwoFactorRequired = true;
|
||||
|
||||
@ -384,8 +375,6 @@ public class DeviceValidatorTests
|
||||
AddValidDeviceToRequest(request);
|
||||
_deviceRepository.GetByIdentifierAsync(context.Device.Identifier, context.User.Id)
|
||||
.Returns(null as Device);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification)
|
||||
.Returns(true);
|
||||
|
||||
context.SsoRequired = true;
|
||||
|
||||
@ -404,7 +393,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
|
||||
context.User = null;
|
||||
@ -430,7 +418,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
context.User.VerifyDevices = false;
|
||||
|
||||
@ -454,7 +441,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
_distributedCache.GetAsync(Arg.Any<string>()).Returns(null as byte[]);
|
||||
context.User.CreationDate = DateTime.UtcNow - TimeSpan.FromHours(23);
|
||||
@ -479,7 +465,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
_distributedCache.GetAsync(Arg.Any<string>()).Returns([1]);
|
||||
|
||||
@ -503,7 +488,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
_distributedCache.GetAsync(Arg.Any<string>()).Returns(null as byte[]);
|
||||
|
||||
@ -535,7 +519,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
_distributedCache.GetAsync(Arg.Any<string>()).Returns(null as byte[]);
|
||||
|
||||
@ -564,7 +547,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
_distributedCache.GetAsync(Arg.Any<string>()).Returns([1]);
|
||||
_deviceRepository.GetManyByUserIdAsync(context.User.Id).Returns([]);
|
||||
@ -590,7 +572,6 @@ public class DeviceValidatorTests
|
||||
{
|
||||
// Arrange
|
||||
ArrangeForHandleNewDeviceVerificationTest(context, request);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.NewDeviceVerification).Returns(true);
|
||||
_globalSettings.EnableNewDeviceVerification = true;
|
||||
_deviceRepository.GetManyByUserIdAsync(context.User.Id).Returns([new Device()]);
|
||||
_distributedCache.GetAsync(Arg.Any<string>()).Returns(null as byte[]);
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Bit.Core.Auth.Enums;
|
||||
using Bit.Core.Auth.Identity.TokenProviders;
|
||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data.Organizations;
|
||||
@ -27,11 +28,11 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
private readonly IUserService _userService;
|
||||
private readonly UserManagerTestWrapper<User> _userManager;
|
||||
private readonly IOrganizationDuoUniversalTokenProvider _organizationDuoUniversalTokenProvider;
|
||||
private readonly IFeatureService _featureService;
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IDataProtectorTokenFactory<SsoEmail2faSessionTokenable> _ssoEmail2faSessionTokenable;
|
||||
private readonly ITwoFactorIsEnabledQuery _twoFactorenabledQuery;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly TwoFactorAuthenticationValidator _sut;
|
||||
|
||||
@ -40,22 +41,22 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
_userService = Substitute.For<IUserService>();
|
||||
_userManager = SubstituteUserManager();
|
||||
_organizationDuoUniversalTokenProvider = Substitute.For<IOrganizationDuoUniversalTokenProvider>();
|
||||
_featureService = Substitute.For<IFeatureService>();
|
||||
_applicationCacheService = Substitute.For<IApplicationCacheService>();
|
||||
_organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
|
||||
_organizationRepository = Substitute.For<IOrganizationRepository>();
|
||||
_ssoEmail2faSessionTokenable = Substitute.For<IDataProtectorTokenFactory<SsoEmail2faSessionTokenable>>();
|
||||
_twoFactorenabledQuery = Substitute.For<ITwoFactorIsEnabledQuery>();
|
||||
_currentContext = Substitute.For<ICurrentContext>();
|
||||
|
||||
_sut = new TwoFactorAuthenticationValidator(
|
||||
_userService,
|
||||
_userManager,
|
||||
_organizationDuoUniversalTokenProvider,
|
||||
_featureService,
|
||||
_applicationCacheService,
|
||||
_organizationUserRepository,
|
||||
_organizationRepository,
|
||||
_ssoEmail2faSessionTokenable,
|
||||
_twoFactorenabledQuery,
|
||||
_currentContext);
|
||||
}
|
||||
|
||||
@ -251,9 +252,9 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(TwoFactorProviderType.Email)]
|
||||
public async void BuildTwoFactorResultAsync_IndividualEmailProvider_SendsEmail_SetsSsoToken_ReturnsNotNull(
|
||||
TwoFactorProviderType providerType,
|
||||
User user)
|
||||
public async void BuildTwoFactorResultAsync_SetsSsoToken_ReturnsNotNull(
|
||||
TwoFactorProviderType providerType,
|
||||
User user)
|
||||
{
|
||||
// Arrange
|
||||
var providerTypeInt = (int)providerType;
|
||||
@ -263,9 +264,6 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
_userManager.SUPPORTS_TWO_FACTOR = true;
|
||||
_userManager.TWO_FACTOR_PROVIDERS = [providerType.ToString()];
|
||||
|
||||
_userService.TwoFactorProviderIsEnabledAsync(Arg.Any<TwoFactorProviderType>(), user)
|
||||
.Returns(true);
|
||||
|
||||
// Act
|
||||
var result = await _sut.BuildTwoFactorResultAsync(user, null);
|
||||
|
||||
@ -278,8 +276,6 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
Assert.True(providers.ContainsKey(providerTypeInt.ToString()));
|
||||
Assert.True(result.ContainsKey("SsoEmail2faSessionToken"));
|
||||
Assert.True(result.ContainsKey("Email"));
|
||||
|
||||
await _userService.Received(1).SendTwoFactorEmailAsync(Arg.Any<User>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -322,9 +318,6 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
string token)
|
||||
{
|
||||
// Arrange
|
||||
_userService.TwoFactorProviderIsEnabledAsync(
|
||||
TwoFactorProviderType.Email, user).Returns(true);
|
||||
|
||||
_userManager.TWO_FACTOR_PROVIDERS = ["email"];
|
||||
|
||||
// Act
|
||||
@ -342,10 +335,8 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
string token)
|
||||
{
|
||||
// Arrange
|
||||
_userService.TwoFactorProviderIsEnabledAsync(
|
||||
TwoFactorProviderType.Email, user).Returns(false);
|
||||
|
||||
_userManager.TWO_FACTOR_PROVIDERS = ["email"];
|
||||
user.TwoFactorProviders = "";
|
||||
|
||||
// Act
|
||||
var result = await _sut.VerifyTwoFactorAsync(
|
||||
@ -362,9 +353,6 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
string token)
|
||||
{
|
||||
// Arrange
|
||||
_userService.TwoFactorProviderIsEnabledAsync(
|
||||
TwoFactorProviderType.OrganizationDuo, user).Returns(false);
|
||||
|
||||
_userManager.TWO_FACTOR_PROVIDERS = ["OrganizationDuo"];
|
||||
|
||||
// Act
|
||||
@ -387,11 +375,9 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
string token)
|
||||
{
|
||||
// Arrange
|
||||
_userService.TwoFactorProviderIsEnabledAsync(
|
||||
providerType, user).Returns(true);
|
||||
|
||||
_userManager.TWO_FACTOR_ENABLED = true;
|
||||
_userManager.TWO_FACTOR_TOKEN_VERIFIED = true;
|
||||
user.TwoFactorProviders = GetTwoFactorIndividualProviderJson(providerType);
|
||||
|
||||
// Act
|
||||
var result = await _sut.VerifyTwoFactorAsync(user, null, providerType, token);
|
||||
@ -412,11 +398,9 @@ public class TwoFactorAuthenticationValidatorTests
|
||||
string token)
|
||||
{
|
||||
// Arrange
|
||||
_userService.TwoFactorProviderIsEnabledAsync(
|
||||
providerType, user).Returns(true);
|
||||
|
||||
_userManager.TWO_FACTOR_ENABLED = true;
|
||||
_userManager.TWO_FACTOR_TOKEN_VERIFIED = false;
|
||||
user.TwoFactorProviders = GetTwoFactorIndividualProviderJson(providerType);
|
||||
|
||||
// Act
|
||||
var result = await _sut.VerifyTwoFactorAsync(user, null, providerType, token);
|
||||
|
@ -54,7 +54,6 @@ IBaseRequestValidatorTestWrapper
|
||||
IDeviceValidator deviceValidator,
|
||||
ITwoFactorAuthenticationValidator twoFactorAuthenticationValidator,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IMailService mailService,
|
||||
ILogger logger,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings,
|
||||
@ -71,7 +70,6 @@ IBaseRequestValidatorTestWrapper
|
||||
deviceValidator,
|
||||
twoFactorAuthenticationValidator,
|
||||
organizationUserRepository,
|
||||
mailService,
|
||||
logger,
|
||||
currentContext,
|
||||
globalSettings,
|
||||
@ -96,6 +94,7 @@ IBaseRequestValidatorTestWrapper
|
||||
return context.ValidatedTokenRequest.Subject ?? new ClaimsPrincipal();
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
protected override void SetErrorResult(
|
||||
BaseRequestValidationContextFake context,
|
||||
Dictionary<string, object> customResponse)
|
||||
@ -103,6 +102,7 @@ IBaseRequestValidatorTestWrapper
|
||||
context.GrantResult = new GrantValidationResult(TokenRequestErrors.InvalidGrant, customResponse: customResponse);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
protected override void SetSsoResult(
|
||||
BaseRequestValidationContextFake context,
|
||||
Dictionary<string, object> customResponse)
|
||||
@ -121,6 +121,7 @@ IBaseRequestValidatorTestWrapper
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
protected override void SetTwoFactorResult(
|
||||
BaseRequestValidationContextFake context,
|
||||
Dictionary<string, object> customResponse)
|
||||
|
@ -56,9 +56,9 @@ public class UserManagerTestWrapper<TUser> : UserManager<TUser> where TUser : cl
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<bool> GetTwoFactorEnabledAsync(TUser user)
|
||||
public override Task<bool> GetTwoFactorEnabledAsync(TUser user)
|
||||
{
|
||||
return TWO_FACTOR_ENABLED;
|
||||
return Task.FromResult(TWO_FACTOR_ENABLED);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -66,9 +66,9 @@ public class UserManagerTestWrapper<TUser> : UserManager<TUser> where TUser : cl
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<IList<string>> GetValidTwoFactorProvidersAsync(TUser user)
|
||||
public override Task<IList<string>> GetValidTwoFactorProvidersAsync(TUser user)
|
||||
{
|
||||
return TWO_FACTOR_PROVIDERS;
|
||||
return Task.FromResult(TWO_FACTOR_PROVIDERS);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -77,9 +77,9 @@ public class UserManagerTestWrapper<TUser> : UserManager<TUser> where TUser : cl
|
||||
/// <param name="user"></param>
|
||||
/// <param name="tokenProvider"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<string> GenerateTwoFactorTokenAsync(TUser user, string tokenProvider)
|
||||
public override Task<string> GenerateTwoFactorTokenAsync(TUser user, string tokenProvider)
|
||||
{
|
||||
return TWO_FACTOR_TOKEN;
|
||||
return Task.FromResult(TWO_FACTOR_TOKEN);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -89,8 +89,8 @@ public class UserManagerTestWrapper<TUser> : UserManager<TUser> where TUser : cl
|
||||
/// <param name="tokenProvider"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<bool> VerifyTwoFactorTokenAsync(TUser user, string tokenProvider, string token)
|
||||
public override Task<bool> VerifyTwoFactorTokenAsync(TUser user, string tokenProvider, string token)
|
||||
{
|
||||
return TWO_FACTOR_TOKEN_VERIFIED;
|
||||
return Task.FromResult(TWO_FACTOR_TOKEN_VERIFIED);
|
||||
}
|
||||
}
|
||||
|
@ -316,6 +316,29 @@ public class OrganizationUserRepositoryTests
|
||||
BillingEmail = user1.Email, // TODO: EF does not enforce this being NOT NULl
|
||||
Plan = "Test", // TODO: EF does not enforce this being NOT NULl
|
||||
PrivateKey = "privatekey",
|
||||
UsePolicies = false,
|
||||
UseSso = false,
|
||||
UseKeyConnector = false,
|
||||
UseScim = false,
|
||||
UseGroups = false,
|
||||
UseDirectory = false,
|
||||
UseEvents = false,
|
||||
UseTotp = false,
|
||||
Use2fa = false,
|
||||
UseApi = false,
|
||||
UseResetPassword = false,
|
||||
UseSecretsManager = false,
|
||||
SelfHost = false,
|
||||
UsersGetPremium = false,
|
||||
UseCustomPermissions = false,
|
||||
Enabled = true,
|
||||
UsePasswordManager = false,
|
||||
LimitCollectionCreation = false,
|
||||
LimitCollectionDeletion = false,
|
||||
LimitItemDeletion = false,
|
||||
AllowAdminAccessToAllCollectionItems = false,
|
||||
UseRiskInsights = false,
|
||||
UseAdminSponsoredFamilies = false
|
||||
});
|
||||
|
||||
var organizationDomain = new OrganizationDomain
|
||||
@ -335,6 +358,7 @@ public class OrganizationUserRepositoryTests
|
||||
UserId = user1.Id,
|
||||
Status = OrganizationUserStatusType.Confirmed,
|
||||
ResetPasswordKey = "resetpasswordkey1",
|
||||
AccessSecretsManager = false
|
||||
});
|
||||
|
||||
await organizationUserRepository.CreateAsync(new OrganizationUser
|
||||
|
@ -0,0 +1,46 @@
|
||||
using Bit.Core.Platform.Installations;
|
||||
using Bit.Infrastructure.IntegrationTest.Comparers;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Infrastructure.IntegrationTest.Platform.Installations;
|
||||
|
||||
public class InstallationRepositoryTests
|
||||
{
|
||||
[DatabaseTheory, DatabaseData]
|
||||
public async Task GetByIdAsync_Works(IInstallationRepository installationRepository)
|
||||
{
|
||||
var installation = await installationRepository.CreateAsync(new Installation
|
||||
{
|
||||
Email = "test@email.com",
|
||||
Key = "installation_key",
|
||||
Enabled = true,
|
||||
});
|
||||
|
||||
var retrievedInstallation = await installationRepository.GetByIdAsync(installation.Id);
|
||||
|
||||
Assert.NotNull(retrievedInstallation);
|
||||
Assert.Equal("installation_key", retrievedInstallation.Key);
|
||||
}
|
||||
|
||||
[DatabaseTheory, DatabaseData]
|
||||
public async Task UpdateAsync_Works(IInstallationRepository installationRepository)
|
||||
{
|
||||
var installation = await installationRepository.CreateAsync(new Installation
|
||||
{
|
||||
Email = "test@email.com",
|
||||
Key = "installation_key",
|
||||
Enabled = true,
|
||||
});
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
installation.LastActivityDate = now;
|
||||
|
||||
await installationRepository.ReplaceAsync(installation);
|
||||
|
||||
var retrievedInstallation = await installationRepository.GetByIdAsync(installation.Id);
|
||||
|
||||
Assert.NotNull(retrievedInstallation.LastActivityDate);
|
||||
Assert.Equal(now, retrievedInstallation.LastActivityDate.Value, LaxDateTimeComparer.Default);
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using AspNetCoreRateLimit;
|
||||
using Bit.Core.Auth.Services;
|
||||
using Bit.Core.Billing.Services;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Platform.Push.Internal;
|
||||
@ -207,8 +206,6 @@ public abstract class WebApplicationFactoryBase<T> : WebApplicationFactory<T>
|
||||
|
||||
Replace<IMailDeliveryService, NoopMailDeliveryService>(services);
|
||||
|
||||
Replace<ICaptchaValidationService, NoopCaptchaValidationService>(services);
|
||||
|
||||
// TODO: Install and use azurite in CI pipeline
|
||||
Replace<IInstallationDeviceRepository, NoopRepos.InstallationDeviceRepository>(services);
|
||||
|
||||
|
Reference in New Issue
Block a user