Esempio n. 1
0
        /// <summary>
        /// Gets all projects for which the current user has access to. Can include archived projects. Can skip decryption.
        /// </summary>
        /// <returns>A list of Project objects</returns>
        public async Task <List <Project> > GetProjects(bool skipDecryption = false, bool includeArchived = false)
        {
            // Get user to validate access
            var currentUser = await _applicationIdentityService.GetCurrentUser();

            if (currentUser == null)
            {
                throw new Exception("Unauthorised requests are not allowed.");
            }

            if (await _applicationIdentityService.IsCurrentUserAdmin())
            {
                return(await GetProjectsForAdmin(skipDecryption));
            }

            // Get projects with access
            // TODO: attempt to make this in 1 query
            var projects = new List <Project>();

            if (includeArchived) // filter out archived
            {
                projects = await _dbContext.Projects
                           .Include(p => p.AccessIdentifiers)
                           .ToListAsync();
            }
            else
            {
                projects = await _dbContext.Projects
                           .Where(p => p.IsArchived == false)
                           .Include(p => p.AccessIdentifiers)
                           .ToListAsync();
            }

            // filter our those without access for the current user
            var projectsWithAccess = projects.Where(p =>
                                                    p.AccessIdentifiers.Any(ai => ai.Identity != null && ai.Identity.Id == currentUser.Id))
                                     .ToList();

            if (projectsWithAccess == null)
            {
                return(null);
            }

            foreach (var project in projectsWithAccess)
            {
                project.IsDecrypted = false;
            }

            if (skipDecryption == false) // double false...
            {
                foreach (var project in projectsWithAccess)
                {
                    project.IsDecrypted = false;
                    DecryptProject(project);
                }
            }

            return(projectsWithAccess.ToList());
        }
Esempio n. 2
0
        /// <summary>
        /// Sets an Assets archive status to true in the DB.
        /// </summary>
        /// <param name="projectId">The project Id of the project owning the Asset</param>
        /// <param name="assetId">The Asset Id of the asset to archive</param>
        /// <returns>A Task result</returns>
        public async Task ArchiveAssetAsync(int projectId, int assetId, string remoteIpAddress)
        {
            // Validate
            if (string.IsNullOrWhiteSpace(remoteIpAddress))
            {
                throw new ArgumentException("You must provide a valid IP address.");
            }
            if (projectId < 1)
            {
                throw new ArgumentException("You must pass a valid project id.");
            }
            if (assetId < 1)
            {
                throw new ArgumentException("You must pass a valid asset id.");
            }

            // Validate current user
            var currentUser = await _applicationIdentityService.GetCurrentUser();

            if (currentUser == null)
            {
                throw new Exception("Unauthorised requests are not allowed.");
            }
            ;

            // Get Asset from DB with a permission and project check
            var retrievedAsset = await _dbContext.Assets.Where(a =>
                                                               a.Id == assetId &&
                                                               a.IsArchived == false &&
                                                               a.Project.Id == projectId &&
                                                               a.Project.AccessIdentifiers.Any(ai => ai.Identity.Id == currentUser.Id))
                                 .Include(p => p.Project.AccessIdentifiers)
                                 .ThenInclude(p => p.Identity) // NOTE: intellisense doesn't work here (23.09.2017) https://github.com/dotnet/roslyn/issues/8237
                                 .FirstOrDefaultAsync();

            if (retrievedAsset == null)
            {
                throw new Exception("The asset was not found or the current user does not have access to it.");
            }

            // Refresh the entity to discard changes and avoid saving a decrypted project
            _dbContext.Entry(retrievedAsset).State         = EntityState.Unchanged;
            _dbContext.Entry(retrievedAsset.Project).State = EntityState.Unchanged;
            retrievedAsset.IsArchived = true;

            // Set modified time/user
            retrievedAsset.Modified   = DateTime.UtcNow;
            retrievedAsset.ModifiedBy = currentUser;

            // LOG event

            var updatedRowCount = await _dbContext.SaveChangesAsync();

            if (updatedRowCount > 1)
            {
                // we have a problem
            }
        }
        public async Task <JsonResult> ExportDatabase()
        {
            var currentUser = await _applicationIdentityService.GetCurrentUser();

            if (currentUser == null)
            {
                return(new JsonResult("Unathorised"));
            }

            if (await _applicationIdentityService.IsCurrentUserAdmin() == false)
            {
                return(new JsonResult("Unathorised"));
            }

            var allProjects = await _projectsService.GetProjects();

            foreach (var project in allProjects)
            {
                await _assetService.LoadAssetsAsync(project);

                foreach (var asset in project.Assets)
                {
                    if (asset.GetType() == typeof(Credential))
                    {
                        var credential = asset as Credential;
                        credential.Password = _assetService.DecryptPassword(credential.Password);
                    }
                }
            }

            return(Json(allProjects, new Newtonsoft.Json.JsonSerializerSettings()
            {
                TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All,
                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
            }));
        }
Esempio n. 4
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
            });
        }