public async Task WhenUserWithSpecificPermission_ShouldSucceed( EffectiveSpecificationPermission actualPermission, SpecificationActionTypes specificationActionTypes) { // Arrange string userId = Guid.NewGuid().ToString(); ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(Constants.ObjectIdentifierClaimType, userId) })); string specification = WellKnownSpecificationId; AuthorizationHandlerContext authContext = CreateAuthenticationContext(principal, specificationActionTypes, specification); IUsersApiClient usersApiClient = Substitute.For <IUsersApiClient>(); usersApiClient.GetEffectivePermissionsForUser(Arg.Is(userId), Arg.Is(WellKnownSpecificationId)).Returns(new ApiResponse <EffectiveSpecificationPermission>(HttpStatusCode.OK, actualPermission)); IOptions <PermissionOptions> options = Substitute.For <IOptions <PermissionOptions> >(); options.Value.Returns(actualOptions); SpecificationPermissionHandler authHandler = new SpecificationPermissionHandler(usersApiClient, options); // Act await authHandler.HandleAsync(authContext); // Assert authContext.HasSucceeded.Should().BeTrue(); }
internal static IAuthorizationHelper CreateAuthorizationHelperSubstitute(SpecificationActionTypes permissionRequired, bool returns = true) { IAuthorizationHelper authHelper = Substitute.For <IAuthorizationHelper>(); authHelper.DoesUserHavePermission(Arg.Any <ClaimsPrincipal>(), Arg.Any <string>(), Arg.Is(permissionRequired)).Returns(returns); return(authHelper); }
public async Task Specifications_SecurityTrimListForChooseFunding_WhenUserHasAccessToNone_ThenReturnZeroSpecifications() { // Arrange IEnumerable <SpecificationSummary> specifications = new List <SpecificationSummary> { new SpecificationSummary { Id = "spec1", FundingStreams = new List <FundingStream> { new FundingStream { Id = "fs1" } } }, new SpecificationSummary { Id = "spec2", FundingStreams = new List <FundingStream> { new FundingStream { Id = "fs2" } } }, new SpecificationSummary { Id = "spec3", FundingStreams = new List <FundingStream> { new FundingStream { Id = "fs3" } } } }; string userId = "testuser"; ClaimsPrincipal user = BuildClaimsPrincipal(userId); SpecificationActionTypes permissionRequired = SpecificationActionTypes.CanChooseFunding; ApiResponse <IEnumerable <Common.ApiClient.Users.Models.FundingStreamPermission> > permissionsResponse = new ApiResponse <IEnumerable <Common.ApiClient.Users.Models.FundingStreamPermission> >(System.Net.HttpStatusCode.OK, new List <Common.ApiClient.Users.Models.FundingStreamPermission> { new Common.ApiClient.Users.Models.FundingStreamPermission { FundingStreamId = "fs1", CanChooseFunding = false }, new Common.ApiClient.Users.Models.FundingStreamPermission { FundingStreamId = "fs2", CanChooseFunding = false }, new Common.ApiClient.Users.Models.FundingStreamPermission { FundingStreamId = "fs3", CanChooseFunding = false } }); IAuthorizationService authorizationService = Substitute.For <IAuthorizationService>(); IUsersApiClient usersClient = Substitute.For <IUsersApiClient>(); usersClient .GetFundingStreamPermissionsForUser(userId) .Returns(permissionsResponse); AuthorizationHelper authHelper = CreateAuthenticationHelper(authorizationService, usersClient); // Act IEnumerable <SpecificationSummary> results = await authHelper.SecurityTrimList(user, specifications, permissionRequired); // Assert results.Should().BeEmpty(); }
private void SetupAuthorizedUser(SpecificationActionTypes specificationActionType) { _authorizationHelper.DoesUserHavePermission( _publishController.User, Arg.Any <string>(), specificationActionType) .Returns(true); }
private bool HasPermission(SpecificationActionTypes requestedPermission, EffectiveSpecificationPermission actualPermissions) { if (actualPermissions == null) { return(false); } switch (requestedPermission) { case SpecificationActionTypes.CanApproveFunding: return(actualPermissions.CanApproveFunding); case SpecificationActionTypes.CanChooseFunding: return(actualPermissions.CanChooseFunding); case SpecificationActionTypes.CanEditCalculations: return(actualPermissions.CanEditCalculations); case SpecificationActionTypes.CanEditSpecification: return(actualPermissions.CanEditSpecification); case SpecificationActionTypes.CanMapDatasets: return(actualPermissions.CanMapDatasets); case SpecificationActionTypes.CanReleaseFunding: return(actualPermissions.CanReleaseFunding); case SpecificationActionTypes.CanRefreshFunding: return(actualPermissions.CanRefreshFunding); case SpecificationActionTypes.CanCreateQaTests: return(actualPermissions.CanCreateQaTests); case SpecificationActionTypes.CanEditQaTests: return(actualPermissions.CanEditQaTests); case SpecificationActionTypes.CanApproveSpecification: return(actualPermissions.CanApproveSpecification); case SpecificationActionTypes.CanAdministerFundingStream: return(actualPermissions.CanAdministerFundingStream); case SpecificationActionTypes.CanDeleteSpecification: return(actualPermissions.CanDeleteSpecification); case SpecificationActionTypes.CanDeleteCalculations: return(actualPermissions.CanDeleteCalculations); case SpecificationActionTypes.CanDeleteQaTests: return(actualPermissions.CanDeleteQaTests); default: return(false); } }
public async Task <IActionResult> UpdateApprovalStatusForAllocationLine([FromRoute] string specificationId, [FromBody] PublishedAllocationLineResultStatusUpdateViewModel allocationLines) { Guard.ArgumentNotNull(allocationLines, nameof(allocationLines)); if (allocationLines.Status != AllocationLineStatusViewModel.Approved && allocationLines.Status != AllocationLineStatusViewModel.Published) { ModelState.AddModelError(nameof(allocationLines.Status), "The status provided is not a valid destination status"); } SpecificationActionTypes permissionRequired = allocationLines.Status == AllocationLineStatusViewModel.Approved ? SpecificationActionTypes.CanApproveFunding : SpecificationActionTypes.CanPublishFunding; if (!await _authorizationHelper.DoesUserHavePermission(User, specificationId, permissionRequired)) { return(new ForbidResult()); } if (!ModelState.IsValid) { return(BadRequest(ModelState)); } PublishedAllocationLineResultStatusUpdateModel updateModel = new PublishedAllocationLineResultStatusUpdateModel() { Status = _mapper.Map <AllocationLineStatus>(allocationLines.Status), }; Dictionary <string, PublishedAllocationLineResultStatusUpdateProviderModel> updateProviders = new Dictionary <string, PublishedAllocationLineResultStatusUpdateProviderModel>(); foreach (PublishedAllocationLineResultStatusUpdateProviderViewModel updateItem in allocationLines.Providers) { PublishedAllocationLineResultStatusUpdateProviderModel providerUpdateModel = null; if (!updateProviders.ContainsKey(updateItem.ProviderId)) { providerUpdateModel = new PublishedAllocationLineResultStatusUpdateProviderModel() { ProviderId = updateItem.ProviderId, }; updateProviders.Add(updateItem.ProviderId, providerUpdateModel); updateModel.AddProvider(providerUpdateModel); } else { providerUpdateModel = updateProviders[updateItem.ProviderId]; } providerUpdateModel.AddAllocationLine(updateItem.AllocationLineId); } await _resultsClient.UpdatePublishedAllocationLineStatus(specificationId, updateModel); return(Ok()); }
public async Task Specifications_SecurityTrimList_WhenUserDoesNotHaveAccessToAllFundingStreams_ThenReturnEmpty() { // Arrange IEnumerable <SpecificationSummary> specifications = new List <SpecificationSummary> { new SpecificationSummary { Id = "spec1", FundingStreams = new List <PolicyModels.FundingStream> { new PolicyModels.FundingStream { Id = "fs1" }, new PolicyModels.FundingStream { Id = "fs2" } } } }; string userId = "testuser"; ClaimsPrincipal user = BuildClaimsPrincipal(userId); SpecificationActionTypes permissionRequired = SpecificationActionTypes.CanCreateQaTests; ApiResponse <IEnumerable <FundingStreamPermission> > permissionsResponse = new ApiResponse <IEnumerable <FundingStreamPermission> >(HttpStatusCode.OK, new List <FundingStreamPermission> { new FundingStreamPermission { FundingStreamId = "fs1", CanCreateQaTests = true }, new FundingStreamPermission { FundingStreamId = "fs2", CanCreateQaTests = false }, new FundingStreamPermission { FundingStreamId = "fs3", CanCreateQaTests = true } }); IAuthorizationService authorizationService = Substitute.For <IAuthorizationService>(); IUsersApiClient usersClient = Substitute.For <IUsersApiClient>(); usersClient .GetFundingStreamPermissionsForUser(userId) .Returns(permissionsResponse); AuthorizationHelper authHelper = CreateAuthenticationHelper(authorizationService, usersClient); // Act IEnumerable <SpecificationSummary> results = await authHelper.SecurityTrimList(user, specifications, permissionRequired); // Assert results.Should().BeEmpty(); }
public async Task <IEnumerable <SpecificationSummary> > SecurityTrimList(ClaimsPrincipal user, IEnumerable <SpecificationSummary> specifications, SpecificationActionTypes permissionRequired) { Guard.ArgumentNotNull(user, nameof(user)); Guard.ArgumentNotNull(specifications, nameof(specifications)); if (IsAdminUser(user)) { return(specifications); } string userId = VerifyObjectIdentifierClaimTypePresent(user); ApiResponse <IEnumerable <FundingStreamPermission> > fundingStreamPermissionsResponse = await _usersClient.GetFundingStreamPermissionsForUser(userId); if (fundingStreamPermissionsResponse.StatusCode != HttpStatusCode.OK) { _logger.Error("Failed to get funding stream permissions for user for security trimming ({user}) - {statuscode}", user.Identity.Name, fundingStreamPermissionsResponse.StatusCode); return(Enumerable.Empty <SpecificationSummary>()); } IEnumerable <FundingStreamPermission> allowedFundingStreams = fundingStreamPermissionsResponse.Content; if (permissionRequired == SpecificationActionTypes.CanCreateQaTests) { allowedFundingStreams = allowedFundingStreams.Where(p => p.CanCreateQaTests); } else if (permissionRequired == SpecificationActionTypes.CanChooseFunding) { allowedFundingStreams = allowedFundingStreams.Where(p => p.CanChooseFunding); } else { throw new NotSupportedException( $"Security trimming specifications by this permission ({permissionRequired} is not currently supported"); } IEnumerable <string> allowedFundingStreamIds = allowedFundingStreams.Select(p => p.FundingStreamId); return(specifications.Where(s => !s.FundingStreams.Select(fs => fs.Id).Except(allowedFundingStreamIds).Any())); }
public async Task <bool> DoesUserHavePermission(ClaimsPrincipal user, string specificationId, SpecificationActionTypes permissionRequired) { AuthorizationResult authorizationResult = await _authorizationService.AuthorizeAsync(user, specificationId, new SpecificationRequirement(permissionRequired)); return(authorizationResult.Succeeded); }
private AuthorizationHandlerContext CreateAuthenticationContext(ClaimsPrincipal principal, SpecificationActionTypes permissionRequired, ISpecificationAuthorizationEntity resource) { SpecificationRequirement requirement = new SpecificationRequirement(permissionRequired); return(new AuthorizationHandlerContext(new[] { requirement }, principal, resource)); }
public async Task <IEnumerable <SpecificationSummary> > SecurityTrimList(ClaimsPrincipal user, IEnumerable <SpecificationSummary> specifications, SpecificationActionTypes permissionRequired) { Guard.ArgumentNotNull(user, nameof(user)); Guard.ArgumentNotNull(specifications, nameof(specifications)); return(await Task.FromResult(specifications)); }
public async Task <bool> DoesUserHavePermission(ClaimsPrincipal user, string specificationId, SpecificationActionTypes permissionRequired) { return(await Task.FromResult(true)); }
public async Task Specifications_SecurityTrimListForChooseFunding_WhenUserHasAccessToSome_ThenReturnCorrectSpecifications() { // Arrange const string spec1Id = "spec1"; const string spec3Id = "spec3"; IEnumerable <SpecificationSummary> specifications = new List <SpecificationSummary> { new SpecificationSummary { Id = spec1Id, FundingStreams = new List <PolicyModels.FundingStream> { new PolicyModels.FundingStream { Id = "fs1" } } }, new SpecificationSummary { Id = "spec2", FundingStreams = new List <PolicyModels.FundingStream> { new PolicyModels.FundingStream { Id = "fs2" } } }, new SpecificationSummary { Id = spec3Id, FundingStreams = new List <PolicyModels.FundingStream> { new PolicyModels.FundingStream { Id = "fs3" } } } }; string userId = "testuser"; ClaimsPrincipal user = BuildClaimsPrincipal(userId); SpecificationActionTypes permissionRequired = SpecificationActionTypes.CanChooseFunding; ApiResponse <IEnumerable <FundingStreamPermission> > permissionsResponse = new ApiResponse <IEnumerable <FundingStreamPermission> >(HttpStatusCode.OK, new List <FundingStreamPermission> { new FundingStreamPermission { FundingStreamId = "fs1", CanChooseFunding = true }, new FundingStreamPermission { FundingStreamId = "fs2", CanChooseFunding = false }, new FundingStreamPermission { FundingStreamId = "fs3", CanChooseFunding = true } }); IAuthorizationService authorizationService = Substitute.For <IAuthorizationService>(); IUsersApiClient usersClient = Substitute.For <IUsersApiClient>(); usersClient .GetFundingStreamPermissionsForUser(userId) .Returns(permissionsResponse); AuthorizationHelper authHelper = CreateAuthenticationHelper(authorizationService, usersClient); // Act IEnumerable <SpecificationSummary> results = await authHelper.SecurityTrimList(user, specifications, permissionRequired); // Assert results.Should().HaveCount(2); results .Any(s => s.Id == spec1Id) .Should() .BeTrue(); results .Any(s => s.Id == spec1Id) .Should() .BeTrue(); }
public SpecificationRequirement(SpecificationActionTypes specificationAction) { ActionType = specificationAction; }
public async Task <bool> DoesUserHavePermission(ClaimsPrincipal user, string specificationId, SpecificationActionTypes permissionRequired) { SpecificationAuthorizationEntity entity = new SpecificationAuthorizationEntity(specificationId); return(await DoesUserHavePermission(user, entity, permissionRequired)); }