public async Task WhenUserCanCreateSpecification_ShouldSucceed() { // 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 = true, 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().BeTrue(); }
public async Task WhenUserIsKnown_AndHasNoPermissions_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, fundingStreamIds); IUsersApiClient usersApiClient = Substitute.For <IUsersApiClient>(); usersApiClient.GetFundingStreamPermissionsForUser(Arg.Is(userId)).Returns(new ApiResponse <IEnumerable <FundingStreamPermission> >(HttpStatusCode.OK, Enumerable.Empty <FundingStreamPermission>())); IOptions <PermissionOptions> options = Substitute.For <IOptions <PermissionOptions> >(); options.Value.Returns(actualOptions); IFeatureToggle features = CreateFeatureToggle(true); FundingStreamPermissionHandler authHandler = new FundingStreamPermissionHandler(usersApiClient, options, features); // 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 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(); }
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 FundingStreams_SecurityTrimList_WhenUserHasAccessToSome_ThenReturnSome() { // Arrange IEnumerable <PolicyModels.FundingStream> fundingStreamIds = new List <PolicyModels.FundingStream> { new PolicyModels.FundingStream { Id = "fs1" }, new PolicyModels.FundingStream { Id = "fs2" }, new PolicyModels.FundingStream { Id = "fs3" } }; string userId = "testuser"; ClaimsPrincipal user = BuildClaimsPrincipal(userId); FundingStreamActionTypes permissionRequired = FundingStreamActionTypes.CanCreateSpecification; ApiResponse <IEnumerable <FundingStreamPermission> > permissionsResponse = new ApiResponse <IEnumerable <FundingStreamPermission> >(HttpStatusCode.OK, new List <FundingStreamPermission> { new FundingStreamPermission { FundingStreamId = "fs1", CanCreateSpecification = false }, 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 IEnumerable <PolicyModels.FundingStream> results = await authHelper.SecurityTrimList(user, fundingStreamIds, permissionRequired); // Assert results.Should().HaveCount(1); results.Should().Contain(r => r.Id == "fs2"); }
public async Task DoesUserHavePermission_WhenUserHasAccessToNone_ThenReturnFalse() { // Arrange IEnumerable <string> fundingStreamIds = new List <string> { "fs1", "fs2", "fs3" }; string userId = "testuser"; ClaimsPrincipal user = BuildClaimsPrincipal(userId); FundingStreamActionTypes permissionRequired = FundingStreamActionTypes.CanCreateSpecification; 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", CanCreateSpecification = false }, new Common.ApiClient.Users.Models.FundingStreamPermission { FundingStreamId = "fs2", CanCreateSpecification = false }, new Common.ApiClient.Users.Models.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 bool result = await authHelper.DoesUserHavePermission(user, fundingStreamIds, permissionRequired); // Assert result.Should().BeFalse(); }
public async Task WhenUserApproveCalculationForDifferentFundingStreams_AndDifferentPermissions_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, "fs2", "fs3" }; AuthorizationHandlerContext authContext = CreateAuthenticationContext(principal, FundingStreamActionTypes.CanApproveCalculations, fundingStreamIds); List <FundingStreamPermission> actualPermissions = new List <FundingStreamPermission> { new FundingStreamPermission { CanApproveCalculations = true, FundingStreamId = "fs4" }, new FundingStreamPermission { CanApproveCalculations = false, FundingStreamId = "fs5" }, new FundingStreamPermission { CanApproveCalculations = true, FundingStreamId = "fs6" } }; IUsersApiClient usersApiClient = Substitute.For <IUsersApiClient>(); usersApiClient.GetFundingStreamPermissionsForUser(Arg.Is(userId)).Returns(new ApiResponse <IEnumerable <FundingStreamPermission> >(HttpStatusCode.OK, actualPermissions)); 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 <IEnumerable <FundingStreamPermission> > GetUserFundingStreamPermissions(ClaimsPrincipal user) { Guard.ArgumentNotNull(user, nameof(user)); string userId = VerifyObjectIdentifierClaimTypePresent(user); if (IsAdminUser(user)) { ApiResponse <IEnumerable <PolicyModels.FundingStream> > fundingStreamsResponse = await _policyClient.GetFundingStreams(); if (fundingStreamsResponse.StatusCode == HttpStatusCode.OK) { List <FundingStreamPermission> permissions = new List <FundingStreamPermission>(); foreach (PolicyModels.FundingStream fundingStream in fundingStreamsResponse.Content) { permissions.Add(new FundingStreamPermission { FundingStreamId = fundingStream.Id, CanAdministerFundingStream = true, CanApproveFunding = true, CanApproveSpecification = true, CanChooseFunding = true, CanCreateQaTests = true, CanCreateSpecification = true, CanEditCalculations = true, CanEditQaTests = true, CanEditSpecification = true, CanMapDatasets = true, CanReleaseFunding = true, CanRefreshFunding = true, CanCreateTemplates = true, CanEditTemplates = true, CanDeleteTemplates = true, CanApproveTemplates = true, CanApplyCustomProfilePattern = true, CanApproveAnyCalculations = true, CanApproveCalculations = true, CanAssignProfilePattern = true, CanCreateProfilePattern = true, CanDeleteCalculations = true, CanDeleteProfilePattern = true, CanDeleteQaTests = true, CanDeleteSpecification = true, CanEditProfilePattern = true, CanApproveAllCalculations = true, CanRefreshPublishedQa = true, CanUploadDataSourceFiles = true, UserId = user.GetUserProfile()?.Id }); } return(permissions); } } ApiResponse <IEnumerable <FundingStreamPermission> > fundingStreamPermissionsResponse = await _usersClient.GetFundingStreamPermissionsForUser(userId); if (fundingStreamPermissionsResponse.StatusCode != HttpStatusCode.OK) { _logger.Error("Failed to get funding stream permissions for user ({user}) - {statuscode}", user.Identity.Name, fundingStreamPermissionsResponse.StatusCode); return(new List <FundingStreamPermission>()); } return(fundingStreamPermissionsResponse.Content); }
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, FundingStreamRequirement requirement, IEnumerable <string> resource) { // If user belongs to the admin group then allow them access if (context.User.HasClaim(c => c.Type == Constants.GroupsClaimType && c.Value.ToLowerInvariant() == _permissionOptions.AdminGroupId.ToString().ToLowerInvariant())) { context.Succeed(requirement); } else { // Get user permissions for funding stream if (context.User.HasClaim(c => c.Type == Constants.ObjectIdentifierClaimType)) { string userId = context.User.FindFirst(Constants.ObjectIdentifierClaimType).Value; ApiResponse <IEnumerable <FundingStreamPermission> > permissionsResponse = await _usersApiClient.GetFundingStreamPermissionsForUser(userId); if (permissionsResponse == null || permissionsResponse.StatusCode != HttpStatusCode.OK) { throw new Exception($"Error calling the permissions service - {permissionsResponse.StatusCode}"); } // Check user has permissions for funding stream if (HasPermissionToAllFundingStreams(resource, requirement.ActionType, permissionsResponse.Content)) { context.Succeed(requirement); } } } }
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 async Task <bool> DoesUserHavePermission(ClaimsPrincipal user, IEnumerable <string> fundingStreamIds, FundingStreamActionTypes permissionRequired) { Guard.ArgumentNotNull(user, nameof(user)); Guard.ArgumentNotNull(fundingStreamIds, nameof(fundingStreamIds)); if (user.HasClaim(c => c.Type == Common.Identity.Constants.GroupsClaimType && c.Value.ToLowerInvariant() == _permissionOptions.AdminGroupId.ToString().ToLowerInvariant())) { return(true); } string userId = VerifyObjectIdentifierClaimTypePresent(user); ApiResponse <IEnumerable <Common.ApiClient.Users.Models.FundingStreamPermission> > fundingStreamPermissionsResponse = await _usersClient.GetFundingStreamPermissionsForUser(userId); if (fundingStreamPermissionsResponse.StatusCode != HttpStatusCode.OK) { _logger.Error("Failed to get funding stream permissions for user ({user}) - {statuscode}", user.Identity.Name, fundingStreamPermissionsResponse.StatusCode); return(false); } IEnumerable <Common.ApiClient.Users.Models.FundingStreamPermission> allowedFundingStreams = fundingStreamPermissionsResponse.Content; if (permissionRequired == FundingStreamActionTypes.CanCreateSpecification) { allowedFundingStreams = allowedFundingStreams.Where(p => p.CanCreateSpecification); } else if (permissionRequired == FundingStreamActionTypes.CanChooseFunding) { allowedFundingStreams = allowedFundingStreams.Where(p => p.CanChooseFunding); } IEnumerable <string> allowedFundingStreamIds = allowedFundingStreams.Select(p => p.FundingStreamId); return(!fundingStreamIds.Except(allowedFundingStreamIds).Any()); }