diff --git a/bitwarden_license/src/Commercial.Core/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandler.cs b/bitwarden_license/src/Commercial.Core/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandler.cs index 744942224f..689b4cb0e7 100644 --- a/bitwarden_license/src/Commercial.Core/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandler.cs +++ b/bitwarden_license/src/Commercial.Core/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandler.cs @@ -52,7 +52,7 @@ public class ProjectAuthorizationHandler : AuthorizationHandler true, AccessClientType.User => true, - AccessClientType.ServiceAccount => false, + AccessClientType.ServiceAccount => true, _ => false, }; @@ -67,10 +67,6 @@ public class ProjectAuthorizationHandler : AuthorizationHandler true, AccessClientType.User => (await _projectRepository.AccessToProjectAsync(project!.Id, userId, accessClient)) .Write, - AccessClientType.ServiceAccount => false, + AccessClientType.ServiceAccount => (await _projectRepository.AccessToProjectAsync(project!.Id, userId, accessClient)) + .Write, _ => false, }; @@ -84,6 +85,7 @@ public class SecretAuthorizationHandler : AuthorizationHandler GetAccessToUpdateSecretAsync(Secret resource, Guid userId, AccessClientType accessClient) + { + var newProject = resource.Projects?.FirstOrDefault(); + var access = (await _secretRepository.AccessToSecretAsync(resource.Id, userId, accessClient)).Write; + var accessToNew = newProject != null && + (await _projectRepository.AccessToProjectAsync(newProject.Id, userId, accessClient)) + .Write; + return access && accessToNew; + } } diff --git a/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs b/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs index 91bfc2960b..ad05ffc5ec 100644 --- a/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs +++ b/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs @@ -1,4 +1,7 @@ -using Bit.Core.Repositories; +using Bit.Core.Context; +using Bit.Core.Exceptions; +using Bit.Core.Identity; +using Bit.Core.Repositories; using Bit.Core.SecretsManager.Commands.Projects.Interfaces; using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Repositories; @@ -10,31 +13,58 @@ public class CreateProjectCommand : ICreateProjectCommand private readonly IAccessPolicyRepository _accessPolicyRepository; private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IProjectRepository _projectRepository; + private readonly ICurrentContext _currentContext; + public CreateProjectCommand( IAccessPolicyRepository accessPolicyRepository, IOrganizationUserRepository organizationUserRepository, - IProjectRepository projectRepository) + IProjectRepository projectRepository, + ICurrentContext currentContext) { _accessPolicyRepository = accessPolicyRepository; _organizationUserRepository = organizationUserRepository; _projectRepository = projectRepository; + _currentContext = currentContext; } - public async Task CreateAsync(Project project, Guid userId) + public async Task CreateAsync(Project project, Guid id, ClientType clientType) { + if (clientType != ClientType.User && clientType != ClientType.ServiceAccount) + { + throw new NotFoundException(); + } + var createdProject = await _projectRepository.CreateAsync(project); - var orgUser = await _organizationUserRepository.GetByOrganizationAsync(createdProject.OrganizationId, - userId); - var accessPolicy = new UserProjectAccessPolicy() + if (clientType == ClientType.User) { - OrganizationUserId = orgUser.Id, - GrantedProjectId = createdProject.Id, - Read = true, - Write = true, - }; - await _accessPolicyRepository.CreateManyAsync(new List { accessPolicy }); + var orgUser = await _organizationUserRepository.GetByOrganizationAsync(createdProject.OrganizationId, id); + + var accessPolicy = new UserProjectAccessPolicy() + { + OrganizationUserId = orgUser.Id, + GrantedProjectId = createdProject.Id, + Read = true, + Write = true, + }; + + await _accessPolicyRepository.CreateManyAsync(new List { accessPolicy }); + + } + else if (clientType == ClientType.ServiceAccount) + { + var serviceAccountProjectAccessPolicy = new ServiceAccountProjectAccessPolicy() + { + ServiceAccountId = id, + GrantedProjectId = createdProject.Id, + Read = true, + Write = true, + }; + + await _accessPolicyRepository.CreateManyAsync(new List { serviceAccountProjectAccessPolicy }); + } + return createdProject; } } diff --git a/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/DeleteProjectCommand.cs b/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/DeleteProjectCommand.cs index 35cd19910d..a9f38a24a1 100644 --- a/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/DeleteProjectCommand.cs +++ b/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/DeleteProjectCommand.cs @@ -55,7 +55,7 @@ public class DeleteProjectCommand : IDeleteProjectCommand foreach (var project in projects) { var access = await _projectRepository.AccessToProjectAsync(project.Id, userId, accessClient); - if (!access.Write || accessClient == AccessClientType.ServiceAccount) + if (!access.Write) { results.Add(new Tuple(project, "access denied")); } diff --git a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandlerTests.cs b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandlerTests.cs index 07feb35b88..eb07a34edc 100644 --- a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandlerTests.cs +++ b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Projects/ProjectAuthorizationHandlerTests.cs @@ -39,6 +39,11 @@ public class ProjectAuthorizationHandlerTests .ReturnsForAnyArgs( (AccessClientType.User, userId)); break; + case PermissionType.RunAsServiceAccountWithPermission: + sutProvider.GetDependency().GetAccessClientAsync(default, organizationId) + .ReturnsForAnyArgs( + (AccessClientType.ServiceAccount, userId)); + break; default: throw new ArgumentOutOfRangeException(nameof(permissionType), permissionType, null); } @@ -103,7 +108,6 @@ public class ProjectAuthorizationHandlerTests } [Theory] - [BitAutoData(AccessClientType.ServiceAccount)] [BitAutoData(AccessClientType.Organization)] public async Task CanCreateProject_NotSupportedClientTypes_DoesNotSucceed(AccessClientType clientType, SutProvider sutProvider, Project project, ClaimsPrincipal claimsPrincipal) @@ -125,6 +129,7 @@ public class ProjectAuthorizationHandlerTests [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission)] public async Task CanCreateProject_Success(PermissionType permissionType, SutProvider sutProvider, Project project, ClaimsPrincipal claimsPrincipal) { @@ -199,6 +204,8 @@ public class ProjectAuthorizationHandlerTests [Theory] [BitAutoData(PermissionType.RunAsUserWithPermission, true, false)] [BitAutoData(PermissionType.RunAsUserWithPermission, false, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, false)] public async Task CanUpdateProject_ShouldNotSucceed(PermissionType permissionType, bool read, bool write, SutProvider sutProvider, Project project, ClaimsPrincipal claimsPrincipal, Guid userId) @@ -221,6 +228,8 @@ public class ProjectAuthorizationHandlerTests [BitAutoData(PermissionType.RunAsAdmin, false, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, true, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, false, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, true)] public async Task CanUpdateProject_Success(PermissionType permissionType, bool read, bool write, SutProvider sutProvider, Project project, ClaimsPrincipal claimsPrincipal, Guid userId) diff --git a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Secrets/SecretAuthorizationHandlerTests.cs b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Secrets/SecretAuthorizationHandlerTests.cs index 3e18a83493..682af8b023 100644 --- a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Secrets/SecretAuthorizationHandlerTests.cs +++ b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/AuthorizationHandlers/Secrets/SecretAuthorizationHandlerTests.cs @@ -41,6 +41,10 @@ public class SecretAuthorizationHandlerTests sutProvider.GetDependency().GetAccessClientAsync(default, organizationId).ReturnsForAnyArgs( (clientType, userId)); break; + case PermissionType.RunAsServiceAccountWithPermission: + sutProvider.GetDependency().GetAccessClientAsync(default, organizationId).ReturnsForAnyArgs( + (AccessClientType.ServiceAccount, userId)); + break; default: throw new ArgumentOutOfRangeException(nameof(permissionType), permissionType, null); } @@ -105,7 +109,6 @@ public class SecretAuthorizationHandlerTests } [Theory] - [BitAutoData(AccessClientType.ServiceAccount)] [BitAutoData(AccessClientType.Organization)] public async Task CanCreateSecret_NotSupportedClientTypes_DoesNotSucceed(AccessClientType clientType, SutProvider sutProvider, Secret secret, Guid userId, @@ -114,7 +117,7 @@ public class SecretAuthorizationHandlerTests var requirement = SecretOperations.Create; SetupPermission(sutProvider, PermissionType.RunAsUserWithPermission, secret.OrganizationId, userId, clientType); sutProvider.GetDependency() - .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, default).Returns( + .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, Arg.Any()).Returns( (true, true)); var authzContext = new AuthorizationHandlerContext(new List { requirement }, claimsPrincipal, secret); @@ -182,6 +185,8 @@ public class SecretAuthorizationHandlerTests [Theory] [BitAutoData(PermissionType.RunAsUserWithPermission, true, false)] [BitAutoData(PermissionType.RunAsUserWithPermission, false, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, false)] public async Task CanCreateSecret_DoesNotSucceed(PermissionType permissionType, bool read, bool write, SutProvider sutProvider, Secret secret, Guid userId, @@ -190,7 +195,7 @@ public class SecretAuthorizationHandlerTests var requirement = SecretOperations.Create; SetupPermission(sutProvider, permissionType, secret.OrganizationId, userId); sutProvider.GetDependency() - .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, default).Returns( + .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, Arg.Any()).ReturnsForAnyArgs( (read, write)); var authzContext = new AuthorizationHandlerContext(new List { requirement }, claimsPrincipal, secret); @@ -207,6 +212,8 @@ public class SecretAuthorizationHandlerTests [BitAutoData(PermissionType.RunAsAdmin, false, false)] [BitAutoData(PermissionType.RunAsUserWithPermission, true, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, false, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, true)] public async Task CanCreateSecret_Success(PermissionType permissionType, bool read, bool write, SutProvider sutProvider, Secret secret, Guid userId, @@ -215,7 +222,7 @@ public class SecretAuthorizationHandlerTests var requirement = SecretOperations.Create; SetupPermission(sutProvider, permissionType, secret.OrganizationId, userId); sutProvider.GetDependency() - .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, default).Returns( + .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, Arg.Any()).ReturnsForAnyArgs( (read, write)); var authzContext = new AuthorizationHandlerContext(new List { requirement }, claimsPrincipal, secret); @@ -243,7 +250,6 @@ public class SecretAuthorizationHandlerTests } [Theory] - [BitAutoData(AccessClientType.ServiceAccount)] [BitAutoData(AccessClientType.Organization)] public async Task CanUpdateSecret_NotSupportedClientTypes_DoesNotSucceed(AccessClientType clientType, SutProvider sutProvider, Secret secret, Guid userId, @@ -252,7 +258,7 @@ public class SecretAuthorizationHandlerTests var requirement = SecretOperations.Update; SetupPermission(sutProvider, PermissionType.RunAsUserWithPermission, secret.OrganizationId, userId, clientType); sutProvider.GetDependency() - .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, default).Returns( + .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, Arg.Any()).Returns( (true, true)); var authzContext = new AuthorizationHandlerContext(new List { requirement }, claimsPrincipal, secret); @@ -327,6 +333,15 @@ public class SecretAuthorizationHandlerTests [BitAutoData(PermissionType.RunAsUserWithPermission, true, false, true, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, true, false, false, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, true, false, false, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, true, true, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, true, false, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, true, true, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, true, false, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, false, true, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, false, false, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, false, true, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, false, false, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, false, false, false)] public async Task CanUpdateSecret_DoesNotSucceed(PermissionType permissionType, bool read, bool write, bool projectRead, bool projectWrite, SutProvider sutProvider, Secret secret, @@ -335,10 +350,10 @@ public class SecretAuthorizationHandlerTests { var requirement = SecretOperations.Update; SetupPermission(sutProvider, permissionType, secret.OrganizationId, userId); - sutProvider.GetDependency().AccessToSecretAsync(secret.Id, userId, default).Returns( + sutProvider.GetDependency().AccessToSecretAsync(secret.Id, userId, Arg.Any()).Returns( (read, write)); sutProvider.GetDependency() - .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, default).Returns( + .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, Arg.Any()).Returns( (projectRead, projectWrite)); var authzContext = new AuthorizationHandlerContext(new List { requirement }, claimsPrincipal, secret); @@ -355,6 +370,8 @@ public class SecretAuthorizationHandlerTests [BitAutoData(PermissionType.RunAsAdmin, false, false)] [BitAutoData(PermissionType.RunAsUserWithPermission, true, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, false, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, true)] public async Task CanUpdateSecret_Success(PermissionType permissionType, bool read, bool write, SutProvider sutProvider, Secret secret, Guid userId, @@ -362,10 +379,10 @@ public class SecretAuthorizationHandlerTests { var requirement = SecretOperations.Update; SetupPermission(sutProvider, permissionType, secret.OrganizationId, userId); - sutProvider.GetDependency().AccessToSecretAsync(secret.Id, userId, default).Returns( + sutProvider.GetDependency().AccessToSecretAsync(secret.Id, userId, Arg.Any()).Returns( (read, write)); sutProvider.GetDependency() - .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, default).Returns( + .AccessToProjectAsync(secret.Projects!.FirstOrDefault()!.Id, userId, Arg.Any()).Returns( (read, write)); var authzContext = new AuthorizationHandlerContext(new List { requirement }, claimsPrincipal, secret); @@ -409,32 +426,16 @@ public class SecretAuthorizationHandlerTests Assert.False(authzContext.HasSucceeded); } - [Theory] - [BitAutoData] - public async Task CanDeleteSecret_ServiceAccountClient_DoesNotSucceed( - SutProvider sutProvider, Secret secret, Guid userId, - ClaimsPrincipal claimsPrincipal) - { - var requirement = SecretOperations.Delete; - SetupPermission(sutProvider, PermissionType.RunAsUserWithPermission, secret.OrganizationId, userId, - AccessClientType.ServiceAccount); - sutProvider.GetDependency() - .AccessToSecretAsync(secret.Id, userId, Arg.Any()) - .Returns((true, true)); - var authzContext = new AuthorizationHandlerContext(new List { requirement }, - claimsPrincipal, secret); - - await sutProvider.Sut.HandleAsync(authzContext); - - Assert.False(authzContext.HasSucceeded); - } - [Theory] [BitAutoData(PermissionType.RunAsAdmin, true, true, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, false, false, false)] [BitAutoData(PermissionType.RunAsUserWithPermission, false, true, true)] [BitAutoData(PermissionType.RunAsUserWithPermission, true, false, false)] [BitAutoData(PermissionType.RunAsUserWithPermission, true, true, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, false, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, false, true, true)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, false, false)] + [BitAutoData(PermissionType.RunAsServiceAccountWithPermission, true, true, true)] public async Task CanDeleteProject_AccessCheck(PermissionType permissionType, bool read, bool write, bool expected, SutProvider sutProvider, Secret secret, diff --git a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Commands/Projects/CreateProjectCommandTests.cs b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Commands/Projects/CreateProjectCommandTests.cs index 9223e56d55..9f9fbf35e4 100644 --- a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Commands/Projects/CreateProjectCommandTests.cs +++ b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Commands/Projects/CreateProjectCommandTests.cs @@ -1,4 +1,5 @@ using Bit.Commercial.Core.SecretsManager.Commands.Projects; +using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Repositories; using Bit.Core.SecretsManager.Entities; @@ -29,7 +30,7 @@ public class CreateProjectCommandTests .CreateAsync(Arg.Any()) .Returns(data); - await sutProvider.Sut.CreateAsync(data, userId); + await sutProvider.Sut.CreateAsync(data, userId, sutProvider.GetDependency().ClientType); await sutProvider.GetDependency().Received(1) .CreateAsync(Arg.Is(data)); diff --git a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Enums/PermissionType.cs b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Enums/PermissionType.cs index 1c4e88e91c..ce718b0618 100644 --- a/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Enums/PermissionType.cs +++ b/bitwarden_license/test/Commercial.Core.Test/SecretsManager/Enums/PermissionType.cs @@ -4,4 +4,5 @@ public enum PermissionType { RunAsAdmin, RunAsUserWithPermission, + RunAsServiceAccountWithPermission } diff --git a/src/Api/SecretsManager/Controllers/ProjectsController.cs b/src/Api/SecretsManager/Controllers/ProjectsController.cs index 7ee58e0d3e..e94da33a67 100644 --- a/src/Api/SecretsManager/Controllers/ProjectsController.cs +++ b/src/Api/SecretsManager/Controllers/ProjectsController.cs @@ -73,9 +73,8 @@ public class ProjectsController : Controller { throw new NotFoundException(); } - var userId = _userService.GetProperUserId(User).Value; - var result = await _createProjectCommand.CreateAsync(project, userId); + var result = await _createProjectCommand.CreateAsync(project, userId, _currentContext.ClientType); // Creating a project means you have read & write permission. return new ProjectResponseModel(result, true, true); diff --git a/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs b/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs index 50cd714cb8..3072528659 100644 --- a/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs +++ b/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs @@ -1,8 +1,9 @@ -using Bit.Core.SecretsManager.Entities; +using Bit.Core.Identity; +using Bit.Core.SecretsManager.Entities; namespace Bit.Core.SecretsManager.Commands.Projects.Interfaces; public interface ICreateProjectCommand { - Task CreateAsync(Project project, Guid userId); + Task CreateAsync(Project project, Guid userId, ClientType clientType); } diff --git a/test/Api.Test/SecretsManager/Controllers/ProjectsControllerTests.cs b/test/Api.Test/SecretsManager/Controllers/ProjectsControllerTests.cs index 951875b1b4..66578218c2 100644 --- a/test/Api.Test/SecretsManager/Controllers/ProjectsControllerTests.cs +++ b/test/Api.Test/SecretsManager/Controllers/ProjectsControllerTests.cs @@ -114,12 +114,12 @@ public class ProjectsControllerTests var resultProject = data.ToProject(orgId); - sutProvider.GetDependency().CreateAsync(default, default) + sutProvider.GetDependency().CreateAsync(default, default, sutProvider.GetDependency().ClientType) .ReturnsForAnyArgs(resultProject); await Assert.ThrowsAsync(() => sutProvider.Sut.CreateAsync(orgId, data)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() - .CreateAsync(Arg.Any(), Arg.Any()); + .CreateAsync(Arg.Any(), Arg.Any(), sutProvider.GetDependency().ClientType); } [Theory] @@ -134,13 +134,13 @@ public class ProjectsControllerTests var resultProject = data.ToProject(orgId); - sutProvider.GetDependency().CreateAsync(default, default) + sutProvider.GetDependency().CreateAsync(default, default, sutProvider.GetDependency().ClientType) .ReturnsForAnyArgs(resultProject); await sutProvider.Sut.CreateAsync(orgId, data); await sutProvider.GetDependency().Received(1) - .CreateAsync(Arg.Any(), Arg.Any()); + .CreateAsync(Arg.Any(), Arg.Any(), sutProvider.GetDependency().ClientType); } [Theory]