示例#1
0
        /// <summary>
        /// Remove roles from the group in keycloak.
        /// </summary>
        /// <param name="group"></param>
        /// <param name="role"></param>
        /// <returns></returns>
        private async Task RemoveRolesFromGroupInKeycloak(KModel.GroupModel group, PModel.RoleModel role)
        {
            var removeRoles = group.RealmRoles?.Where(r => !role.Claims.Select(c => c.Name).Contains(r)) ?? new string[0];

            foreach (var rname in removeRoles)
            {
                // Get the matching role from keycloak.
                var krole = await _client.HandleRequestAsync <KModel.RoleModel>(HttpMethod.Get, $"{_options.Auth.Keycloak.Admin.Authority}/roles/{rname}");

                var roles = new[] {
                    new KModel.RoleModel()
                    {
                        Id          = krole.Id,
                        Name        = krole.Name,
                        Composite   = false,
                        ClientRole  = false,
                        ContainerId = _options.Auth.Keycloak.Realm,
                        Description = krole.Description
                    }
                };

                // Update the group in keycloak.
                var response = await _client.SendJsonAsync($"{_options.Auth.Keycloak.Admin.Authority}/groups/{group.Id}/role-mappings/realm", HttpMethod.Delete, roles);

                if (!response.IsSuccessStatusCode)
                {
                    throw new HttpClientRequestException(response, $"Failed to update the group '{role.Name}' removing role '{rname}' in keycloak");
                }
            }
        }
示例#2
0
        /// <summary>
        /// Add a group to keycloak.
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        private async Task <KModel.GroupModel> AddGroupToKeycloak(PModel.RoleModel role)
        {
            var addGroup = new KModel.GroupModel()
            {
                Name       = role.Name,
                Path       = $"/{role.Name}",
                RealmRoles = role.Claims.Select(c => c.Name).ToArray()
            };

            // Add the group to keycloak and sync with PIMS.
            var response = await _client.SendJsonAsync($"{_options.Auth.Keycloak.Admin.Authority}/groups", HttpMethod.Post, addGroup);

            if (response.StatusCode == HttpStatusCode.Created)
            {
                // Get the Group Id
                var groups = await _client.HandleRequestAsync <IEnumerable <KModel.GroupModel> >(HttpMethod.Get, $"{_options.Auth.Keycloak.Admin.Authority}/groups?search={role.Name}");

                role.KeycloakGroupId = groups.FirstOrDefault().Id;
                role.Key             = role.KeycloakGroupId.Value;
                return(await GetKeycloakGroupAsync(role, false));
            }
            else
            {
                throw new HttpClientRequestException(response, $"Failed to add the group '{role.Name}' to keycloak");
            }
        }
示例#3
0
        /// <summary>
        /// Get the keycloak group that matches the PIMS role.
        /// If it doesn't exist, create it in keycloak.
        /// </summary>
        /// <param name="role"></param>
        /// <param name="update"></param>
        /// <returns></returns>
        private async Task <KModel.GroupModel> GetKeycloakGroupAsync(PModel.RoleModel role, bool update = true)
        {
            try
            {
                // Make a request to keycloak to find a matching group.
                // If one is found, sync both keycloak and PIMS.
                // If one is not found, add it to keycloak and sync with PIMS.
                var group = await _client.HandleRequestAsync <KModel.GroupModel>(HttpMethod.Get, $"{_options.Auth.Keycloak.Admin.Authority}/groups/{role.KeycloakGroupId ?? role.Key}");

                // If the roles match the claims, return it.
                if (update)
                {
                    return(await UpdateGroupInKeycloak(group, role));
                }

                return(group);
            }
            catch (HttpClientRequestException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    // Check if the group exists as a different name.
                    var groups = await _client.HandleRequestAsync <IEnumerable <KModel.GroupModel> >(HttpMethod.Get, $"{_options.Auth.Keycloak.Admin.Authority}/groups?search={role.Name}");

                    var existingGroup = groups.FirstOrDefault(g => g.Name == role.Name);

                    if (existingGroup != null)
                    {
                        role.Key             = existingGroup.Id.Value;
                        role.KeycloakGroupId = existingGroup.Id;
                        if (update)
                        {
                            return(await UpdateGroupInKeycloak(existingGroup, role));
                        }
                        return(existingGroup);
                    }
                    else
                    {
                        return(await AddGroupToKeycloak(role));
                    }
                }

                throw;
            }
        }
示例#4
0
        /// <summary>
        /// Add roles to the group in keycloak.
        /// </summary>
        /// <param name="group"></param>
        /// <param name="role"></param>
        /// <returns></returns>
        private async Task AddRolesToGroupInKeycloak(KModel.GroupModel group, PModel.RoleModel role)
        {
            // Get the matching role from keycloak.
            //var krole = await HandleRequestAsync<KModel.RoleModel>(HttpMethod.Get, $"{_options.Auth.Keycloak.Admin.Authority}/roles/{claim.Name}");
            var roles = role.Claims.Select(c => new KModel.RoleModel()
            {
                Id          = c.KeycloakRoleId.Value,
                Name        = c.Name,
                Composite   = false,
                ClientRole  = false,
                ContainerId = _options.Auth.Keycloak.Realm,
                Description = c.Description
            }).ToArray();

            // Update the group in keycloak.
            var response = await _client.SendJsonAsync($"{_options.Auth.Keycloak.Admin.Authority}/groups/{group.Id}/role-mappings/realm", HttpMethod.Post, roles);

            if (!response.IsSuccessStatusCode)
            {
                throw new HttpClientRequestException(response, $"Failed to update the group '{role.Name}' with the roles '{String.Join(",", roles.Select(r => r.Name).ToArray())}' in keycloak");
            }
        }
示例#5
0
        /// <summary>
        /// Update a group in keycloak.
        /// </summary>
        /// <param name="group"></param>
        /// <param name="role"></param>
        /// <returns></returns>
        private async Task <KModel.GroupModel> UpdateGroupInKeycloak(KModel.GroupModel group, PModel.RoleModel role)
        {
            // Update the group in keycloak.
            var response = await _client.SendJsonAsync($"{_options.Auth.Keycloak.Admin.Authority}/groups/{group.Id}", HttpMethod.Put, group);

            if (response.IsSuccessStatusCode)
            {
                await RemoveRolesFromGroupInKeycloak(group, role);
                await AddRolesToGroupInKeycloak(group, role);

                return(await GetKeycloakGroupAsync(role, false));
            }
            else
            {
                throw new HttpClientRequestException(response, $"Failed to update the group '{role.Name}' in keycloak");
            }
        }