mirror of
https://github.com/bitwarden/server.git
synced 2025-07-21 01:21:42 -05:00
Merge branch 'main' into option-to-disable-built-in-mssql
This commit is contained in:
@ -9,7 +9,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
||||||
<PackageReference Include="NSubstitute" Version="$(NSubstituteVersion)" />
|
<PackageReference Include="NSubstitute" Version="$(NSubstituteVersion)" />
|
||||||
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
||||||
|
@ -16,6 +16,7 @@ using Bit.Core.Utilities;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using AdminConsoleEntities = Bit.Core.AdminConsole.Entities;
|
||||||
|
|
||||||
namespace Bit.Api.AdminConsole.Controllers;
|
namespace Bit.Api.AdminConsole.Controllers;
|
||||||
|
|
||||||
@ -55,17 +56,16 @@ public class PoliciesController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{type}")]
|
[HttpGet("{type}")]
|
||||||
public async Task<PolicyResponseModel> Get(string orgId, int type)
|
public async Task<PolicyResponseModel> Get(Guid orgId, int type)
|
||||||
{
|
{
|
||||||
var orgIdGuid = new Guid(orgId);
|
if (!await _currentContext.ManagePolicies(orgId))
|
||||||
if (!await _currentContext.ManagePolicies(orgIdGuid))
|
|
||||||
{
|
{
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
var policy = await _policyRepository.GetByOrganizationIdTypeAsync(orgIdGuid, (PolicyType)type);
|
var policy = await _policyRepository.GetByOrganizationIdTypeAsync(orgId, (PolicyType)type);
|
||||||
if (policy == null)
|
if (policy == null)
|
||||||
{
|
{
|
||||||
throw new NotFoundException();
|
return new PolicyResponseModel(new AdminConsoleEntities.Policy() { Type = (PolicyType)type, Enabled = false });
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PolicyResponseModel(policy);
|
return new PolicyResponseModel(policy);
|
||||||
|
@ -148,6 +148,13 @@ public class AccountsController : Controller
|
|||||||
throw new BadRequestException("MasterPasswordHash", "Invalid password.");
|
throw new BadRequestException("MasterPasswordHash", "Invalid password.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If Account Deprovisioning is enabled, we need to check if the user is managed by any organization.
|
||||||
|
if (_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
&& await _userService.IsManagedByAnyOrganizationAsync(user.Id))
|
||||||
|
{
|
||||||
|
throw new BadRequestException("Cannot change emails for accounts owned by an organization. Contact your organization administrator for additional details.");
|
||||||
|
}
|
||||||
|
|
||||||
await _userService.InitiateEmailChangeAsync(user, model.NewEmail);
|
await _userService.InitiateEmailChangeAsync(user, model.NewEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +172,13 @@ public class AccountsController : Controller
|
|||||||
throw new BadRequestException("You cannot change your email when using Key Connector.");
|
throw new BadRequestException("You cannot change your email when using Key Connector.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If Account Deprovisioning is enabled, we need to check if the user is managed by any organization.
|
||||||
|
if (_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
&& await _userService.IsManagedByAnyOrganizationAsync(user.Id))
|
||||||
|
{
|
||||||
|
throw new BadRequestException("Cannot change emails for accounts owned by an organization. Contact your organization administrator for additional details.");
|
||||||
|
}
|
||||||
|
|
||||||
var result = await _userService.ChangeEmailAsync(user, model.MasterPasswordHash, model.NewEmail,
|
var result = await _userService.ChangeEmailAsync(user, model.MasterPasswordHash, model.NewEmail,
|
||||||
model.NewMasterPasswordHash, model.Token, model.Key);
|
model.NewMasterPasswordHash, model.Token, model.Key);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
|
@ -148,6 +148,7 @@ public static class FeatureFlagKeys
|
|||||||
public const string Pm13322AddPolicyDefinitions = "pm-13322-add-policy-definitions";
|
public const string Pm13322AddPolicyDefinitions = "pm-13322-add-policy-definitions";
|
||||||
public const string LimitCollectionCreationDeletionSplit = "pm-10863-limit-collection-creation-deletion-split";
|
public const string LimitCollectionCreationDeletionSplit = "pm-10863-limit-collection-creation-deletion-split";
|
||||||
public const string GeneratorToolsModernization = "generator-tools-modernization";
|
public const string GeneratorToolsModernization = "generator-tools-modernization";
|
||||||
|
public const string NewDeviceVerification = "new-device-verification";
|
||||||
|
|
||||||
public static List<string> GetAllKeys()
|
public static List<string> GetAllKeys()
|
||||||
{
|
{
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" />
|
<PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" />
|
||||||
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.401.24" />
|
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.401.30" />
|
||||||
<PackageReference Include="AWSSDK.SQS" Version="3.7.400.34" />
|
<PackageReference Include="AWSSDK.SQS" Version="3.7.400.40" />
|
||||||
<PackageReference Include="Azure.Data.Tables" Version="12.9.0" />
|
<PackageReference Include="Azure.Data.Tables" Version="12.9.0" />
|
||||||
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.3.4" />
|
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.3.4" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="8.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="8.0.10" />
|
||||||
<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.18.1" />
|
<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.18.1" />
|
||||||
<PackageReference Include="Azure.Storage.Blobs" Version="12.21.2" />
|
<PackageReference Include="Azure.Storage.Blobs" Version="12.21.2" />
|
||||||
<PackageReference Include="Azure.Storage.Queues" Version="12.19.1" />
|
<PackageReference Include="Azure.Storage.Queues" Version="12.19.1" />
|
||||||
@ -35,15 +35,15 @@
|
|||||||
<PackageReference Include="Fido2.AspNet" Version="3.0.1" />
|
<PackageReference Include="Fido2.AspNet" Version="3.0.1" />
|
||||||
<PackageReference Include="Handlebars.Net" Version="2.1.6" />
|
<PackageReference Include="Handlebars.Net" Version="2.1.6" />
|
||||||
<PackageReference Include="MailKit" Version="4.8.0" />
|
<PackageReference Include="MailKit" Version="4.8.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.44.0" />
|
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.45.0" />
|
||||||
<PackageReference Include="Microsoft.Azure.NotificationHubs" Version="4.2.0" />
|
<PackageReference Include="Microsoft.Azure.NotificationHubs" Version="4.2.0" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Cosmos" Version="1.6.1" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Cosmos" Version="1.6.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="8.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.10" />
|
||||||
<PackageReference Include="Quartz" Version="3.9.0" />
|
<PackageReference Include="Quartz" Version="3.9.0" />
|
||||||
<PackageReference Include="SendGrid" Version="9.29.3" />
|
<PackageReference Include="SendGrid" Version="9.29.3" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
|
||||||
@ -58,8 +58,8 @@
|
|||||||
<PackageReference Include="Stripe.net" Version="45.14.0" />
|
<PackageReference Include="Stripe.net" Version="45.14.0" />
|
||||||
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
||||||
<PackageReference Include="YubicoDotNetClient" Version="1.2.0" />
|
<PackageReference Include="YubicoDotNetClient" Version="1.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.8" />
|
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.10" />
|
||||||
<PackageReference Include="LaunchDarkly.ServerSdk" Version="8.5.2" />
|
<PackageReference Include="LaunchDarkly.ServerSdk" Version="8.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
using System.Net.Http.Headers;
|
using System.Net;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using Bit.Api.Auth.Models.Request.Accounts;
|
||||||
using Bit.Api.IntegrationTest.Factories;
|
using Bit.Api.IntegrationTest.Factories;
|
||||||
|
using Bit.Api.IntegrationTest.Helpers;
|
||||||
using Bit.Api.Models.Response;
|
using Bit.Api.Models.Response;
|
||||||
|
using Bit.Core;
|
||||||
|
using Bit.Core.Billing.Enums;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using NSubstitute;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Bit.Api.IntegrationTest.Controllers;
|
namespace Bit.Api.IntegrationTest.Controllers;
|
||||||
@ -35,4 +44,82 @@ public class AccountsControllerTest : IClassFixture<ApiApplicationFactory>
|
|||||||
Assert.Null(content.PrivateKey);
|
Assert.Null(content.PrivateKey);
|
||||||
Assert.NotNull(content.SecurityStamp);
|
Assert.NotNull(content.SecurityStamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostEmailToken_WhenAccountDeprovisioningEnabled_WithManagedAccount_ThrowsBadRequest()
|
||||||
|
{
|
||||||
|
var email = await SetupOrganizationManagedAccount();
|
||||||
|
|
||||||
|
var tokens = await _factory.LoginAsync(email);
|
||||||
|
var client = _factory.CreateClient();
|
||||||
|
|
||||||
|
var model = new EmailTokenRequestModel
|
||||||
|
{
|
||||||
|
NewEmail = $"{Guid.NewGuid()}@example.com",
|
||||||
|
MasterPasswordHash = "master_password_hash"
|
||||||
|
};
|
||||||
|
|
||||||
|
using var message = new HttpRequestMessage(HttpMethod.Post, "/accounts/email-token")
|
||||||
|
{
|
||||||
|
Content = JsonContent.Create(model)
|
||||||
|
};
|
||||||
|
message.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.Token);
|
||||||
|
var response = await client.SendAsync(message);
|
||||||
|
|
||||||
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Contains("Cannot change emails for accounts owned by an organization", content);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostEmail_WhenAccountDeprovisioningEnabled_WithManagedAccount_ThrowsBadRequest()
|
||||||
|
{
|
||||||
|
var email = await SetupOrganizationManagedAccount();
|
||||||
|
|
||||||
|
var tokens = await _factory.LoginAsync(email);
|
||||||
|
var client = _factory.CreateClient();
|
||||||
|
|
||||||
|
var model = new EmailRequestModel
|
||||||
|
{
|
||||||
|
NewEmail = $"{Guid.NewGuid()}@example.com",
|
||||||
|
MasterPasswordHash = "master_password_hash",
|
||||||
|
NewMasterPasswordHash = "master_password_hash",
|
||||||
|
Token = "validtoken",
|
||||||
|
Key = "key"
|
||||||
|
};
|
||||||
|
|
||||||
|
using var message = new HttpRequestMessage(HttpMethod.Post, "/accounts/email")
|
||||||
|
{
|
||||||
|
Content = JsonContent.Create(model)
|
||||||
|
};
|
||||||
|
message.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.Token);
|
||||||
|
var response = await client.SendAsync(message);
|
||||||
|
|
||||||
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Contains("Cannot change emails for accounts owned by an organization", content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> SetupOrganizationManagedAccount()
|
||||||
|
{
|
||||||
|
_factory.SubstituteService<IFeatureService>(featureService =>
|
||||||
|
featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true));
|
||||||
|
|
||||||
|
// Create the owner account
|
||||||
|
var ownerEmail = $"{Guid.NewGuid()}@bitwarden.com";
|
||||||
|
await _factory.LoginWithNewAccount(ownerEmail);
|
||||||
|
|
||||||
|
// Create the organization
|
||||||
|
var (_organization, _) = await OrganizationTestHelpers.SignUpAsync(_factory, plan: PlanType.EnterpriseAnnually2023,
|
||||||
|
ownerEmail: ownerEmail, passwordManagerSeats: 10, paymentMethod: PaymentMethodType.Card);
|
||||||
|
|
||||||
|
// Create a new organization member
|
||||||
|
var (email, orgUser) = await OrganizationTestHelpers.CreateNewUserWithAccountAsync(_factory, _organization.Id,
|
||||||
|
OrganizationUserType.Custom, new Permissions { AccessReports = true, ManageScim = true });
|
||||||
|
|
||||||
|
// Add a verified domain
|
||||||
|
await OrganizationTestHelpers.CreateVerifiedDomainAsync(_factory, _organization.Id, "bitwarden.com");
|
||||||
|
|
||||||
|
return email;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,4 +105,22 @@ public static class OrganizationTestHelpers
|
|||||||
|
|
||||||
return (email, organizationUser);
|
return (email, organizationUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a VerifiedDomain for the specified organization.
|
||||||
|
/// </summary>
|
||||||
|
public static async Task CreateVerifiedDomainAsync(ApiApplicationFactory factory, Guid organizationId, string domain)
|
||||||
|
{
|
||||||
|
var organizationDomainRepository = factory.GetService<IOrganizationDomainRepository>();
|
||||||
|
|
||||||
|
var verifiedDomain = new OrganizationDomain
|
||||||
|
{
|
||||||
|
OrganizationId = organizationId,
|
||||||
|
DomainName = domain,
|
||||||
|
Txt = "btw+test18383838383"
|
||||||
|
};
|
||||||
|
verifiedDomain.SetVerifiedDate();
|
||||||
|
|
||||||
|
await organizationDomainRepository.CreateAsync(verifiedDomain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using Bit.Api.Auth.Models.Request.WebAuthn;
|
|||||||
using Bit.Api.Auth.Validators;
|
using Bit.Api.Auth.Validators;
|
||||||
using Bit.Api.Tools.Models.Request;
|
using Bit.Api.Tools.Models.Request;
|
||||||
using Bit.Api.Vault.Models.Request;
|
using Bit.Api.Vault.Models.Request;
|
||||||
|
using Bit.Core;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
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;
|
||||||
@ -143,6 +144,21 @@ public class AccountsControllerTests : IDisposable
|
|||||||
await _userService.Received(1).InitiateEmailChangeAsync(user, newEmail);
|
await _userService.Received(1).InitiateEmailChangeAsync(user, newEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostEmailToken_WithAccountDeprovisioningEnabled_WhenUserIsNotManagedByAnOrganization_ShouldInitiateEmailChange()
|
||||||
|
{
|
||||||
|
var user = GenerateExampleUser();
|
||||||
|
ConfigureUserServiceToReturnValidPrincipalFor(user);
|
||||||
|
ConfigureUserServiceToAcceptPasswordFor(user);
|
||||||
|
_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true);
|
||||||
|
_userService.IsManagedByAnyOrganizationAsync(user.Id).Returns(false);
|
||||||
|
var newEmail = "example@user.com";
|
||||||
|
|
||||||
|
await _sut.PostEmailToken(new EmailTokenRequestModel { NewEmail = newEmail });
|
||||||
|
|
||||||
|
await _userService.Received(1).InitiateEmailChangeAsync(user, newEmail);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PostEmailToken_WhenNotAuthorized_ShouldThrowUnauthorizedAccessException()
|
public async Task PostEmailToken_WhenNotAuthorized_ShouldThrowUnauthorizedAccessException()
|
||||||
{
|
{
|
||||||
@ -165,6 +181,22 @@ public class AccountsControllerTests : IDisposable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostEmailToken_WithAccountDeprovisioningEnabled_WhenUserIsManagedByAnOrganization_ShouldThrowBadRequestException()
|
||||||
|
{
|
||||||
|
var user = GenerateExampleUser();
|
||||||
|
ConfigureUserServiceToReturnValidPrincipalFor(user);
|
||||||
|
ConfigureUserServiceToAcceptPasswordFor(user);
|
||||||
|
_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true);
|
||||||
|
_userService.IsManagedByAnyOrganizationAsync(user.Id).Returns(true);
|
||||||
|
|
||||||
|
var result = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
|
() => _sut.PostEmailToken(new EmailTokenRequestModel())
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.Equal("Cannot change emails for accounts owned by an organization. Contact your organization administrator for additional details.", result.Message);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PostEmail_ShouldChangeUserEmail()
|
public async Task PostEmail_ShouldChangeUserEmail()
|
||||||
{
|
{
|
||||||
@ -178,6 +210,21 @@ public class AccountsControllerTests : IDisposable
|
|||||||
await _userService.Received(1).ChangeEmailAsync(user, default, default, default, default, default);
|
await _userService.Received(1).ChangeEmailAsync(user, default, default, default, default, default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostEmail_WithAccountDeprovisioningEnabled_WhenUserIsNotManagedByAnOrganization_ShouldChangeUserEmail()
|
||||||
|
{
|
||||||
|
var user = GenerateExampleUser();
|
||||||
|
ConfigureUserServiceToReturnValidPrincipalFor(user);
|
||||||
|
_userService.ChangeEmailAsync(user, default, default, default, default, default)
|
||||||
|
.Returns(Task.FromResult(IdentityResult.Success));
|
||||||
|
_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true);
|
||||||
|
_userService.IsManagedByAnyOrganizationAsync(user.Id).Returns(false);
|
||||||
|
|
||||||
|
await _sut.PostEmail(new EmailRequestModel());
|
||||||
|
|
||||||
|
await _userService.Received(1).ChangeEmailAsync(user, default, default, default, default, default);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PostEmail_WhenNotAuthorized_ShouldThrownUnauthorizedAccessException()
|
public async Task PostEmail_WhenNotAuthorized_ShouldThrownUnauthorizedAccessException()
|
||||||
{
|
{
|
||||||
@ -201,6 +248,21 @@ public class AccountsControllerTests : IDisposable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostEmail_WithAccountDeprovisioningEnabled_WhenUserIsManagedByAnOrganization_ShouldThrowBadRequestException()
|
||||||
|
{
|
||||||
|
var user = GenerateExampleUser();
|
||||||
|
ConfigureUserServiceToReturnValidPrincipalFor(user);
|
||||||
|
_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true);
|
||||||
|
_userService.IsManagedByAnyOrganizationAsync(user.Id).Returns(true);
|
||||||
|
|
||||||
|
var result = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
|
() => _sut.PostEmail(new EmailRequestModel())
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.Equal("Cannot change emails for accounts owned by an organization. Contact your organization administrator for additional details.", result.Message);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PostVerifyEmail_ShouldSendEmailVerification()
|
public async Task PostVerifyEmail_ShouldSendEmailVerification()
|
||||||
{
|
{
|
||||||
|
@ -3,8 +3,10 @@ using System.Text.Json;
|
|||||||
using Bit.Api.AdminConsole.Controllers;
|
using Bit.Api.AdminConsole.Controllers;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Api.Response;
|
||||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
@ -132,4 +134,71 @@ public class PoliciesControllerTests
|
|||||||
// Act & Assert
|
// Act & Assert
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetMasterPasswordPolicy(orgId));
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetMasterPasswordPolicy(orgId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData]
|
||||||
|
public async Task Get_WhenUserCanManagePolicies_WithExistingType_ReturnsExistingPolicy(
|
||||||
|
SutProvider<PoliciesController> sutProvider, Guid orgId, Policy policy, int type)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
sutProvider.GetDependency<ICurrentContext>()
|
||||||
|
.ManagePolicies(orgId)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
policy.Type = (PolicyType)type;
|
||||||
|
policy.Enabled = true;
|
||||||
|
policy.Data = null;
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IPolicyRepository>()
|
||||||
|
.GetByOrganizationIdTypeAsync(orgId, (PolicyType)type)
|
||||||
|
.Returns(policy);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await sutProvider.Sut.Get(orgId, type);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<PolicyResponseModel>(result);
|
||||||
|
Assert.Equal(policy.Id, result.Id);
|
||||||
|
Assert.Equal(policy.Type, result.Type);
|
||||||
|
Assert.Equal(policy.Enabled, result.Enabled);
|
||||||
|
Assert.Equal(policy.OrganizationId, result.OrganizationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData]
|
||||||
|
public async Task Get_WhenUserCanManagePolicies_WithNonExistingType_ReturnsDefaultPolicy(
|
||||||
|
SutProvider<PoliciesController> sutProvider, Guid orgId, int type)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
sutProvider.GetDependency<ICurrentContext>()
|
||||||
|
.ManagePolicies(orgId)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IPolicyRepository>()
|
||||||
|
.GetByOrganizationIdTypeAsync(orgId, (PolicyType)type)
|
||||||
|
.Returns((Policy)null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await sutProvider.Sut.Get(orgId, type);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<PolicyResponseModel>(result);
|
||||||
|
Assert.Equal(result.Type, (PolicyType)type);
|
||||||
|
Assert.False(result.Enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[BitAutoData]
|
||||||
|
public async Task Get_WhenUserCannotManagePolicies_ThrowsNotFoundException(
|
||||||
|
SutProvider<PoliciesController> sutProvider, Guid orgId, int type)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
sutProvider.GetDependency<ICurrentContext>()
|
||||||
|
.ManagePolicies(orgId)
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.Get(orgId, type));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
||||||
<PackageReference Include="NSubstitute" Version="$(NSubstituteVersion)" />
|
<PackageReference Include="NSubstitute" Version="$(NSubstituteVersion)" />
|
||||||
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.9.1" />
|
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.10.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
|
||||||
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitRunnerVisualStudioVersion)">
|
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitRunnerVisualStudioVersion)">
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="DbScripts\**\*.sql" />
|
<EmbeddedResource Include="DbScripts\**\*.sql" />
|
||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="dbup-sqlserver" Version="5.0.41" />
|
<PackageReference Include="dbup-sqlserver" Version="5.0.41" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Migrator\Migrator.csproj" />
|
<ProjectReference Include="..\Migrator\Migrator.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommandDotNet" Version="7.0.4" />
|
<PackageReference Include="CommandDotNet" Version="7.0.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Handlebars.Net" Version="2.1.6" />
|
<PackageReference Include="Handlebars.Net" Version="2.1.6" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
<PackageReference Include="YamlDotNet" Version="11.2.1" />
|
<PackageReference Include="YamlDotNet" Version="11.2.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user