1
0
mirror of https://github.com/bitwarden/server.git synced 2025-02-07 00:21:32 +01:00

Merge branch 'main' into brant/azure-service-bus

This commit is contained in:
Brant DeBow 2025-02-06 17:42:16 -05:00
commit 31904b9358
No known key found for this signature in database
GPG Key ID: 94411BB25947C72B
22 changed files with 167 additions and 132 deletions

View File

@ -64,7 +64,6 @@
"Braintree",
"coverlet.collector",
"CsvHelper",
"FluentAssertions",
"Kralizek.AutoFixture.Extensions.MockHttp",
"Microsoft.AspNetCore.Mvc.Testing",
"Microsoft.Extensions.Logging",

View File

@ -8,6 +8,11 @@
<RootNamespace>Bit.$(MSBuildProjectName)</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<!-- Treat it as a test project if the project hasn't set their own value and it follows our test project conventions -->
<IsTestProject Condition="'$(IsTestProject)' == '' and ($(MSBuildProjectName.EndsWith('.Test')) or $(MSBuildProjectName.EndsWith('.IntegrationTest')))">true</IsTestProject>
<Nullable Condition="'$(Nullable)' == '' and '$(IsTestProject)' == 'true'">annotations</Nullable>
<!-- Uncomment the below line when we are ready to enable nullable repo wide -->
<!-- <Nullable Condition="'$(Nullable)' == '' and '$(IsTestProject)' != 'true'">enable</Nullable> -->
</PropertyGroup>
<!--

View File

@ -248,7 +248,7 @@ public class GroupsControllerTests : IClassFixture<ScimApplicationFactory>, IAsy
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public async Task Post_InvalidDisplayName_BadRequest(string displayName)
public async Task Post_InvalidDisplayName_BadRequest(string? displayName)
{
var organizationId = ScimApplicationFactory.TestOrganizationId1;
var model = new ScimGroupRequestModel

View File

@ -324,7 +324,7 @@ public class UsersControllerTests : IClassFixture<ScimApplicationFactory>, IAsyn
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public async Task Post_InvalidEmail_BadRequest(string email)
public async Task Post_InvalidEmail_BadRequest(string? email)
{
var displayName = "Test User 5";
var externalId = "UE";

View File

@ -266,8 +266,18 @@ public class AccountsController : Controller
throw new UnauthorizedAccessException();
}
try
{
user = model.ToUser(user);
}
catch (Exception e)
{
ModelState.AddModelError(string.Empty, e.Message);
throw new BadRequestException(ModelState);
}
var result = await _setInitialMasterPasswordCommand.SetInitialMasterPasswordAsync(
model.ToUser(user),
user,
model.MasterPasswordHash,
model.Key,
model.OrgIdentifier);
@ -974,7 +984,6 @@ public class AccountsController : Controller
await _userService.ResendNewDeviceVerificationEmail(request.Email, request.Secret);
}
[RequireFeature(FeatureFlagKeys.NewDeviceVerification)]
[HttpPost("verify-devices")]
[HttpPut("verify-devices")]
public async Task SetUserVerifyDevicesAsync([FromBody] SetVerifyDevicesRequestModel request)

View File

@ -1,26 +1,36 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Entities;
using Bit.Core.Utilities;
namespace Bit.Core.Auth.Models.Api.Request.Accounts;
public class KeysRequestModel
{
[Required]
public string PublicKey { get; set; }
[Required]
public string EncryptedPrivateKey { get; set; }
public User ToUser(User existingUser)
{
if (string.IsNullOrWhiteSpace(existingUser.PublicKey) && !string.IsNullOrWhiteSpace(PublicKey))
if (string.IsNullOrWhiteSpace(PublicKey) || string.IsNullOrWhiteSpace(EncryptedPrivateKey))
{
throw new InvalidOperationException("Public and private keys are required.");
}
if (string.IsNullOrWhiteSpace(existingUser.PublicKey) && string.IsNullOrWhiteSpace(existingUser.PrivateKey))
{
existingUser.PublicKey = PublicKey;
}
if (string.IsNullOrWhiteSpace(existingUser.PrivateKey))
{
existingUser.PrivateKey = EncryptedPrivateKey;
return existingUser;
}
else if (PublicKey == existingUser.PublicKey && CoreHelpers.FixedTimeEquals(EncryptedPrivateKey, existingUser.PrivateKey))
{
return existingUser;
}
else
{
throw new InvalidOperationException("Cannot replace existing key(s) with new key(s).");
}
return existingUser;
}
}

