コード例 #1
0
        /// <summary>
        /// Fetch all Users in PIMS and update keycloak so they have the same roles and claims.
        /// </summary>
        /// <param name="log"></param>
        /// <returns></returns>
        private async Task SyncUsersAsync(StringBuilder log)
        {
            // Fetch all users in keycloak so that they can be synced.
            // This is useful when the database has been refreshed.
            var kusers = await _client.HandleGetAsync <KModel.UserModel[]>(_client.AdminRoute($"users"));

            var page        = 1;
            var quantity    = 50;
            var users       = new List <UserModel>();
            var pageOfUsers = await _client.HandleRequestAsync <PageModel <UserModel> >(HttpMethod.Get, $"{_options.Api.Uri}/admin/users?page={page}&quantity={quantity}"); // TODO: Replace paging with specific requests for a user.

            users.AddRange(pageOfUsers.Items);

            // Keep asking for pages of users until we have them all.
            while (pageOfUsers.Items.Count() == quantity)
            {
                pageOfUsers = await _client.HandleRequestAsync <PageModel <UserModel> >(HttpMethod.Get, $"{_options.Api.Uri}/admin/users?page={++page}&quantity={quantity}");

                users.AddRange(pageOfUsers.Items);
            }

            foreach (var user in users)
            {
                var kuser = await GetUserAsync(user);

                // Ignore users that only exist in PIMS.
                if (kuser == null)
                {
                    continue;
                }

                // Sync user agencies.
                if (kuser.Attributes == null)
                {
                    kuser.Attributes = new Dictionary <string, string[]>();
                }
                kuser.Enabled                   = !user.IsDisabled;
                kuser.FirstName                 = user.FirstName;
                kuser.LastName                  = user.LastName;
                kuser.EmailVerified             = user.EmailVerified;
                kuser.Attributes["displayName"] = new[] { user.DisplayName };
                kuser.Attributes["position"]    = new[] { user.Position };
                kuser.Attributes["agencies"]    = user.Agencies.Select(a => a.Id.ToString()).ToArray();

                _logger.LogInformation($"Updating User in Keycloak '{user.Username}'.");
                log.Append($"Keycloak - User updated '{user.Username}'{Environment.NewLine}");
                var userResponse = await _client.SendJsonAsync($"{_options.Auth.Keycloak.Admin.Authority}/users/{kuser.Id}", HttpMethod.Put, kuser);

                if (!userResponse.IsSuccessStatusCode)
                {
                    throw new HttpClientRequestException(userResponse, $"Failed to update the user '{user.Username}' in keycloak");
                }

                // Sync user roles.
                foreach (var role in user.Roles)
                {
                    var groupResponse = await _client.SendAsync($"{_options.Auth.Keycloak.Admin.Authority}/users/{kuser.Id}/groups/{role.KeycloakGroupId}", HttpMethod.Put);

                    if (!groupResponse.IsSuccessStatusCode)
                    {
                        throw new HttpClientRequestException(groupResponse, $"Failed to add the group '{role.Name}' to the user '{user.Username}' keycloak");
                    }
                }
            }

            // Add keycloak users to PIMS.
            // Only add users who don't exist.
            foreach (var kuser in kusers.Where(u => !users.Any(pu => pu.Username == u.Username)))
            {
                try
                {
                    if (String.IsNullOrWhiteSpace(kuser.Email) || String.IsNullOrWhiteSpace(kuser.FirstName) || String.IsNullOrWhiteSpace(kuser.LastName))
                    {
                        _logger.LogInformation($"Unable to add user to PIMS '{kuser.Username}'.");
                        continue;
                    }

                    _logger.LogInformation($"Adding User to PIMS '{kuser.Username}'.");
                    var user   = new UserModel(kuser);
                    var uRoles = user.Roles as List <RoleModel>;

                    // Check if the agencies listed in Keycloak exist in PIMS.  If they don't report the issue in the summary.
                    var removeAgencies = new List <AgencyModel>();
                    if (user.Agencies?.Any() == true)
                    {
                        var agencies = user.Agencies.ToArray();
                        foreach (var agency in agencies)
                        {
                            var aexists = await _client.HandleRequestAsync <AgencyModel>(HttpMethod.Get, $"{_options.Api.Uri}/admin/agencies/{agency.Id}", r =>
                            {
                                _logger.LogError($"Agency '{agency.Id}' does not exist in PIMS.", user);
                                log.Append($"PIMS - Agency missing '{agency.Id}'{Environment.NewLine}");
                                removeAgencies.Add(agency);
                                return(true);
                            });
                        }
                    }

                    // Remove any agencies.
                    removeAgencies.ForEach(a => ((List <AgencyModel>)user.Agencies).Remove(a));

                    // Fetch the users groups from keycloak.
                    var kgroups = await _client.HandleGetAsync <KModel.GroupModel[]>(_client.AdminRoute($"users/{kuser.Id}/groups"));

                    // Fetch the group from PIMS.
                    foreach (var kgroup in kgroups)
                    {
                        var role = await _client.HandleGetAsync <RoleModel>($"{_options.Api.Uri}/admin/roles/name/{kgroup.Name}", r => true);

                        if (role != null)
                        {
                            uRoles.Add(role);
                        }
                    }

                    user.Roles = uRoles;

                    // Add the user to PIMS.
                    user = await _client.HandleRequestAsync <UserModel, UserModel>(HttpMethod.Post, $"{_options.Api.Uri}/admin/users", user);

                    log.Append($"Keycloak User added to PIMS '{user.Username}'{Environment.NewLine}");
                }
                catch (HttpClientRequestException ex)
                {
                    _logger.LogError($"Failed to add keycloak user '{kuser.Email}' to PIMS.", ex);
                }
            }
        }
コード例 #2
0
ファイル: RealmFactory.cs プロジェクト: ychung-mot/PIMS
        /// <summary>
        /// Update the realm information.
        /// </summary>
        /// <returns></returns>
        private async Task UpdateRealmAsync()
        {
            _logger.LogInformation($"Updating realm '{_options.Realm.Name}'");
            // Determine if realm exists, it will throw an exception if it doesn't.
            var realm = await _client.HandleGetAsync <KModel.RealmModel>(_client.AdminRoute());

            realm.DisplayName     = _options.Realm.DisplayName;
            realm.DisplayNameHtml = _options.Realm.DisplayNameHtml;

            var rRes = await _client.SendJsonAsync(_client.AdminRoute(), HttpMethod.Put, realm);

            if (!rRes.IsSuccessStatusCode)
            {
                throw new HttpClientRequestException(rRes);
            }

            await AddUpdateRealmRolesAsync();
            await AddUpdateGroupsAsync();
            await AddUpdateClientsAsync();
        }