1
0
mirror of https://github.com/bitwarden/server synced 2026-01-14 22:43:19 +00:00

Merge branch 'main' into tools/pm-21918/send-authentication-commands

This commit is contained in:
✨ Audrey ✨
2025-08-25 14:55:45 -04:00
176 changed files with 14667 additions and 1455 deletions

View File

@@ -2,7 +2,6 @@
using Bit.Api.Billing.Models.Requests;
using Bit.Api.Billing.Models.Responses;
using Bit.Commercial.Core.Billing.Providers.Services;
using Bit.Core;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Enums.Provider;
using Bit.Core.AdminConsole.Repositories;
@@ -346,9 +345,6 @@ public class ProviderBillingControllerTests
}
};
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.PM21383_GetProviderPriceFromStripe)
.Returns(true);
sutProvider.GetDependency<IProviderPlanRepository>().GetByProviderId(provider.Id).Returns(providerPlans);
foreach (var providerPlan in providerPlans)

View File

@@ -22,7 +22,7 @@ namespace Bit.Api.Test.Controllers;
public class CollectionsControllerTests
{
[Theory, BitAutoData]
public async Task Post_Success(Organization organization, CollectionRequestModel collectionRequest,
public async Task Post_Success(Organization organization, CreateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
Collection ExpectedCollection() => Arg.Is<Collection>(c =>
@@ -46,9 +46,10 @@ public class CollectionsControllerTests
}
[Theory, BitAutoData]
public async Task Put_Success(Collection collection, CollectionRequestModel collectionRequest,
public async Task Put_Success(Collection collection, UpdateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
collection.DefaultUserCollectionEmail = null;
Collection ExpectedCollection() => Arg.Is<Collection>(c => c.Id == collection.Id &&
c.Name == collectionRequest.Name && c.ExternalId == collectionRequest.ExternalId &&
c.OrganizationId == collection.OrganizationId);
@@ -72,7 +73,7 @@ public class CollectionsControllerTests
}
[Theory, BitAutoData]
public async Task Put_WithNoCollectionPermission_ThrowsNotFound(Collection collection, CollectionRequestModel collectionRequest,
public async Task Put_WithNoCollectionPermission_ThrowsNotFound(Collection collection, UpdateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
sutProvider.GetDependency<IAuthorizationService>()
@@ -484,4 +485,176 @@ public class CollectionsControllerTests
await sutProvider.GetDependency<IBulkAddCollectionAccessCommand>().DidNotReceiveWithAnyArgs()
.AddAccessAsync(default, default, default);
}
[Theory, BitAutoData]
public async Task Put_With_NonNullName_DoesNotPreserveExistingName(Collection existingCollection, UpdateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
// Arrange
var newName = "new name";
var originalName = "original name";
existingCollection.Name = originalName;
existingCollection.DefaultUserCollectionEmail = null;
collectionRequest.Name = newName;
sutProvider.GetDependency<ICollectionRepository>()
.GetByIdAsync(existingCollection.Id)
.Returns(existingCollection);
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(),
existingCollection,
Arg.Is<IEnumerable<IAuthorizationRequirement>>(r => r.Contains(BulkCollectionOperations.Update)))
.Returns(AuthorizationResult.Success());
// Act
await sutProvider.Sut.Put(existingCollection.OrganizationId, existingCollection.Id, collectionRequest);
// Assert
await sutProvider.GetDependency<IUpdateCollectionCommand>()
.Received(1)
.UpdateAsync(
Arg.Is<Collection>(c => c.Id == existingCollection.Id && c.Name == newName),
Arg.Any<IEnumerable<CollectionAccessSelection>>(),
Arg.Any<IEnumerable<CollectionAccessSelection>>());
}
[Theory, BitAutoData]
public async Task Put_WithNullName_DoesPreserveExistingName(Collection existingCollection, UpdateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
// Arrange
var originalName = "original name";
existingCollection.Name = originalName;
existingCollection.DefaultUserCollectionEmail = null;
collectionRequest.Name = null;
sutProvider.GetDependency<ICollectionRepository>()
.GetByIdAsync(existingCollection.Id)
.Returns(existingCollection);
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(),
existingCollection,
Arg.Is<IEnumerable<IAuthorizationRequirement>>(r => r.Contains(BulkCollectionOperations.Update)))
.Returns(AuthorizationResult.Success());
// Act
await sutProvider.Sut.Put(existingCollection.OrganizationId, existingCollection.Id, collectionRequest);
// Assert
await sutProvider.GetDependency<IUpdateCollectionCommand>()
.Received(1)
.UpdateAsync(
Arg.Is<Collection>(c => c.Id == existingCollection.Id && c.Name == originalName),
Arg.Any<IEnumerable<CollectionAccessSelection>>(),
Arg.Any<IEnumerable<CollectionAccessSelection>>());
}
[Theory, BitAutoData]
public async Task Put_WithDefaultUserCollectionEmail_DoesPreserveExistingName(Collection existingCollection, UpdateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
// Arrange
var originalName = "original name";
var defaultUserCollectionEmail = "user@email.com";
existingCollection.Name = originalName;
existingCollection.DefaultUserCollectionEmail = defaultUserCollectionEmail;
collectionRequest.Name = "new name";
sutProvider.GetDependency<ICollectionRepository>()
.GetByIdAsync(existingCollection.Id)
.Returns(existingCollection);
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(),
existingCollection,
Arg.Is<IEnumerable<IAuthorizationRequirement>>(r => r.Contains(BulkCollectionOperations.Update)))
.Returns(AuthorizationResult.Success());
// Act
await sutProvider.Sut.Put(existingCollection.OrganizationId, existingCollection.Id, collectionRequest);
// Assert
await sutProvider.GetDependency<IUpdateCollectionCommand>()
.Received(1)
.UpdateAsync(
Arg.Is<Collection>(c => c.Id == existingCollection.Id && c.Name == originalName && c.DefaultUserCollectionEmail == defaultUserCollectionEmail),
Arg.Any<IEnumerable<CollectionAccessSelection>>(),
Arg.Any<IEnumerable<CollectionAccessSelection>>());
}
[Theory, BitAutoData]
public async Task Put_WithEmptyName_DoesPreserveExistingName(Collection existingCollection, UpdateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
// Arrange
var originalName = "original name";
existingCollection.Name = originalName;
existingCollection.DefaultUserCollectionEmail = null;
collectionRequest.Name = ""; // Empty string
sutProvider.GetDependency<ICollectionRepository>()
.GetByIdAsync(existingCollection.Id)
.Returns(existingCollection);
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(),
existingCollection,
Arg.Is<IEnumerable<IAuthorizationRequirement>>(r => r.Contains(BulkCollectionOperations.Update)))
.Returns(AuthorizationResult.Success());
// Act
await sutProvider.Sut.Put(existingCollection.OrganizationId, existingCollection.Id, collectionRequest);
// Assert
await sutProvider.GetDependency<IUpdateCollectionCommand>()
.Received(1)
.UpdateAsync(
Arg.Is<Collection>(c => c.Id == existingCollection.Id && c.Name == originalName),
Arg.Any<IEnumerable<CollectionAccessSelection>>(),
Arg.Any<IEnumerable<CollectionAccessSelection>>());
}
[Theory, BitAutoData]
public async Task Put_WithWhitespaceOnlyName_DoesPreserveExistingName(Collection existingCollection, UpdateCollectionRequestModel collectionRequest,
SutProvider<CollectionsController> sutProvider)
{
// Arrange
var originalName = "original name";
existingCollection.Name = originalName;
existingCollection.DefaultUserCollectionEmail = null;
collectionRequest.Name = " "; // Whitespace only
sutProvider.GetDependency<ICollectionRepository>()
.GetByIdAsync(existingCollection.Id)
.Returns(existingCollection);
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(),
existingCollection,
Arg.Is<IEnumerable<IAuthorizationRequirement>>(r => r.Contains(BulkCollectionOperations.Update)))
.Returns(AuthorizationResult.Success());
// Act
await sutProvider.Sut.Put(existingCollection.OrganizationId, existingCollection.Id, collectionRequest);
// Assert
await sutProvider.GetDependency<IUpdateCollectionCommand>()
.Received(1)
.UpdateAsync(
Arg.Is<Collection>(c => c.Id == existingCollection.Id && c.Name == originalName),
Arg.Any<IEnumerable<CollectionAccessSelection>>(),
Arg.Any<IEnumerable<CollectionAccessSelection>>());
}
}