View File

@ -1,6 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@ -419,22 +419,32 @@ public class AccountsControllerTests : IDisposable
[Theory]
[BitAutoData(true, false)] // User has PublicKey and PrivateKey, and Keys in request are NOT null
[BitAutoData(true, true)] // User has PublicKey and PrivateKey, and Keys in request are null
[BitAutoData(false, false)] // User has neither PublicKey nor PrivateKey, and Keys in request are NOT null
[BitAutoData(false, true)] // User has neither PublicKey nor PrivateKey, and Keys in request are null
[BitAutoData(true, "existingPrivateKey", "existingPublicKey", true)] // allow providing existing keys in the request
[BitAutoData(true, null, null, true)] // allow not setting the public key when the user already has a key
[BitAutoData(false, "newPrivateKey", "newPublicKey", true)] // allow setting new keys when the user has no keys
[BitAutoData(false, null, null, true)] // allow not setting the public key when the user has no keys
// do not allow single key
[BitAutoData(false, "existingPrivateKey", null, false)]
[BitAutoData(false, null, "existingPublicKey", false)]
[BitAutoData(false, "newPrivateKey", null, false)]
[BitAutoData(false, null, "newPublicKey", false)]
[BitAutoData(true, "existingPrivateKey", null, false)]
[BitAutoData(true, null, "existingPublicKey", false)]
[BitAutoData(true, "newPrivateKey", null, false)]
[BitAutoData(true, null, "newPublicKey", false)]
// reject overwriting existing keys
[BitAutoData(true, "newPrivateKey", "newPublicKey", false)]
public async Task PostSetPasswordAsync_WhenUserExistsAndSettingPasswordSucceeds_ShouldHandleKeysCorrectlyAndReturn(
bool hasExistingKeys,
bool shouldSetKeysToNull,
User user,
SetPasswordRequestModel setPasswordRequestModel)
bool hasExistingKeys,
string requestPrivateKey,
string requestPublicKey,
bool shouldSucceed,
User user,
SetPasswordRequestModel setPasswordRequestModel)
{
// Arrange
const string existingPublicKey = "existingPublicKey";
const string existingEncryptedPrivateKey = "existingEncryptedPrivateKey";
const string newPublicKey = "newPublicKey";
const string newEncryptedPrivateKey = "newEncryptedPrivateKey";
const string existingEncryptedPrivateKey = "existingPrivateKey";
if (hasExistingKeys)
{
@ -447,16 +457,16 @@ public class AccountsControllerTests : IDisposable
user.PrivateKey = null;
}
if (shouldSetKeysToNull)
if (requestPrivateKey == null && requestPublicKey == null)
{
setPasswordRequestModel.Keys = null;
}
else
{
setPasswordRequestModel.Keys = new KeysRequestModel()
setPasswordRequestModel.Keys = new KeysRequestModel
{
PublicKey = newPublicKey,
EncryptedPrivateKey = newEncryptedPrivateKey
EncryptedPrivateKey = requestPrivateKey,
PublicKey = requestPublicKey
};
}
@ -469,44 +479,66 @@ public class AccountsControllerTests : IDisposable
.Returns(Task.FromResult(IdentityResult.Success));
// Act
await _sut.PostSetPasswordAsync(setPasswordRequestModel);
// Assert
await _setInitialMasterPasswordCommand.Received(1)
.SetInitialMasterPasswordAsync(
Arg.Is<User>(u => u == user),
Arg.Is<string>(s => s == setPasswordRequestModel.MasterPasswordHash),
Arg.Is<string>(s => s == setPasswordRequestModel.Key),
Arg.Is<string>(s => s == setPasswordRequestModel.OrgIdentifier));
// Additional Assertions for User object modifications
Assert.Equal(setPasswordRequestModel.MasterPasswordHint, user.MasterPasswordHint);
Assert.Equal(setPasswordRequestModel.Kdf, user.Kdf);
Assert.Equal(setPasswordRequestModel.KdfIterations, user.KdfIterations);
Assert.Equal(setPasswordRequestModel.KdfMemory, user.KdfMemory);
Assert.Equal(setPasswordRequestModel.KdfParallelism, user.KdfParallelism);
Assert.Equal(setPasswordRequestModel.Key, user.Key);
if (hasExistingKeys)
if (shouldSucceed)
{
// User Keys should not be modified
Assert.Equal(existingPublicKey, user.PublicKey);
Assert.Equal(existingEncryptedPrivateKey, user.PrivateKey);
}
else if (!shouldSetKeysToNull)
{
// User had no keys so they should be set to the request model's keys
Assert.Equal(setPasswordRequestModel.Keys.PublicKey, user.PublicKey);
Assert.Equal(setPasswordRequestModel.Keys.EncryptedPrivateKey, user.PrivateKey);
await _sut.PostSetPasswordAsync(setPasswordRequestModel);
// Assert
await _setInitialMasterPasswordCommand.Received(1)
.SetInitialMasterPasswordAsync(
Arg.Is<User>(u => u == user),
Arg.Is<string>(s => s == setPasswordRequestModel.MasterPasswordHash),
Arg.Is<string>(s => s == setPasswordRequestModel.Key),
Arg.Is<string>(s => s == setPasswordRequestModel.OrgIdentifier));
// Additional Assertions for User object modifications
Assert.Equal(setPasswordRequestModel.MasterPasswordHint, user.MasterPasswordHint);
Assert.Equal(setPasswordRequestModel.Kdf, user.Kdf);
Assert.Equal(setPasswordRequestModel.KdfIterations, user.KdfIterations);
Assert.Equal(setPasswordRequestModel.KdfMemory, user.KdfMemory);
Assert.Equal(setPasswordRequestModel.KdfParallelism, user.KdfParallelism);
Assert.Equal(setPasswordRequestModel.Key, user.Key);
}
else
{
// User had no keys and the request model's keys were null, so they should be set to null
Assert.Null(user.PublicKey);
Assert.Null(user.PrivateKey);
await Assert.ThrowsAsync<BadRequestException>(() => _sut.PostSetPasswordAsync(setPasswordRequestModel));
}
}
[Theory]
[BitAutoData]
public async Task PostSetPasswordAsync_WhenUserExistsAndHasKeysAndKeysAreUpdated_ShouldThrowAsync(
User user,
SetPasswordRequestModel setPasswordRequestModel)
{
// Arrange
const string existingPublicKey = "existingPublicKey";
const string existingEncryptedPrivateKey = "existingEncryptedPrivateKey";
const string newPublicKey = "newPublicKey";
const string newEncryptedPrivateKey = "newEncryptedPrivateKey";
user.PublicKey = existingPublicKey;
user.PrivateKey = existingEncryptedPrivateKey;
setPasswordRequestModel.Keys = new KeysRequestModel()
{
PublicKey = newPublicKey,
EncryptedPrivateKey = newEncryptedPrivateKey
};
_userService.GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(Task.FromResult(user));
_setInitialMasterPasswordCommand.SetInitialMasterPasswordAsync(
user,
setPasswordRequestModel.MasterPasswordHash,
setPasswordRequestModel.Key,
setPasswordRequestModel.OrgIdentifier)
.Returns(Task.FromResult(IdentityResult.Success));
// Act & Assert
await Assert.ThrowsAsync<BadRequestException>(() => _sut.PostSetPasswordAsync(setPasswordRequestModel));
}
[Theory]
[BitAutoData]
public async Task PostSetPasswordAsync_WhenUserDoesNotExist_ShouldThrowUnauthorizedAccessException(
@ -525,6 +557,7 @@ public class AccountsControllerTests : IDisposable
User user,
SetPasswordRequestModel model)
{
model.Keys = null;
// Arrange
_userService.GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(Task.FromResult(user));
_setInitialMasterPasswordCommand.SetInitialMasterPasswordAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>())

