Пример #1
0
        /// <summary>
        /// Update the specified user in keycloak and PIMS, only add and roles.
        /// </summary>
        /// <param name="user"></param>
        /// <exception type="KeyNotFoundException">User does not exist in keycloak or PIMS.</exception>
        /// <returns></returns>
        public async Task <Entity.PimsUser> AppendToUserAsync(Entity.PimsUser update)
        {
            var kuser = await _keycloakService.GetUserAsync(update.GuidIdentifierValue.Value) ?? throw new KeyNotFoundException("User does not exist in Keycloak");

            var euser = _pimsRepository.User.GetTracking(update.Id);

            IEnumerable <long> addRoleIds = update.PimsUserRoles.Except(euser.PimsUserRoles, new UserRoleRoleIdComparer()).Select(r => r.RoleId).ToArray();

            var roleIds = update.PimsUserRoles.Select(r => r.RoleId);

            foreach (var roleId in roleIds)
            {
                var role = _pimsRepository.Role.Find(roleId) ?? throw new KeyNotFoundException("Cannot assign a role to a user, when the role does not exist.");
                if (role.KeycloakGroupId == null)
                {
                    throw new KeyNotFoundException("PIMS has not been synced with Keycloak.");
                }
                _logger.LogInformation($"Adding keycloak group '{role.Name}' to user '{euser.BusinessIdentifierValue}'.");
                await _keycloakService.AddGroupToUserAsync(update.GuidIdentifierValue.Value, role.KeycloakGroupId.Value);
            }

            addRoleIds.ForEach(r =>
            {
                var role = _pimsRepository.Role.Find(r) ?? throw new KeyNotFoundException("Cannot assign a role to a user, when the role does not exist.");
                if (role.KeycloakGroupId == null)
                {
                    throw new KeyNotFoundException("PIMS has not been synced with Keycloak.");
                }
                euser.PimsUserRoles.Add(new Entity.PimsUserRole(euser, role));
            });

            return(await SaveUserChanges(update, euser, kuser));
        }
Пример #2
0
        /// <summary>
        /// Create a new instance of an AccessRequest for a default user.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="keycloakUserId"></param>
        /// <param name="username"></param>
        /// <param name="firstName"></param>
        /// <param name="lastName"></param>
        /// <param name="person"></param>
        /// <param name="role"></param>
        /// <param name="organization"></param>
        /// <returns></returns>
        public static Entity.PimsUser CreateUser(long id, Guid keycloakUserId, string username, string firstName = "given name", string lastName = "surname", Entity.PimsRole role = null, Entity.PimsOrganization organization = null, Entity.PimsAddress address = null)
        {
            organization ??= EntityHelper.CreateOrganization(id, "Organization 1");
            role ??= EntityHelper.CreateRole("Real Estate Manager");
            var person = new Entity.PimsPerson(lastName, firstName, address);

            person.PimsContactMethods = new List <Entity.PimsContactMethod>();
            var user = new Entity.PimsUser(keycloakUserId, username, person)
            {
                Id        = id,
                IssueDate = DateTime.UtcNow,
                ConcurrencyControlNumber = 1
            };

            user.PimsUserRoles.Add(new Entity.PimsUserRole()
            {
                Role = role, RoleId = role.Id, User = user, UserId = user.Id
            });
            user.PimsUserOrganizations.Add(new Entity.PimsUserOrganization()
            {
                Organization = organization, OrganizationId = organization.Id, User = user, UserId = user.Id
            });

            return(user);
        }
Пример #3
0
        public void GetMyUsers_Success()
        {
            // Arrange
            var helper     = new TestHelper();
            var controller = helper.CreateController <UserController>(Permissions.AdminUsers);

            var mapper  = helper.GetService <IMapper>();
            var service = helper.GetService <Mock <IPimsRepository> >();
            var users   = new Entity.PimsUser[] { EntityHelper.CreateUser("user1"), EntityHelper.CreateUser("user2") };
            var paged   = new Entity.Models.Paged <Entity.PimsUser>(users);
            var filter  = new Entity.Models.UserFilter(1, 1, "organization", "username", "lastname", "firstname", "email", false, "role", null, "position");

            service.Setup(m => m.User.Get(It.IsAny <Entity.Models.UserFilter>())).Returns(paged);

            // Act
            var result = controller.GetMyUsers(filter);

            // Assert
            var actionResult = Assert.IsType <JsonResult>(result);

            Assert.Null(actionResult.StatusCode);
            var actualResult = Assert.IsType <Pims.Api.Models.PageModel <Model.UserModel> >(actionResult.Value);

            Assert.Equal(mapper.Map <Model.UserModel[]>(users), actualResult.Items, new DeepPropertyCompare());
            service.Verify(m => m.User.Get(It.IsAny <Entity.Models.UserFilter>()), Times.Once());
        }
