Пример #1
0
        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));
            }
        }
Пример #2
0
        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)));
        }
Пример #6
0
        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));
            }
        }
Пример #11
0
        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
                                                          ));
        }
Пример #12
0
        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
                                                          ));
        }
Пример #13
0
        public async Task <HttpStatusCode> UpdateFundingStreamPermission(FundingStreamPermission fundingStreamPermission)
        {
            Guard.ArgumentNotNull(fundingStreamPermission, nameof(fundingStreamPermission));

            return(await _cosmosRepository.UpsertAsync(fundingStreamPermission, fundingStreamPermission.UserId));
        }
Пример #14
0
        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));
        }
Пример #15
0
        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}"));
        }
Пример #16
0
 private void GivenTheUserHasPermissionToUploadDataSourceFilesForFundingStream(string fundingSteamId,
                                                                               FundingStreamPermission fundingStreamPermission)
 => _authorisationHelper
 .Setup(_ => _.GetUserFundingStreamPermissions(It.IsAny <ClaimsPrincipal>(), fundingSteamId))
 .ReturnsAsync(fundingStreamPermission);