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);
        }
Exemplo n.º 10
0
        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();
        }
Exemplo n.º 12
0
        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());
        }