Пример #4
0
        /// <summary>
        /// Update the specified user in keycloak and PIMS.
        /// </summary>
        /// <param name="user"></param>
        /// <exception type="KeyNotFoundException">User does not exist in keycloak or PIMS.</exception>
        /// <returns></returns>
        public async Task <Entity.PimsUser> UpdateUserAsync(Entity.PimsUser user)
        {
            var kuser = await _keycloakService.GetUserAsync(user.GuidIdentifierValue.Value) ?? throw new KeyNotFoundException("User does not exist in Keycloak");

            var euser = _pimsRepository.User.GetTracking(user.Id);

            IEnumerable <long> addRoleIds;
            IEnumerable <long> removeRoleIds;

            addRoleIds    = user.PimsUserRoles.Except(euser.PimsUserRoles, new UserRoleRoleIdComparer()).Select(r => r.RoleId).ToArray();
            removeRoleIds = euser.PimsUserRoles.Except(user.PimsUserRoles, new UserRoleRoleIdComparer()).Select(r => r.RoleId).ToArray();

            // Update Roles.
            removeRoleIds.ForEach(r =>
            {
                var role = _pimsRepository.Role.Find(r) ?? throw new KeyNotFoundException("Cannot remove a role from a user, when the role does not exist.");
                if (role.KeycloakGroupId == null)
                {
                    throw new KeyNotFoundException("PIMS has not been synced with Keycloak.");
                }
                euser = _pimsRepository.User.RemoveRole(euser, role.RoleId);
            });
            addRoleIds.ForEach(r =>
            {
                var role = _pimsRepository.Role.Find(r) ?? throw new KeyNotFoundException("Cannot assign a role to a user, when the role does not exist.");
                if (role.KeycloakGroupId == null)
                {
                    throw new KeyNotFoundException("PIMS has not been synced with Keycloak.");
                }
                euser.PimsUserRoles.Add(new Entity.PimsUserRole(euser, role));
            });

            return(await SaveUserChanges(user, euser, kuser, true));
        }
Пример #5
0
        /// <summary>
        /// Save the updated user in keycloak and database.
        /// </summary>
        /// <param name="update"></param>
        /// <param name="euser"></param>
        /// <param name="kuser"></param>
        /// <returns></returns>
        private async Task <Entity.PimsUser> SaveUserChanges(Entity.PimsUser update, Entity.PimsUser euser, KModel.UserModel kuser, bool resetRoles = false)
        {
            // Update PIMS
            euser.BusinessIdentifierValue = kuser.Username; // PIMS must use whatever username is set in keycloak.
            euser.Person.FirstName        = update.Person.FirstName;
            euser.Person.MiddleNames      = update.Person.MiddleNames;
            euser.Person.Surname          = update.Person.Surname;
            euser.Position   = update.Position;
            euser.Note       = update.Note;
            euser.IsDisabled = update.IsDisabled;
            euser.ConcurrencyControlNumber = update.ConcurrencyControlNumber;

            //TODO: currently the PIMS contact method screen does not support the concept of multiple contact methods, so for now simply overwrite any work email addresses.
            euser.Person.PimsContactMethods.RemoveAll(c => c.ContactMethodTypeCode == ContactMethodTypes.WorkEmail);
            update.Person.PimsContactMethods.ForEach(c =>
            {
                euser.Person.PimsContactMethods.Add(new PimsContactMethod(c.Person, c.Organization, c.ContactMethodTypeCode, c.ContactMethodValue));
            });

            euser = _pimsRepository.User.UpdateOnly(euser);

            // Now update keycloak
            var kmodel = _mapper.Map <KModel.UserModel>(update);

            if (resetRoles)
            {
                // Remove all keycloak groups from user.  // TODO: Only add/remove the ones that should be removed.
                var userGroups = await _keycloakService.GetUserGroupsAsync(euser.GuidIdentifierValue.Value);

                foreach (var group in userGroups)
                {
                    await _keycloakService.RemoveGroupFromUserAsync(update.GuidIdentifierValue.Value, group.Id);
                }
            }

            var roleIds = update.PimsUserRoles.Select(r => r.RoleId);

            foreach (var roleId in roleIds)
            {
                var role = _pimsRepository.Role.Find(roleId) ?? throw new KeyNotFoundException("Cannot assign a role to a user, when the role does not exist.");
                if (role.KeycloakGroupId == null)
                {
                    throw new KeyNotFoundException("PIMS has not been synced with Keycloak.");
                }
                _logger.LogInformation($"Adding keycloak group '{role.Name}' to user '{euser.BusinessIdentifierValue}'.");
                await _keycloakService.AddGroupToUserAsync(update.GuidIdentifierValue.Value, role.KeycloakGroupId.Value);
            }

            kmodel.Attributes = new Dictionary <string, string[]>
            {
                ["displayName"] = new[] { update.BusinessIdentifierValue }
            };
            _logger.LogInformation($"Updating keycloak user '{euser.BusinessIdentifierValue}'.");
            await _keycloakService.UpdateUserAsync(kmodel);

            return(_pimsRepository.User.Get(euser.Id));
        }
