using System.Security.Claims; using Bit.Api.AdminConsole.Controllers; using Bit.Api.AdminConsole.Models.Request; using Bit.Api.Vault.AuthorizationHandlers.Collections; using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Exceptions; using Bit.Core.Models.Data; using Bit.Core.Models.Data.Organizations; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Microsoft.AspNetCore.Authorization; using NSubstitute; using Xunit; namespace Bit.Api.Test.AdminConsole.Controllers; [ControllerCustomize(typeof(GroupsController))] [SutProviderCustomize] public class GroupsControllerTests { [Theory] [BitAutoData] public async Task Post_AuthorizedToGiveAccessToCollections_Success(Organization organization, GroupRequestModel groupRequestModel, SutProvider sutProvider) { // Enable FC sutProvider.GetDependency().GetOrganizationAbilityAsync(organization.Id).Returns( new OrganizationAbility { Id = organization.Id, AllowAdminAccessToAllCollectionItems = false }); sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), Arg.Any>(), Arg.Is>(reqs => reqs.Contains(BulkCollectionOperations.ModifyGroupAccess))) .Returns(AuthorizationResult.Success()); sutProvider.GetDependency().GetByIdAsync(organization.Id).Returns(organization); sutProvider.GetDependency().ManageGroups(organization.Id).Returns(true); var response = await sutProvider.Sut.Post(organization.Id, groupRequestModel); var requestModelCollectionIds = groupRequestModel.Collections.Select(c => c.Id).ToHashSet(); // Assert that it checked permissions await sutProvider.GetDependency().Received(1).ManageGroups(organization.Id); await sutProvider.GetDependency() .Received(1) .AuthorizeAsync(Arg.Any(), Arg.Is>(collections => collections.All(c => requestModelCollectionIds.Contains(c.Id))), Arg.Is>(reqs => reqs.Single() == BulkCollectionOperations.ModifyGroupAccess)); // Assert that it saved the data await sutProvider.GetDependency().Received(1).CreateGroupAsync( Arg.Is(g => g.OrganizationId == organization.Id && g.Name == groupRequestModel.Name), organization, Arg.Is>(access => access.All(c => requestModelCollectionIds.Contains(c.Id))), Arg.Any>()); Assert.Equal(groupRequestModel.Name, response.Name); Assert.Equal(organization.Id, response.OrganizationId); } [Theory] [BitAutoData] public async Task Post_NotAuthorizedToGiveAccessToCollections_Throws(Organization organization, GroupRequestModel groupRequestModel, SutProvider sutProvider) { // Enable FC sutProvider.GetDependency().GetOrganizationAbilityAsync(organization.Id).Returns( new OrganizationAbility { Id = organization.Id, AllowAdminAccessToAllCollectionItems = false }); sutProvider.GetDependency().GetByIdAsync(organization.Id).Returns(organization); sutProvider.GetDependency().ManageGroups(organization.Id).Returns(true); var requestModelCollectionIds = groupRequestModel.Collections.Select(c => c.Id).ToHashSet(); sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), Arg.Is>(collections => collections.All(c => requestModelCollectionIds.Contains(c.Id))), Arg.Is>(reqs => reqs.Contains(BulkCollectionOperations.ModifyGroupAccess))) .Returns(AuthorizationResult.Failed()); await Assert.ThrowsAsync(() => sutProvider.Sut.Post(organization.Id, groupRequestModel)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateGroupAsync(default, default, default, default); } }