Exemple #1
0
        public async void CreateProject_ShouldReturnCorrectAccess()
        {
            // Arrange
            _fakeHttpContextItems.Add(ApplicationIdentityService.CURRENTUSERKEY, _testUser);

            var newDecryptedProject = CreateTestProject();

            AccessIdentifier accessIdentifier1 = new AccessIdentifier();

            accessIdentifier1.Role     = TeamStore.Keeper.Enums.Role.Editor;
            accessIdentifier1.Identity = new ApplicationUser()
            {
                AzureAdNameIdentifier   = "TestAdIdentity1",
                AzureAdObjectIdentifier = "TestAdObjectId1",
                TenantId = "1234",
                Upn      = "*****@*****.**"
            };

            AccessIdentifier accessIdentifier2 = new AccessIdentifier();

            accessIdentifier2.Role     = TeamStore.Keeper.Enums.Role.Owner;
            accessIdentifier2.Identity = new ApplicationGroup()
            {
                DisplayName             = "TestGroup1",
                AzureAdObjectIdentifier = "TestAdObjectId1",
                TenantId = "1234"
            };

            newDecryptedProject.AccessIdentifiers.Add(accessIdentifier1);
            newDecryptedProject.AccessIdentifiers.Add(accessIdentifier2);

            // Act
            var createdProjectId = await _projectsService.CreateProject(newDecryptedProject);

            var retrievedProject = await _projectsService.GetProject(createdProjectId);

            // Assert
            Assert.True(retrievedProject.Id > 0);
            Assert.False(retrievedProject.IsArchived);
            Assert.Equal(3, retrievedProject.AccessIdentifiers.Count); // +1 for the Owner
            Assert.NotNull(retrievedProject.AccessIdentifiers.First());
            Assert.NotNull(retrievedProject.AccessIdentifiers.First().Project);
            Assert.True(retrievedProject.AccessIdentifiers.First().ProjectForeignKey > 0);
            Assert.Equal(Role.Editor, retrievedProject.AccessIdentifiers.First().Role);
            Assert.NotEqual(Role.Reader, retrievedProject.AccessIdentifiers.First().Role);
            Assert.IsType <ApplicationUser>(retrievedProject.AccessIdentifiers.First().Identity);
            Assert.Equal("1234", retrievedProject.AccessIdentifiers.First().Identity.TenantId);
            Assert.Equal("TestAdObjectId1", retrievedProject.AccessIdentifiers.First().Identity.AzureAdObjectIdentifier);
            Assert.Equal("*****@*****.**", ((ApplicationUser)retrievedProject.AccessIdentifiers.First().Identity).Upn);
            Assert.Equal("TestAdIdentity1", ((ApplicationUser)retrievedProject.AccessIdentifiers.First().Identity).AzureAdNameIdentifier);

            // Cleanup
            await _projectsService.ArchiveProject(retrievedProject, "127.0.1.1");

            var archivedProject = await _projectsService.GetProject(createdProjectId);

            Assert.Null(archivedProject);
        }
        private static AccessIdentifierViewModel BuildAccessIdentityViewModel(AccessIdentifier accessIdentifier)
        {
            var newAccessIdentifierViewModel = new AccessIdentifierViewModel();
            var appIdentity = (ApplicationUser)accessIdentifier.Identity;

            newAccessIdentifierViewModel.DisplayName  = appIdentity.DisplayName;
            newAccessIdentifierViewModel.Role         = accessIdentifier.Role;
            newAccessIdentifierViewModel.Upn          = appIdentity.Upn;
            newAccessIdentifierViewModel.LastModified = accessIdentifier.Modified == DateTime.MinValue ? accessIdentifier.Created : accessIdentifier.Modified;

            return(newAccessIdentifierViewModel);
        }
Exemple #3
0
        /// <summary>
        /// Grants access to a project
        /// </summary>
        /// <param name="projectId">The Id of the project</param>
        /// <param name="upn">The UPN identifier of the identity for which access will be granted to</param>
        /// <param name="role">The role/level of access that will be granted</param>
        /// <param name="remoteIpAddress">The IP address of the incoming request</param>
        /// <param name="projectsService">An instance of IProjectService to assist with resolving of the project</param>
        /// <returns>A Task object with an AccessChangeResult representing the result</returns>
        public async Task <AccessChangeResult> GrantAccessAsync(
            int projectId,
            string upn,
            Role role,
            string remoteIpAddress,
            IProjectsService projectsService)
        {
            if (string.IsNullOrWhiteSpace(upn))
            {
                throw new ArgumentNullException(nameof(upn));
            }
            if (string.IsNullOrWhiteSpace(remoteIpAddress))
            {
                throw new ArgumentNullException(nameof(remoteIpAddress));
            }
            if (projectId == 0)
            {
                throw new ArgumentException("You must provide a valid project id.");
            }
            var currentUser = await _applicationIdentityService.GetCurrentUser();

            if (currentUser == null)
            {
                throw new ArgumentException("The current user could not be retrieved.");
            }

            // Get/find the project
            var project = await projectsService.GetProject(projectId, true);

            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            // Refresh the entity to discard changes and avoid saving a decrypted project
            if (project.IsDecrypted == true)
            {
                _dbContext.Entry(project).State = EntityState.Unchanged; // project will be encrypted here
            }

            // Verify current user has permissions to grant access, aka Owner
            if (await CurrentUserHasAccessAsync(projectId, projectsService, Role.Owner) == false)
            {
                await _eventService.LogCustomEventAsync(currentUser.Id.ToString(), $"User {currentUser.Upn} attepted to give access to {upn} without having access to project with ID: {projectId}.");

                throw new Exception("The current user does not have permissions to grant access.");
            }

            // Check if the target user already has access
            if (CheckAccess(project, upn, Role.Owner))
            {
                await _eventService.LogCustomEventAsync(currentUser.Id.ToString(), $"The user {currentUser.Upn} attepted to give access to {upn} who already has access to project with ID: {projectId}.");

                return(new AccessChangeResult()
                {
                    Success = false, Message = $"User {upn} already has access."
                });                                                                                               // no need to grant
            }

            // TODO: grant access to AD group
            var newAccessIdentifier = new AccessIdentifier();

            newAccessIdentifier.Project   = project ?? throw new ArgumentNullException(nameof(project));
            newAccessIdentifier.Role      = role;
            newAccessIdentifier.Created   = DateTime.UtcNow;
            newAccessIdentifier.CreatedBy = currentUser ?? throw new ArgumentNullException(nameof(currentUser));
            newAccessIdentifier.Identity  = await _applicationIdentityService.EnsureUserByUpnAsync(upn);

            project.AccessIdentifiers.Add(newAccessIdentifier);

            // Validation of the access identifiers before save
            foreach (var item in project.AccessIdentifiers)
            {
                if ((item.Identity == null))
                {
                    await _eventService.LogCustomEventAsync(currentUser.Upn, $"Ensure did not return a user for {upn}");

                    return(new AccessChangeResult()
                    {
                        Success = false, Message = $"The user or group '{upn}' was not found."
                    });
                }
            }

            // Save Grant event
            // Issue: LogGrantAccessEventAsync calls SaveChanges.
            await _eventService.LogGrantAccessEventAsync(projectId, remoteIpAddress, role, newAccessIdentifier.Identity.Id, currentUser.Id, "UPN: " + upn);

            var modifiedRows = await _dbContext.SaveChangesAsync();

            return(new AccessChangeResult()
            {
                Success = true
            });
        }