Пример #6
0
 /// <summary>
 /// Create a new instance of a UserOrganization class.
 /// </summary>
 /// <param name="user"></param>
 /// <param name="organization"></param>
 /// <param name="role"></param>
 public PimsUserOrganization(PimsUser user, PimsOrganization organization, PimsRole role)
 {
     this.User           = user ?? throw new ArgumentNullException(nameof(user));
     this.UserId         = user.Id;
     this.Organization   = organization ?? throw new ArgumentNullException(nameof(organization));
     this.OrganizationId = organization.Id;
     this.Role           = role ?? throw new ArgumentNullException(nameof(role));
     this.RoleId         = role.RoleId;
 }
Пример #7
0
 /// <summary>
 /// Create a new instance of a AccessRequest class.
 /// </summary>
 /// <param name="user"></param>
 /// <param name="role"></param>
 /// <param name="status"></param>
 public PimsAccessRequest(PimsUser user, PimsRole role, PimsAccessRequestStatusType status) : this()
 {
     this.User   = user ?? throw new ArgumentNullException(nameof(user));
     this.UserId = user.Id;
     this.Role   = role ?? throw new ArgumentNullException(nameof(role));
     this.RoleId = role.RoleId;
     this.AccessRequestStatusTypeCodeNavigation = status ?? throw new ArgumentNullException(nameof(status));
     this.AccessRequestStatusTypeCode           = status.Id;
 }
Пример #8
0
 /// <summary>
 /// Create a new instance of a UserRole class.
 /// </summary>
 /// <param name="user"></param>
 /// <param name="role"></param>
 public PimsUserRole(PimsUser user, PimsRole role)
 {
     this.User   = user;
     this.UserId = user?.Id ??
                   throw new ArgumentNullException(nameof(user));
     this.Role   = role;
     this.RoleId = role?.RoleId ??
                   throw new ArgumentNullException(nameof(role));
 }
Пример #9
0
 private static void UpdateUser(Model.UserModel model, Entity.PimsUser entity)
 {
     entity.PimsUserOrganizations.Where(a => a != null).ForEach(a => {
         a.UserId = entity.Id;
         a.RoleId = model.Roles.FirstOrDefault()?.Id ?? 0;
     });
     entity.PimsUserRoles.Where(r => r?.RoleId != null).ForEach(r => r.UserId = entity.Id);
     if (model?.Email?.Length > 0)
     {
         entity.Person.PimsContactMethods.Add(new PimsContactMethod(entity.Person, null, ContactMethodTypes.WorkEmail, model.Email));
     }
 }
Пример #10
0
        /// <summary>
        /// Create a new instance of an AccessRequest for the specified user.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="user"></param>
        /// <param name="role"></param>
        /// <param name="organization"></param>
        /// <returns></returns>
        public static Entity.PimsAccessRequest CreateAccessRequest(long id, Entity.PimsUser user, Entity.PimsRole role, Entity.PimsOrganization organization)
        {
            user ??= EntityHelper.CreateUser("test");
            role ??= EntityHelper.CreateRole("Real Estate Manager");
            var accessRequest = new Entity.PimsAccessRequest()
            {
                AccessRequestId = id,
                UserId          = user.Id,
                User            = user,
                RoleId          = role.Id,
                Role            = role
            };

            organization ??= EntityHelper.CreateOrganization(id, "test", EntityHelper.CreateOrganizationType("Type 1"), EntityHelper.CreateOrganizationIdentifierType("Identifier 1"), EntityHelper.CreateAddress(id));
            accessRequest.PimsAccessRequestOrganizations.Add(new Entity.PimsAccessRequestOrganization()
            {
                AccessRequestId = id,
                AccessRequest   = accessRequest,
                OrganizationId  = organization.Id,
                Organization    = organization
            });

            return(accessRequest);
        }
Пример #11
0
 /// <summary>
 /// Creates a new instance of a UserModel object, initializes it with specified arguments.
 /// </summary>
 /// <param name="user"></param>
 public UserModel(Entity.PimsUser user)
 {
     this.Id  = user.Id;
     this.Key = user.GuidIdentifierValue.Value;
 }