View File

@@ -317,7 +317,7 @@ public class ProjectsControllerTests
[Theory]
[BitAutoData]
public async Task BulkDeleteProjects_ReturnsAccessDeniedForProjectsWithoutAccess_Success(
SutProvider<ProjectsController> sutProvider, List<Project> data)
SutProvider<ProjectsController> sutProvider, Guid userId, List<Project> data)
{
var ids = data.Select(project => project.Id).ToList();
@@ -333,6 +333,7 @@ public class ProjectsControllerTests
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), data.First(),
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).Returns(AuthorizationResult.Failed());
sutProvider.GetDependency<IUserService>().GetProperUserId(default).ReturnsForAnyArgs(userId);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId)).ReturnsForAnyArgs(true);
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
var results = await sutProvider.Sut.BulkDeleteAsync(ids);
@@ -346,7 +347,7 @@ public class ProjectsControllerTests
[Theory]
[BitAutoData]
public async Task BulkDeleteProjects_Success(SutProvider<ProjectsController> sutProvider, List<Project> data)
public async Task BulkDeleteProjects_Success(SutProvider<ProjectsController> sutProvider, Guid userId, List<Project> data)
{
var ids = data.Select(project => project.Id).ToList();
var organizationId = data.First().OrganizationId;
@@ -357,7 +358,7 @@ public class ProjectsControllerTests
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), project,
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).ReturnsForAnyArgs(AuthorizationResult.Success());
}
sutProvider.GetDependency<IUserService>().GetProperUserId(default).ReturnsForAnyArgs(userId);
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId)).ReturnsForAnyArgs(true);