View File

@ -6,7 +6,6 @@
<ItemGroup>
<PackageReference Include="Divergic.Logging.Xunit" Version="4.3.0" />
<PackageReference Include="FluentAssertions" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
<PackageReference Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageReference Include="xunit" Version="$(XUnitVersion)" />

View File

@ -8,7 +8,6 @@ using Bit.Core.Enums;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Divergic.Logging.Xunit;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
@ -577,14 +576,14 @@ public class PayPalControllerTests
{
var statusCodeActionResult = (IStatusCodeActionResult)result;
statusCodeActionResult.StatusCode.Should().Be(statusCode);
Assert.Equal(statusCode, statusCodeActionResult.StatusCode);
}
private static void Logged(ICacheLogger logger, LogLevel logLevel, string message)
{
logger.Last.Should().NotBeNull();
logger.Last!.LogLevel.Should().Be(logLevel);
logger.Last!.Message.Should().Be(message);
Assert.NotNull(logger.Last);
Assert.Equal(logLevel, logger.Last!.LogLevel);
Assert.Equal(message, logger.Last!.Message);
}
private static void LoggedError(ICacheLogger logger, string message)

View File

@ -2,7 +2,6 @@
using Bit.Billing.Services.Implementations;
using Bit.Billing.Test.Utilities;
using Bit.Core.Settings;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Stripe;
@ -36,10 +35,8 @@ public class StripeEventServiceTests
var function = async () => await _stripeEventService.GetCharge(stripeEvent);
// Assert
await function
.Should()
.ThrowAsync<Exception>()
.WithMessage($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Charge)}'");
var exception = await Assert.ThrowsAsync<Exception>(function);
Assert.Equal($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Charge)}'", exception.Message);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetCharge(
Arg.Any<string>(),
@ -58,7 +55,7 @@ public class StripeEventServiceTests
var charge = await _stripeEventService.GetCharge(stripeEvent);
// Assert
charge.Should().BeEquivalentTo(stripeEvent.Data.Object as Charge);
Assert.Equivalent(stripeEvent.Data.Object as Charge, charge, true);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetCharge(
Arg.Any<string>(),
@ -88,8 +85,8 @@ public class StripeEventServiceTests
var charge = await _stripeEventService.GetCharge(stripeEvent, true, expand);
// Assert
charge.Should().Be(apiCharge);
charge.Should().NotBeSameAs(eventCharge);
Assert.Equal(apiCharge, charge);
Assert.NotSame(eventCharge, charge);
await _stripeFacade.Received().GetCharge(
apiCharge.Id,
@ -110,10 +107,8 @@ public class StripeEventServiceTests
var function = async () => await _stripeEventService.GetCustomer(stripeEvent);
// Assert
await function
.Should()
.ThrowAsync<Exception>()
.WithMessage($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Customer)}'");
var exception = await Assert.ThrowsAsync<Exception>(function);
Assert.Equal($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Customer)}'", exception.Message);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetCustomer(
Arg.Any<string>(),
@ -132,7 +127,7 @@ public class StripeEventServiceTests
var customer = await _stripeEventService.GetCustomer(stripeEvent);
// Assert
customer.Should().BeEquivalentTo(stripeEvent.Data.Object as Customer);
Assert.Equivalent(stripeEvent.Data.Object as Customer, customer, true);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetCustomer(
Arg.Any<string>(),
@ -162,8 +157,8 @@ public class StripeEventServiceTests
var customer = await _stripeEventService.GetCustomer(stripeEvent, true, expand);
// Assert
customer.Should().Be(apiCustomer);
customer.Should().NotBeSameAs(eventCustomer);
Assert.Equal(apiCustomer, customer);
Assert.NotSame(eventCustomer, customer);
await _stripeFacade.Received().GetCustomer(
apiCustomer.Id,
@ -184,10 +179,8 @@ public class StripeEventServiceTests
var function = async () => await _stripeEventService.GetInvoice(stripeEvent);
// Assert
await function
.Should()
.ThrowAsync<Exception>()
.WithMessage($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Invoice)}'");
var exception = await Assert.ThrowsAsync<Exception>(function);
Assert.Equal($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Invoice)}'", exception.Message);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetInvoice(
Arg.Any<string>(),
@ -206,7 +199,7 @@ public class StripeEventServiceTests
var invoice = await _stripeEventService.GetInvoice(stripeEvent);
// Assert
invoice.Should().BeEquivalentTo(stripeEvent.Data.Object as Invoice);
Assert.Equivalent(stripeEvent.Data.Object as Invoice, invoice, true);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetInvoice(
Arg.Any<string>(),
@ -236,8 +229,8 @@ public class StripeEventServiceTests
var invoice = await _stripeEventService.GetInvoice(stripeEvent, true, expand);
// Assert
invoice.Should().Be(apiInvoice);
invoice.Should().NotBeSameAs(eventInvoice);
Assert.Equal(apiInvoice, invoice);
Assert.NotSame(eventInvoice, invoice);
await _stripeFacade.Received().GetInvoice(
apiInvoice.Id,
@ -258,10 +251,8 @@ public class StripeEventServiceTests
var function = async () => await _stripeEventService.GetPaymentMethod(stripeEvent);
// Assert
await function
.Should()
.ThrowAsync<Exception>()
.WithMessage($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(PaymentMethod)}'");
var exception = await Assert.ThrowsAsync<Exception>(function);
Assert.Equal($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(PaymentMethod)}'", exception.Message);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetPaymentMethod(
Arg.Any<string>(),
@ -280,7 +271,7 @@ public class StripeEventServiceTests
var paymentMethod = await _stripeEventService.GetPaymentMethod(stripeEvent);
// Assert
paymentMethod.Should().BeEquivalentTo(stripeEvent.Data.Object as PaymentMethod);
Assert.Equivalent(stripeEvent.Data.Object as PaymentMethod, paymentMethod, true);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetPaymentMethod(
Arg.Any<string>(),
@ -310,8 +301,8 @@ public class StripeEventServiceTests
var paymentMethod = await _stripeEventService.GetPaymentMethod(stripeEvent, true, expand);
// Assert
paymentMethod.Should().Be(apiPaymentMethod);
paymentMethod.Should().NotBeSameAs(eventPaymentMethod);
Assert.Equal(apiPaymentMethod, paymentMethod);
Assert.NotSame(eventPaymentMethod, paymentMethod);
await _stripeFacade.Received().GetPaymentMethod(
apiPaymentMethod.Id,
@ -332,10 +323,8 @@ public class StripeEventServiceTests
var function = async () => await _stripeEventService.GetSubscription(stripeEvent);
// Assert
await function
.Should()
.ThrowAsync<Exception>()
.WithMessage($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Subscription)}'");
var exception = await Assert.ThrowsAsync<Exception>(function);
Assert.Equal($"Stripe event with ID '{stripeEvent.Id}' does not have object matching type '{nameof(Subscription)}'", exception.Message);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetSubscription(
Arg.Any<string>(),
@ -354,7 +343,7 @@ public class StripeEventServiceTests
var subscription = await _stripeEventService.GetSubscription(stripeEvent);
// Assert
subscription.Should().BeEquivalentTo(stripeEvent.Data.Object as Subscription);
Assert.Equivalent(stripeEvent.Data.Object as Subscription, subscription, true);
await _stripeFacade.DidNotReceiveWithAnyArgs().GetSubscription(
Arg.Any<string>(),
@ -384,8 +373,8 @@ public class StripeEventServiceTests
var subscription = await _stripeEventService.GetSubscription(stripeEvent, true, expand);
// Assert
subscription.Should().Be(apiSubscription);
subscription.Should().NotBeSameAs(eventSubscription);
Assert.Equal(apiSubscription, subscription);
Assert.NotSame(eventSubscription, subscription);
await _stripeFacade.Received().GetSubscription(
apiSubscription.Id,
@ -417,7 +406,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetSubscription(
subscription.Id,
@ -447,7 +436,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetCharge(
charge.Id,
@ -475,7 +464,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetCustomer(
invoice.CustomerId,
@ -505,7 +494,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetInvoice(
invoice.Id,
@ -535,7 +524,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetPaymentMethod(
paymentMethod.Id,
@ -561,7 +550,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetCustomer(
customer.Id,
@ -592,7 +581,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeFalse();
Assert.False(cloudRegionValid);
await _stripeFacade.Received(1).GetSubscription(
subscription.Id,
@ -623,7 +612,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetSubscription(
subscription.Id,
@ -657,7 +646,7 @@ public class StripeEventServiceTests
var cloudRegionValid = await _stripeEventService.ValidateCloudRegion(stripeEvent);
// Assert
cloudRegionValid.Should().BeTrue();
Assert.True(cloudRegionValid);
await _stripeFacade.Received(1).GetSubscription(
subscription.Id,

View File

@ -41,8 +41,6 @@ using Xunit;
using Organization = Bit.Core.AdminConsole.Entities.Organization;
using OrganizationUser = Bit.Core.Entities.OrganizationUser;
#nullable enable
namespace Bit.Core.Test.Services;
[SutProviderCustomize]

View File

@ -109,7 +109,7 @@ public class OrgUserInviteTokenableTests
[Theory]
[InlineData(null)]
[InlineData("")]
public void Valid_NullOrEmptyOrgUserEmail_ReturnsFalse(string email)
public void Valid_NullOrEmptyOrgUserEmail_ReturnsFalse(string? email)
{
var token = new OrgUserInviteTokenable
{

View File

@ -271,7 +271,7 @@ public class CoreHelpersTests
[InlineData("ascii.com", "ascii.com")]
[InlineData("", "")]
[InlineData(null, null)]
public void PunyEncode_Success(string text, string expected)
public void PunyEncode_Success(string? text, string? expected)
{
var actual = CoreHelpers.PunyEncode(text);
Assert.Equal(expected, actual);
@ -435,7 +435,7 @@ public class CoreHelpersTests
[InlineData("name@", "name@")] // @ symbol but no domain
[InlineData("", "")] // Empty string
[InlineData(null, null)] // null
public void ObfuscateEmail_Success(string input, string expected)
public void ObfuscateEmail_Success(string? input, string? expected)
{
Assert.Equal(expected, CoreHelpers.ObfuscateEmail(input));
}
@ -456,7 +456,7 @@ public class CoreHelpersTests
[InlineData("user@")]
[InlineData("@example.com")]
[InlineData("user@ex@ample.com")]
public void GetEmailDomain_ReturnsNull(string wrongEmail)
public void GetEmailDomain_ReturnsNull(string? wrongEmail)
{
Assert.Null(CoreHelpers.GetEmailDomain(wrongEmail));
}

View File

@ -25,7 +25,7 @@ public class EncryptedStringAttributeTests
[InlineData("Rsa2048_OaepSha256_HmacSha256_B64.QmFzZTY0UGFydA==|QmFzZTY0UGFydA==")] // Valid Rsa2048_OaepSha256_HmacSha256_B64 as a string
[InlineData("6.QmFzZTY0UGFydA==|QmFzZTY0UGFydA==")] // Valid Rsa2048_OaepSha1_HmacSha256_B64 as a number
[InlineData("Rsa2048_OaepSha1_HmacSha256_B64.QmFzZTY0UGFydA==|QmFzZTY0UGFydA==")]
public void IsValid_ReturnsTrue_WhenValid(string input)
public void IsValid_ReturnsTrue_WhenValid(string? input)
{
var sut = new EncryptedStringAttribute();

View File

@ -47,7 +47,7 @@ public class StrictEmailAttributeTests
[InlineData("hellothere@world.com-")] // domain ending in hyphen
[InlineData("hellö@world.com")] // unicode at end of local-part
[InlineData("héllo@world.com")] // unicode in middle of local-part
public void IsValid_ReturnsFalseWhenInvalid(string email)
public void IsValid_ReturnsFalseWhenInvalid(string? email)
{
var sut = new StrictEmailAddressAttribute();

View File

@ -42,7 +42,7 @@ public class StrictEmailAddressListAttributeTests
[Theory]
[InlineData("single@email.com", false)]
[InlineData(null, false)]
public void IsValid_ReturnsTrue_WhenValid(string email, bool valid)
public void IsValid_ReturnsTrue_WhenValid(string? email, bool valid)
{
var sut = new StrictEmailAddressListAttribute();

View File

@ -3,7 +3,6 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
@ -21,9 +20,9 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Events\Events.csproj" />
<ProjectReference Include="..\IntegrationTestCommon\IntegrationTestCommon.csproj" />
<ItemGroup>
<ProjectReference Include="..\..\src\Events\Events.csproj" />
<ProjectReference Include="..\IntegrationTestCommon\IntegrationTestCommon.csproj" />
</ItemGroup>
</Project>

View File

@ -45,7 +45,7 @@ public class IconLinkTests
[InlineData(" ", false)]
[InlineData("unusable", false)]
[InlineData("ico", true)]
public void WithNoRel_IsUsable(string extension, bool expectedResult)
public void WithNoRel_IsUsable(string? extension, bool expectedResult)
{
SetAttributeValue("href", $"/favicon.{extension}");

View File

@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>

View File

@ -3,8 +3,6 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
@ -22,8 +20,8 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Infrastructure.Dapper\Infrastructure.Dapper.csproj" />
<ItemGroup>
<ProjectReference Include="..\..\src\Infrastructure.Dapper\Infrastructure.Dapper.csproj" />
</ItemGroup>
</Project>

View File

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<UserSecretsId>6570f288-5c2c-47ad-8978-f3da255079c2</UserSecretsId>
</PropertyGroup>