public async Task <IActionResult> CreateTemplateAsClone([FromBody] TemplateCreateAsCloneCommand createModel) { Guard.ArgumentNotNull(createModel, nameof(createModel)); if (!ModelState.IsValid) { return(BadRequest(ModelState)); } FundingStreamPermission permissions = await _authorizationHelper.GetUserFundingStreamPermissions(User, createModel.FundingStreamId); if (!permissions.CanCreateTemplates) { _logger.Error($"User [{User?.Identity?.Name}] has insufficient permissions to create a {createModel.FundingStreamId} template"); return(Forbid(new AuthenticationProperties())); } ValidatedApiResponse <string> result = await _client.CreateTemplateAsClone(createModel); switch (result.StatusCode) { case HttpStatusCode.Created: return(Created($"api/templates/build/{result.Content}", result.Content)); case HttpStatusCode.BadRequest: return(BadRequest(result.ModelState)); default: return(StatusCode((int)result.StatusCode)); } }
private bool HasPermissionToAllFundingStreams(IEnumerable <string> fundingStreamIds, FundingStreamActionTypes requestedPermission, IEnumerable <FundingStreamPermission> actualPermissions) { if (actualPermissions == null || actualPermissions.Count() == 0) { // No permissions to check against so can't have permission for the action return(false); } if (requestedPermission == FundingStreamActionTypes.CanCreateSpecification) { foreach (string item in fundingStreamIds) { FundingStreamPermission foundPermission = actualPermissions.FirstOrDefault(p => p.FundingStreamId == item && p.CanCreateSpecification); if (foundPermission == null) { // A required permission is missing so can't succeed return(false); } } return(true); } else { return(false); } }
public async Task WhenUserCannotCreateSpecification_ShouldNotSucceed() { // Arrange string userId = Guid.NewGuid().ToString(); ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(Constants.ObjectIdentifierClaimType, userId) })); List <string> fundingStreamIds = new List <string> { WellKnownFundingStreamId }; AuthorizationHandlerContext authContext = CreateAuthenticationContext(principal, FundingStreamActionTypes.CanCreateSpecification, fundingStreamIds); FundingStreamPermission actualPermission = new FundingStreamPermission { CanCreateSpecification = false, FundingStreamId = WellKnownFundingStreamId }; IUsersApiClient usersApiClient = Substitute.For <IUsersApiClient>(); usersApiClient.GetFundingStreamPermissionsForUser(Arg.Is(userId)).Returns(new ApiResponse <IEnumerable <FundingStreamPermission> >(HttpStatusCode.OK, new List <FundingStreamPermission> { actualPermission })); IOptions <PermissionOptions> options = Substitute.For <IOptions <PermissionOptions> >(); options.Value.Returns(actualOptions); FundingStreamPermissionHandler authHandler = new FundingStreamPermissionHandler(usersApiClient, options); // Act await authHandler.HandleAsync(authContext); // Assert authContext.HasSucceeded.Should().BeFalse(); }
public async Task GetUserFundingStreamPermissions_WhenUserHasNoAccess_ThenReturnFalse() { // Arrange string userId = "testuser"; ClaimsPrincipal user = BuildClaimsPrincipal(userId); ApiResponse <IEnumerable <FundingStreamPermission> > permissionsResponse = new ApiResponse <IEnumerable <FundingStreamPermission> >(HttpStatusCode.OK, new List <FundingStreamPermission> { new FundingStreamPermission { FundingStreamId = "fs1", CanCreateSpecification = true }, new FundingStreamPermission { FundingStreamId = "fs2", CanCreateSpecification = true }, new FundingStreamPermission { FundingStreamId = "fs3", CanCreateSpecification = false } }); IAuthorizationService authorizationService = Substitute.For <IAuthorizationService>(); IUsersApiClient usersClient = Substitute.For <IUsersApiClient>(); usersClient .GetFundingStreamPermissionsForUser(userId) .Returns(permissionsResponse); AuthorizationHelper authHelper = CreateAuthenticationHelper(authorizationService, usersClient); // Act FundingStreamPermission result = await authHelper.GetUserFundingStreamPermissions(user, "fs3"); // Assert result.CanCreateSpecification.Should().BeFalse(); }
public async Task <IActionResult> UpdatePermissionForUser(string userId, string fundingStreamId, FundingStreamPermissionUpdateModel updateModel, Reference author) { if (string.IsNullOrWhiteSpace(userId)) { return(new BadRequestObjectResult($"{nameof(userId)} is empty or null")); } if (string.IsNullOrWhiteSpace(fundingStreamId)) { return(new BadRequestObjectResult($"{nameof(fundingStreamId)} is empty or null")); } User user = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetUserById(userId)); if (user == null) { return(new PreconditionFailedResult("userId not found")); } FundingStreamPermission existingPermissions = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetFundingStreamPermission(userId, fundingStreamId)); FundingStreamPermission newPermissions = _mapper.Map <FundingStreamPermissionUpdateModel, FundingStreamPermission>(updateModel); newPermissions.FundingStreamId = fundingStreamId; newPermissions.UserId = userId; if (existingPermissions == null || !existingPermissions.HasSamePermissions(newPermissions)) { HttpStatusCode saveResult = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.UpdateFundingStreamPermission(newPermissions)); if (saveResult != HttpStatusCode.OK && saveResult != HttpStatusCode.Created) { return(new InternalServerErrorResult($"Saving funding stream permission to repository returned '{saveResult}'")); } FundingStreamPermissionVersion version = new FundingStreamPermissionVersion() { Author = author, Permission = newPermissions, PublishStatus = Models.Versioning.PublishStatus.Updated, Date = DateTimeOffset.Now, UserId = userId, }; version.Version = await _fundingStreamPermissionVersionRepositoryPolicy.ExecuteAsync(() => _fundingStreamPermissionVersionRepository.GetNextVersionNumber(version, partitionKeyId: userId)); await _fundingStreamPermissionVersionRepositoryPolicy.ExecuteAsync(() => _fundingStreamPermissionVersionRepository.SaveVersion(version, userId)); await ClearEffectivePermissionsForUser(userId); } return(new OkObjectResult(_mapper.Map <FundingStreamPermissionCurrent>(newPermissions))); }
public async Task <IActionResult> ValidateDataset([FromBody] ValidateDatasetModel vm) { Guard.ArgumentNotNull(vm, nameof(vm)); FundingStreamPermission permissions = await _authorizationHelper.GetUserFundingStreamPermissions(User, vm.FundingStreamId); if (permissions?.CanUploadDataSourceFiles != true) { _logger.Error($"User [{User?.Identity?.Name}] has insufficient permissions to upload a dataset file for {vm.FundingStreamId}"); return(Forbid(new AuthenticationProperties())); } if (!ModelState.IsValid) { return(BadRequest(ModelState)); } ValidatedApiResponse <DatasetValidationStatusModel> apiResponse = await _datasetApiClient.ValidateDataset( new GetDatasetBlobModel { DatasetId = vm.DatasetId, Version = vm.Version, Filename = vm.Filename, Description = vm.Description, Comment = vm.Comment, FundingStreamId = vm.FundingStreamId, MergeExistingVersion = vm.MergeExistingVersion }); if (apiResponse == null) { _logger.Warning("Validate Dataset API response was null"); return(new InternalServerErrorResult("Validate Dataset API response was null")); } if (!apiResponse.StatusCode.IsSuccess()) { _logger.Warning("Failed to validate dataset with status code: {statusCode}", apiResponse.StatusCode); if (apiResponse.IsBadRequest(out BadRequestObjectResult badRequest)) { return(badRequest); } return(new InternalServerErrorResult( "Validate Dataset API response failed with status code: {statusCode}" + apiResponse.StatusCode)); } DatasetValidationStatusViewModel result = _mapper.Map <DatasetValidationStatusViewModel>(apiResponse.Content); return(new OkObjectResult(result)); }
public async Task <IActionResult> GetFundingStreams(bool securityTrimmed) { ApiResponse <IEnumerable <FundingStream> > response = await _policiesApiClient.GetFundingStreams(); if (response.StatusCode == HttpStatusCode.OK) { IEnumerable <FundingStream> fundingStreams = response.Content.OrderBy(x => x.Name); if (securityTrimmed) { IEnumerable <Task <FundingStream> > tasks = fundingStreams.Select(async(_) => { FundingStreamPermission permission = await _authorizationHelper.GetUserFundingStreamPermissions(User, _.Id); return(permission != null ? (permission.CanCreateSpecification ? _ : null) : null); }); fundingStreams = await Task.WhenAll(tasks); } return(Ok(fundingStreams.Where(_ => _ != null))); } throw new InvalidOperationException($"An error occurred while retrieving code context. Status code={response.StatusCode}"); }
public async Task UpdatePermissionForUser_WhenPermissionsAreSetOnAFundingStreamAndNoneHaveBeenSetBefore_ThenPermissionsSaved() { // Arrange IUserRepository userRepository = CreateUserRepository(); User user = new User() { UserId = UserId }; userRepository .GetUserById(Arg.Is(UserId)) .Returns(user); FundingStreamPermission existingPermission = null; userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is(FundingStreamId)) .Returns(existingPermission); userRepository .UpdateFundingStreamPermission(Arg.Any <FundingStreamPermission>()) .Returns(HttpStatusCode.Created); ICacheProvider cacheProvider = CreateCacheProvider(); FundingStreamPermissionUpdateModel updateModel = new FundingStreamPermissionUpdateModel() { CanApproveFunding = true, CanChooseFunding = false, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanReleaseFunding = false, CanCreateTemplates = true, CanEditTemplates = true, CanDeleteTemplates = true, CanApproveTemplates = true, CanCreateProfilePattern = true, CanEditProfilePattern = true, CanDeleteProfilePattern = true, CanAssignProfilePattern = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = true, CanApproveAnyCalculations = false, CanApproveAllCalculations = false }; IVersionRepository <FundingStreamPermissionVersion> versionRepository = CreateFundingStreamPermissionRepository(); versionRepository .GetNextVersionNumber(Arg.Any <FundingStreamPermissionVersion>(), 0, Arg.Is(UserId)) .Returns(1); FundingStreamPermissionService service = CreateService( userRepository, cacheProvider: cacheProvider, fundingStreamPermissionVersionRepository: versionRepository); // Act IActionResult result = await service.UpdatePermissionForUser(UserId, FundingStreamId, updateModel, null); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .BeEquivalentTo <FundingStreamPermissionCurrent>(new FundingStreamPermissionCurrent() { UserId = UserId, FundingStreamId = FundingStreamId, CanApproveFunding = true, CanChooseFunding = false, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanReleaseFunding = false, CanCreateTemplates = true, CanEditTemplates = true, CanDeleteTemplates = true, CanApproveTemplates = true, CanCreateProfilePattern = true, CanEditProfilePattern = true, CanDeleteProfilePattern = true, CanAssignProfilePattern = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = true, CanApproveAnyCalculations = false, CanApproveAllCalculations = false, }); await userRepository .Received(1) .UpdateFundingStreamPermission(Arg.Is <FundingStreamPermission>(p => p.FundingStreamId == FundingStreamId && p.UserId == UserId && p.CanApproveFunding && !p.CanChooseFunding && !p.CanCreateSpecification && !p.CanEditCalculations && !p.CanEditSpecification && !p.CanMapDatasets && !p.CanReleaseFunding && p.CanCreateTemplates && p.CanEditTemplates && p.CanDeleteTemplates && p.CanApproveTemplates && p.CanCreateProfilePattern && p.CanEditProfilePattern && p.CanDeleteProfilePattern && !p.CanAssignProfilePattern && !p.CanApplyCustomProfilePattern && p.CanApproveCalculations && !p.CanApproveAnyCalculations && !p.CanApproveAllCalculations )); await cacheProvider .Received(1) .DeleteHashSet(Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}")); await versionRepository .Received(1) .GetNextVersionNumber(Arg.Is <FundingStreamPermissionVersion>(v => v.EntityId == $"{UserId}_{FundingStreamId}"), partitionKeyId: Arg.Is(UserId)); await versionRepository .Received(1) .SaveVersion(Arg.Is <FundingStreamPermissionVersion>(v => v.EntityId == $"{UserId}_{FundingStreamId}" && v.Version == 1 ), Arg.Is(UserId)); }
public async Task UpdatePermissionForUser_WhenSavingPermissionsFails_ThenInternalServerErrorReturned() { // Arrange IUserRepository userRepository = CreateUserRepository(); User user = new User() { UserId = UserId }; userRepository .GetUserById(Arg.Is(UserId)) .Returns(user); FundingStreamPermission existingPermission = new FundingStreamPermission() { UserId = UserId, FundingStreamId = FundingStreamId, CanApproveFunding = true, CanChooseFunding = false, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanReleaseFunding = false, CanCreateProfilePattern = false, CanEditProfilePattern = false, CanDeleteProfilePattern = false, CanAssignProfilePattern = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = true, CanApproveAnyCalculations = false, CanApproveAllCalculations = false }; userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is(FundingStreamId)) .Returns(existingPermission); userRepository .UpdateFundingStreamPermission(Arg.Any <FundingStreamPermission>()) .Returns(HttpStatusCode.InternalServerError); ICacheProvider cacheProvider = CreateCacheProvider(); FundingStreamPermissionUpdateModel updateModel = new FundingStreamPermissionUpdateModel() { CanApproveFunding = true, CanChooseFunding = true, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanReleaseFunding = false, CanCreateProfilePattern = false, CanEditProfilePattern = false, CanDeleteProfilePattern = false, CanAssignProfilePattern = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = false, CanApproveAnyCalculations = true, CanApproveAllCalculations = true }; FundingStreamPermissionService service = CreateService(userRepository, cacheProvider: cacheProvider); // Act IActionResult result = await service.UpdatePermissionForUser(UserId, FundingStreamId, updateModel, null); // Assert result .Should() .BeOfType <InternalServerErrorResult>() .Which .Value .Should() .Be("Saving funding stream permission to repository returned 'InternalServerError'"); await userRepository .Received(1) .UpdateFundingStreamPermission(Arg.Any <FundingStreamPermission>()); await cacheProvider .Received(0) .DeleteHashSet(Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}")); }
public async Task <IActionResult> GetEffectivePermissionsForUser(string userId, string specificationId) { if (string.IsNullOrWhiteSpace(userId)) { return(new BadRequestObjectResult($"{nameof(userId)} is empty or null")); } if (string.IsNullOrWhiteSpace(specificationId)) { return(new BadRequestObjectResult($"{nameof(specificationId)} is empty or null")); } EffectiveSpecificationPermission cachedPermissions = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.GetHashValue <EffectiveSpecificationPermission>($"{CacheKeys.EffectivePermissions}:{userId}", specificationId)); if (cachedPermissions != null) { return(new OkObjectResult(cachedPermissions)); } else { ApiResponse <SpecModel.SpecificationSummary> specificationApiResponse = await _specificationsApiClientPolicy.ExecuteAsync(() => _specificationsApiClient.GetSpecificationSummaryById(specificationId)); if (!specificationApiResponse.StatusCode.IsSuccess() || specificationApiResponse.Content == null) { return(new PreconditionFailedResult("Specification not found")); } SpecModel.SpecificationSummary specification = specificationApiResponse.Content; List <FundingStreamPermission> permissionsForUser = new List <FundingStreamPermission>(); foreach (Reference fundingStream in specification.FundingStreams) { FundingStreamPermission permission = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetFundingStreamPermission(userId, fundingStream.Id)); if (permission != null) { permissionsForUser.Add(permission); } else { // Add permission for this funding stream with no permissions - used further down to calculate permissions (required for pessimistic permissions) permissionsForUser.Add(new FundingStreamPermission { UserId = userId, FundingStreamId = fundingStream.Id, CanApproveFunding = false, CanChooseFunding = false, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanReleaseFunding = false, CanAdministerFundingStream = false, CanApproveSpecification = false, CanCreateQaTests = false, CanDeleteCalculations = false, CanDeleteSpecification = false, CanDeleteQaTests = false, CanEditQaTests = false, CanRefreshFunding = false, CanCreateTemplates = false, CanEditTemplates = false, CanDeleteTemplates = false, CanApproveTemplates = false, CanCreateProfilePattern = false, CanEditProfilePattern = false, CanDeleteProfilePattern = false, CanAssignProfilePattern = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = false, CanApproveAnyCalculations = false, CanApproveAllCalculations = false }); } } EffectiveSpecificationPermission specificationPermissions = GeneratePermissions(permissionsForUser, specificationId, userId); string userPermissionHashKey = $"{CacheKeys.EffectivePermissions}:{userId}"; // Does the hash set for this user already exist - used to determine the timeout for the hash set below bool existingHashSetExists = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.HashSetExists(userPermissionHashKey)); // Cache effective permissions for the specification / user await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.SetHashValue(userPermissionHashKey, specificationId, specificationPermissions)); // If the hash set does not exist, then set an expiry for the whole hash set. This stops the users permissions being stored indefinitely if (!existingHashSetExists) { await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.SetHashExpiry(userPermissionHashKey, DateTime.UtcNow.AddHours(12))); } return(new OkObjectResult(specificationPermissions)); } }
public async Task GetEffectivePermissionsForUser_WhenNotFoundInCacheResultsAreQueriedWithMultipleFundingStreamAndNoPermissionsAreInRepository_ThenOkResultReturnedWithNoPermissions() { // Arrange IUserRepository userRepository = CreateUserRepository(); ISpecificationRepository specificationRepository = CreateSpecificationRepository(); ICacheProvider cacheProvider = CreateCacheProvider(); IMapper mapper = CreateMappingConfiguration(); EffectiveSpecificationPermission cachedPermission = null; cacheProvider .GetHashValue <EffectiveSpecificationPermission>(Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}"), Arg.Is(SpecificationId)) .Returns(cachedPermission); SpecificationSummary specificationSummary = new SpecificationSummary() { Id = SpecificationId, FundingStreams = new List <Reference>() { new Reference("fs1", "Funding Stream 1"), new Reference("fs2", "Funding Stream 2") } }; specificationRepository .GetSpecificationSummaryById(Arg.Is(SpecificationId)) .Returns(specificationSummary); FundingStreamPermission fs1Permission = null; userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is("fs1")) .Returns(fs1Permission); FundingStreamPermission fs2Permission = null; userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is("fs2")) .Returns(fs2Permission); FundingStreamPermissionService service = CreateService(userRepository, specificationRepository, cacheProvider: cacheProvider, mapper: mapper); // Act IActionResult result = await service.GetEffectivePermissionsForUser(UserId, SpecificationId, null); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .BeEquivalentTo(new EffectiveSpecificationPermission() { UserId = UserId, SpecificationId = SpecificationId, CanApproveFunding = false, CanCreateSpecification = false, CanMapDatasets = false, CanChooseFunding = false, CanEditCalculations = false, CanEditSpecification = false, CanPublishFunding = false, CanAdministerFundingStream = false, CanApproveSpecification = false, CanCreateQaTests = false, CanEditQaTests = false, CanRefreshFunding = false, }); await cacheProvider .Received(1) .SetHashValue( Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}"), Arg.Is(SpecificationId), Arg.Is <EffectiveSpecificationPermission>(p => !p.CanApproveFunding && !p.CanChooseFunding && !p.CanCreateSpecification && !p.CanEditCalculations && !p.CanEditSpecification && !p.CanMapDatasets && !p.CanPublishFunding && !p.CanAdministerFundingStream && !p.CanApproveSpecification && !p.CanCreateQaTests && !p.CanEditQaTests && !p.CanRefreshFunding && p.SpecificationId == SpecificationId && p.UserId == UserId )); }
public async Task GetEffectivePermissionsForUser_WhenNotFoundInCacheResultsAreQueriedWithMultipleFundingStreamAndUserHasPermissionsButNotAcrossAllFundingStreams_ThenOkResultReturnedWithPermissionsThatOnlyAllFundingStreamsHave() { // Arrange IUserRepository userRepository = CreateUserRepository(); ISpecificationsApiClient specificationsApiClient = CreateSpecificationsApiClient(); ICacheProvider cacheProvider = CreateCacheProvider(); IMapper mapper = CreateMappingConfiguration(); EffectiveSpecificationPermission cachedPermission = null; cacheProvider .GetHashValue <EffectiveSpecificationPermission>(Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}"), Arg.Is(SpecificationId)) .Returns(cachedPermission); SpecModel.SpecificationSummary specificationSummary = new SpecModel.SpecificationSummary() { Id = SpecificationId, FundingStreams = new List <Reference>() { new Reference("fs1", "Funding Stream 1"), new Reference("fs2", "Funding Stream 2"), } }; specificationsApiClient .GetSpecificationSummaryById(Arg.Is(SpecificationId)) .Returns(new ApiResponse <SpecModel.SpecificationSummary>(HttpStatusCode.OK, specificationSummary)); FundingStreamPermission fs1Permission = new FundingStreamPermission() { UserId = UserId, FundingStreamId = "fs1", CanChooseFunding = false, CanCreateSpecification = true, CanApproveFunding = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanReleaseFunding = false, CanAdministerFundingStream = false, CanApproveSpecification = false, CanCreateQaTests = false, CanEditQaTests = false, CanRefreshFunding = false, CanCreateProfilePattern = false, CanEditProfilePattern = false, CanDeleteProfilePattern = false, CanAssignProfilePattern = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = true, CanApproveAnyCalculations = false, CanApproveAllCalculations = false }; FundingStreamPermission fs2Permission = new FundingStreamPermission() { UserId = UserId, FundingStreamId = "fs1", CanChooseFunding = false, CanCreateSpecification = true, CanApproveFunding = true, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanReleaseFunding = false, CanAdministerFundingStream = false, CanApproveSpecification = false, CanCreateQaTests = false, CanEditQaTests = false, CanRefreshFunding = false, CanCreateProfilePattern = false, CanEditProfilePattern = false, CanDeleteProfilePattern = false, CanAssignProfilePattern = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = true, CanApproveAnyCalculations = false, CanApproveTemplates = false, CanCreateTemplates = false, CanDeleteCalculations = false, CanDeleteQaTests = false, CanDeleteSpecification = false, CanDeleteTemplates = false, CanEditTemplates = false, CanApproveAllCalculations = false }; userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is("fs1")) .Returns(fs1Permission); userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is("fs2")) .Returns(fs2Permission); FundingStreamPermissionService service = CreateService(userRepository, specificationsApiClient, cacheProvider: cacheProvider, mapper: mapper); // Act IActionResult result = await service.GetEffectivePermissionsForUser(UserId, SpecificationId); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .BeEquivalentTo(new EffectiveSpecificationPermission() { UserId = UserId, SpecificationId = SpecificationId, CanApproveFunding = false, CanCreateSpecification = true, CanMapDatasets = false, CanChooseFunding = false, CanEditCalculations = false, CanEditSpecification = false, CanReleaseFunding = false, CanAdministerFundingStream = false, CanApproveSpecification = false, CanCreateQaTests = false, CanEditQaTests = false, CanRefreshFunding = false, CanApproveAnyCalculations = false, CanAssignProfilePattern = false, CanDeleteSpecification = false, CanDeleteQaTests = false, CanDeleteCalculations = false, CanApplyCustomProfilePattern = false, CanApproveCalculations = true, CanApproveAllCalculations = false }); await cacheProvider .Received(1) .SetHashValue( Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}"), Arg.Is(SpecificationId), Arg.Is <EffectiveSpecificationPermission>(p => !p.CanApproveFunding && !p.CanChooseFunding && p.CanCreateSpecification && !p.CanEditCalculations && !p.CanEditSpecification && !p.CanMapDatasets && !p.CanReleaseFunding && !p.CanAdministerFundingStream && !p.CanApproveSpecification && !p.CanCreateQaTests && !p.CanEditQaTests && !p.CanRefreshFunding && p.SpecificationId == SpecificationId && p.UserId == UserId )); }
public async Task <HttpStatusCode> UpdateFundingStreamPermission(FundingStreamPermission fundingStreamPermission) { Guard.ArgumentNotNull(fundingStreamPermission, nameof(fundingStreamPermission)); return(await _cosmosRepository.UpsertAsync(fundingStreamPermission, fundingStreamPermission.UserId)); }
public async Task UpdatePermissionForUser_WhenPermissionsAreSetOnAFundingStreamAndNoneHaveBeenSetBefore_ThenPermissionsSaved() { // Arrange IUserRepository userRepository = CreateUserRepository(); User user = new User() { UserId = UserId }; userRepository .GetUserById(Arg.Is(UserId)) .Returns(user); FundingStreamPermission existingPermission = null; userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is(FundingStreamId)) .Returns(existingPermission); userRepository .UpdateFundingStreamPermission(Arg.Any <FundingStreamPermission>()) .Returns(HttpStatusCode.Created); ICacheProvider cacheProvider = CreateCacheProvider(); FundingStreamPermissionUpdateModel updateModel = new FundingStreamPermissionUpdateModel() { CanApproveFunding = true, CanChooseFunding = false, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanPublishFunding = false, }; string json = JsonConvert.SerializeObject(updateModel); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpRequest request = Substitute.For <HttpRequest>(); request .Body .Returns(stream); IVersionRepository <FundingStreamPermissionVersion> versionRepository = CreateFundingStreamPermissionRepository(); versionRepository .GetNextVersionNumber(Arg.Any <FundingStreamPermissionVersion>(), 0, Arg.Is(UserId)) .Returns(1); FundingStreamPermissionService service = CreateService( userRepository, cacheProvider: cacheProvider, fundingStreamPermissionVersionRepository: versionRepository); // Act IActionResult result = await service.UpdatePermissionForUser(UserId, FundingStreamId, request); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .BeEquivalentTo <FundingStreamPermissionCurrent>(new FundingStreamPermissionCurrent() { UserId = UserId, FundingStreamId = FundingStreamId, CanApproveFunding = true, CanChooseFunding = false, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanPublishFunding = false, }); await userRepository .Received(1) .UpdateFundingStreamPermission(Arg.Is <FundingStreamPermission>(p => p.FundingStreamId == FundingStreamId && p.UserId == UserId && p.CanApproveFunding && !p.CanChooseFunding && !p.CanCreateSpecification && !p.CanEditCalculations && !p.CanEditSpecification && !p.CanMapDatasets && !p.CanPublishFunding )); await cacheProvider .Received(1) .DeleteHashSet(Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}")); await versionRepository .Received(1) .GetNextVersionNumber(Arg.Is <FundingStreamPermissionVersion>(v => v.EntityId == $"{UserId}_{FundingStreamId}"), partitionKeyId: Arg.Is(UserId)); await versionRepository .Received(1) .SaveVersion(Arg.Is <FundingStreamPermissionVersion>(v => v.EntityId == $"{UserId}_{FundingStreamId}" && v.Version == 1 ), Arg.Is(UserId)); }
public async Task UpdatePermissionForUser_WhenSavingPermissionsFails_ThenInternalServerErrorReturned() { // Arrange IUserRepository userRepository = CreateUserRepository(); User user = new User() { UserId = UserId }; userRepository .GetUserById(Arg.Is(UserId)) .Returns(user); FundingStreamPermission existingPermission = new FundingStreamPermission() { UserId = UserId, FundingStreamId = FundingStreamId, CanApproveFunding = true, CanChooseFunding = false, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanPublishFunding = false, }; userRepository .GetFundingStreamPermission(Arg.Is(UserId), Arg.Is(FundingStreamId)) .Returns(existingPermission); userRepository .UpdateFundingStreamPermission(Arg.Any <FundingStreamPermission>()) .Returns(HttpStatusCode.InternalServerError); ICacheProvider cacheProvider = CreateCacheProvider(); FundingStreamPermissionUpdateModel updateModel = new FundingStreamPermissionUpdateModel() { CanApproveFunding = true, CanChooseFunding = true, CanCreateSpecification = false, CanEditCalculations = false, CanEditSpecification = false, CanMapDatasets = false, CanPublishFunding = false, }; string json = JsonConvert.SerializeObject(updateModel); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpRequest request = Substitute.For <HttpRequest>(); request .Body .Returns(stream); FundingStreamPermissionService service = CreateService(userRepository, cacheProvider: cacheProvider); // Act IActionResult result = await service.UpdatePermissionForUser(UserId, FundingStreamId, request); // Assert result .Should() .BeOfType <InternalServerErrorResult>() .Which .Value .Should() .Be("Saving funding stream permission to repository returned 'InternalServerError'"); await userRepository .Received(1) .UpdateFundingStreamPermission(Arg.Any <FundingStreamPermission>()); await cacheProvider .Received(0) .DeleteHashSet(Arg.Is($"{CacheKeys.EffectivePermissions}:{UserId}")); }
private void GivenTheUserHasPermissionToUploadDataSourceFilesForFundingStream(string fundingSteamId, FundingStreamPermission fundingStreamPermission) => _authorisationHelper .Setup(_ => _.GetUserFundingStreamPermissions(It.IsAny <ClaimsPrincipal>(), fundingSteamId)) .ReturnsAsync(fundingStreamPermission);