public ApiErrorItem? PerformPasswordChange()

in src/Zyborg.PassCore.PasswordProvider.LDAP/LdapPasswordChangeProvider.cs [66:146]


        public ApiErrorItem? PerformPasswordChange(
            string username,
            string currentPassword,
            string newPassword)
        {
            try
            {
                var cleanUsername = CleaningUsername(username);

                var searchFilter = _options.LdapSearchFilter.Replace("{Username}", cleanUsername);

                _logger.LogWarning("LDAP query: {0}", searchFilter);

                using var ldap = BindToLdap();
                var search = ldap.Search(
                    _options.LdapSearchBase,
                    LdapConnection.ScopeSub,
                    searchFilter,
                    new[] { "distinguishedName" },
                    false,
                    _searchConstraints);

                // We cannot use search.Count here -- apparently it does not
                // wait for the results to return before resolving the count
                // but fortunately hasMore seems to block until final result
                if (!search.HasMore())
                {
                    _logger.LogWarning("Unable to find username: [{0}]", cleanUsername);

                    return new ApiErrorItem(
                        _options.HideUserNotFound ? ApiErrorCode.InvalidCredentials : ApiErrorCode.UserNotFound,
                        _options.HideUserNotFound ? "Invalid credentials" : "Username could not be located");
                }

                if (search.Count > 1)
                {
                    _logger.LogWarning("Found multiple with same username: [{0}] - Count {1}", cleanUsername, search.Count);

                    // Hopefully this should not ever happen if AD is preserving SAM Account Name
                    // uniqueness constraint, but just in case, handling this corner case
                    return new ApiErrorItem(ApiErrorCode.UserNotFound, "Multiple matching user entries resolved");
                }

                var userDN = search.Next().Dn;

                if (_options.LdapChangePasswordWithDelAdd)
                {
                    ChangePasswordDelAdd(currentPassword, newPassword, ldap, userDN);
                }
                else
                {
                    ChangePasswordReplace(newPassword, ldap, userDN);
                }

                if (_options.LdapStartTls)
                    ldap.StopTls();

                ldap.Disconnect();
            }
            catch (LdapException ex)
            {
                var item = ParseLdapException(ex);

                _logger.LogWarning(item.Message, ex);

                return item;
            }
            catch (Exception ex)
            {
                var item = ex is ApiErrorException apiError
                    ? apiError.ToApiErrorItem()
                    : new ApiErrorItem(ApiErrorCode.InvalidCredentials, $"Failed to update password: {ex.Message}");

                _logger.LogWarning(item.Message, ex);

                return item;
            }

            // Everything seems to have worked:
            return null;
        }