using Bit.Core.AdminConsole.Entities; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Business; using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Scim.Models; using Bit.Scim.Users; using Bit.Scim.Utilities; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using NSubstitute; using Xunit; namespace Bit.Scim.Test.Users; [SutProviderCustomize] public class PostUserCommandTests { [Theory] [BitAutoData] public async Task PostUser_Success(SutProvider sutProvider, string externalId, Guid organizationId, List emails, ICollection organizationUsers, Core.Entities.OrganizationUser newUser, Organization organization) { var scimUserRequestModel = new ScimUserRequestModel { ExternalId = externalId, Emails = emails, Active = true, Schemas = new List { ScimConstants.Scim2SchemaUser } }; sutProvider.GetDependency() .GetManyDetailsByOrganizationAsync(organizationId) .Returns(organizationUsers); sutProvider.GetDependency().GetByIdAsync(organizationId).Returns(organization); sutProvider.GetDependency().HasSecretsManagerStandalone(organization).Returns(true); sutProvider.GetDependency() .InviteUserAsync(organizationId, invitingUserId: null, EventSystemUser.SCIM, Arg.Is(i => i.Emails.Single().Equals(scimUserRequestModel.PrimaryEmail.ToLowerInvariant()) && i.Type == OrganizationUserType.User && !i.Collections.Any() && !i.Groups.Any() && i.AccessSecretsManager), externalId) .Returns(newUser); var user = await sutProvider.Sut.PostUserAsync(organizationId, scimUserRequestModel); await sutProvider.GetDependency().Received(1).InviteUserAsync(organizationId, invitingUserId: null, EventSystemUser.SCIM, Arg.Is(i => i.Emails.Single().Equals(scimUserRequestModel.PrimaryEmail.ToLowerInvariant()) && i.Type == OrganizationUserType.User && !i.Collections.Any() && !i.Groups.Any() && i.AccessSecretsManager), externalId); await sutProvider.GetDependency().Received(1).GetDetailsByIdAsync(newUser.Id); } [Theory] [BitAutoData] public async Task PostUser_NullEmail_Throws(SutProvider sutProvider, Guid organizationId) { var scimUserRequestModel = new ScimUserRequestModel { Emails = new List(), Active = true, Schemas = new List { ScimConstants.Scim2SchemaUser } }; await Assert.ThrowsAsync(async () => await sutProvider.Sut.PostUserAsync(organizationId, scimUserRequestModel)); } [Theory] [BitAutoData] public async Task PostUser_Inactive_Throws(SutProvider sutProvider, Guid organizationId, List emails) { var scimUserRequestModel = new ScimUserRequestModel { Emails = emails, Active = false, Schemas = new List { ScimConstants.Scim2SchemaUser } }; await Assert.ThrowsAsync(async () => await sutProvider.Sut.PostUserAsync(organizationId, scimUserRequestModel)); } [Theory] [BitAutoData] public async Task PostUser_DuplicateExternalId_Throws(SutProvider sutProvider, Guid organizationId, List emails, ICollection organizationUsers) { var scimUserRequestModel = new ScimUserRequestModel { ExternalId = organizationUsers.First().ExternalId, Emails = emails, Active = true, Schemas = new List { ScimConstants.Scim2SchemaUser } }; sutProvider.GetDependency() .GetManyDetailsByOrganizationAsync(organizationId) .Returns(organizationUsers); await Assert.ThrowsAsync(async () => await sutProvider.Sut.PostUserAsync(organizationId, scimUserRequestModel)); } [Theory] [BitAutoData] public async Task PostUser_DuplicateUserName_Throws(SutProvider sutProvider, Guid organizationId, List emails, ICollection organizationUsers) { var scimUserRequestModel = new ScimUserRequestModel { UserName = organizationUsers.First().ExternalId, Emails = emails, Active = true, Schemas = new List { ScimConstants.Scim2SchemaUser } }; sutProvider.GetDependency() .GetManyDetailsByOrganizationAsync(organizationId) .Returns(organizationUsers); await Assert.ThrowsAsync(async () => await sutProvider.Sut.PostUserAsync(organizationId, scimUserRequestModel)); } }