mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
15.34.2006 059f1eb59194d5a7484b876fbbc9a938521e15a9
Update the modify operation code so that it will generate account status
notifications for the following events:
- User password change
- Administrative password reset
- Administrative account disable
- Administrative account enable
- Administrative account unlock
3 files modified
188 ■■■■■ changed files
opends/src/server/org/opends/server/core/ModifyOperation.java 110 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/CoreMessages.java 74 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AttributeType.java 4 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -56,8 +56,10 @@
import org.opends.server.protocols.ldap.LDAPException;
import org.opends.server.protocols.ldap.LDAPModification;
import org.opends.server.schema.AuthPasswordSyntax;
import org.opends.server.schema.BooleanSyntax;
import org.opends.server.schema.UserPasswordSyntax;
import org.opends.server.types.AcceptRejectWarn;
import org.opends.server.types.AccountStatusNotificationType;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
@@ -76,6 +78,7 @@
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SynchronizationProviderResult;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.core.CoreConstants.*;
import static org.opends.server.loggers.Access.*;
import static org.opends.server.loggers.Debug.*;
@@ -1251,6 +1254,9 @@
        // Declare variables used for password policy state processing.
        boolean passwordChanged = false;
        boolean currentPasswordProvided = false;
        boolean isEnabled = true;
        boolean enabledStateChanged = false;
        boolean wasLocked = false;
        int numPasswords;
        if (currentEntry.hasAttribute(pwPolicyState.getPasswordAttribute()))
        {
@@ -1283,6 +1289,11 @@
          if (passwordChanged)
          {
            // See if the account was locked for any reason.
            wasLocked = pwPolicyState.lockedDueToIdleInterval() ||
                        pwPolicyState.lockedDueToMaximumResetAge() ||
                        pwPolicyState.lockedDueToFailures();
            // Update the password policy state attributes in the user's entry.
            // If the modification fails, then these changes won't be applied.
            pwPolicyState.setPasswordChangedTime();
@@ -1342,8 +1353,7 @@
          // If the modification is updating the password attribute, then
          // perform any necessary password policy processing.  This processing
          // should be skipped for internal and synchronization operations.
          boolean isPassword = a.getAttributeType().equals(
                                    pwPolicyState.getPasswordAttribute());
          boolean isPassword = t.equals(pwPolicyState.getPasswordAttribute());
          if (isPassword &&
              (! (isInternalOperation() || isSynchronizationOperation())))
          {
@@ -1657,6 +1667,37 @@
                break modifyProcessing;
            }
          }
          else
          {
            // See if it's an attribute used to maintain the account
            // enabled/disabled state.
            AttributeType disabledAttr =
                 DirectoryServer.getAttributeType(OP_ATTR_ACCOUNT_DISABLED,
                                                  true);
            if (t.equals(disabledAttr))
            {
              enabledStateChanged = true;
              for (AttributeValue v : a.getValues())
              {
                try
                {
                  isEnabled = (! BooleanSyntax.decodeBooleanValue(
                                                    v.getNormalizedValue()));
                }
                catch (DirectoryException de)
                {
                  setResultCode(ResultCode.INVALID_ATTRIBUTE_SYNTAX);
                  int msgID = MSGID_MODIFY_INVALID_DISABLED_VALUE;
                  String message =
                       getMessage(msgID, OP_ATTR_ACCOUNT_DISABLED,
                                  String.valueOf(de.getErrorMessage()));
                  appendErrorMessage(message);
                  break modifyProcessing;
                }
              }
            }
          }
          switch (m.getModificationType())
@@ -2361,20 +2402,63 @@
            backend.replaceEntry(modifiedEntry, this);
            // If the update was successful and included a self password change,
            // then clear the "must change" flag in the client connection.
            if ((getResultCode() == ResultCode.SUCCESS) && passwordChanged &&
                selfChange)
            // If the modification was successful, then see if there's any other
            // work that we need to do here before handing off to postop
            // plugins.
            if (passwordChanged)
            {
              // We really only want to do this if the authentication DN from
              // the client connection is equal to the entry that was updated to
              // avoid clearing the flag for the wrong user.
              AuthenticationInfo authInfo =
                   clientConnection.getAuthenticationInfo();
              if (authInfo.getAuthenticationDN().equals(entryDN))
              if (selfChange)
              {
                clientConnection.setMustChangePassword(false);
                AuthenticationInfo authInfo =
                     clientConnection.getAuthenticationInfo();
                if (authInfo.getAuthenticationDN().equals(entryDN))
                {
                  clientConnection.setMustChangePassword(false);
                }
                int    msgID   = MSGID_MODIFY_PASSWORD_CHANGED;
                String message = getMessage(msgID);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.PASSWORD_CHANGED, entryDN,
                     msgID, message);
              }
              else
              {
                int    msgID   = MSGID_MODIFY_PASSWORD_RESET;
                String message = getMessage(msgID);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.PASSWORD_RESET, entryDN,
                     msgID, message);
              }
            }
            if (enabledStateChanged)
            {
              if (isEnabled)
              {
                int    msgID   = MSGID_MODIFY_ACCOUNT_ENABLED;
                String message = getMessage(msgID);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.ACCOUNT_ENABLED, entryDN,
                     msgID, message);
              }
              else
              {
                int    msgID   = MSGID_MODIFY_ACCOUNT_DISABLED;
                String message = getMessage(msgID);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.ACCOUNT_DISABLED, entryDN,
                     msgID, message);
              }
            }
            if (wasLocked)
            {
              int    msgID   = MSGID_MODIFY_ACCOUNT_UNLOCKED;
              String message = getMessage(msgID);
              pwPolicyState.generateAccountStatusNotification(
                   AccountStatusNotificationType.ACCOUNT_UNLOCKED, entryDN,
                   msgID, message);
            }
          }
opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -5756,6 +5756,67 @@
  /**
   * The message ID for the message that will be used if an attempt is made to
   * modify the account disabled attribute using an invalid value.  This takes
   * two arguments, which are the name of the attribute and a message explaining
   * the reason the value was invalid.
   */
  public static final int MSGID_MODIFY_INVALID_DISABLED_VALUE =
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 550;
  /**
   * The message ID for the message that will be used in the account status
   * notification indicating that a user's password has been changed.  This does
   * not take any arguments.
   */
  public static final int MSGID_MODIFY_PASSWORD_CHANGED =
       CATEGORY_MASK_CORE | SEVERITY_MASK_INFORMATIONAL | 551;
  /**
   * The message ID for the message that will be used in the account status
   * notification indicating that a user's password has been reset by an
   * administrator.  This does not take any arguments.
   */
  public static final int MSGID_MODIFY_PASSWORD_RESET =
       CATEGORY_MASK_CORE | SEVERITY_MASK_INFORMATIONAL | 552;
  /**
   * The message ID for the message that will be used in the account status
   * notification indicating that a user's account has been enabled.  This does
   * not take any arguments.
   */
  public static final int MSGID_MODIFY_ACCOUNT_ENABLED =
       CATEGORY_MASK_CORE | SEVERITY_MASK_INFORMATIONAL | 553;
  /**
   * The message ID for the message that will be used in the account status
   * notification indicating that a user's account has been disabled.  This does
   * not take any arguments.
   */
  public static final int MSGID_MODIFY_ACCOUNT_DISABLED =
       CATEGORY_MASK_CORE | SEVERITY_MASK_INFORMATIONAL | 554;
  /**
   * The message ID for the message that will be used in the account status
   * notification indicating that a user's account has been unlocked.  This does
   * not take any arguments.
   */
  public static final int MSGID_MODIFY_ACCOUNT_UNLOCKED =
       CATEGORY_MASK_CORE | SEVERITY_MASK_INFORMATIONAL | 555;
  /**
   * Associates a set of generic messages with the message IDs defined
   * in this class.
   */
@@ -6867,6 +6928,9 @@
    registerMessage(MSGID_MODIFY_INVALID_MOD_TYPE_FOR_PASSWORD,
                    "Invalid modification type %s attempted on password " +
                    "attribute %s.");
    registerMessage(MSGID_MODIFY_INVALID_DISABLED_VALUE,
                    "Invalid value provided for operational attribute %s:  " +
                    "%s.");
    registerMessage(MSGID_MODIFY_ADD_NO_VALUES,
                    "Entry %s cannot be modified because the modification " +
                    "contained an add component for attribute %s but no " +
@@ -6940,6 +7004,16 @@
                    "The modify operation was not actually performed in the " +
                    "Directory Server backend because the LDAP no-op control " +
                    "was present in the request.");
    registerMessage(MSGID_MODIFY_PASSWORD_CHANGED,
                    "The user password has been changed.");
    registerMessage(MSGID_MODIFY_PASSWORD_RESET,
                    "The user password has been administratively reset.");
    registerMessage(MSGID_MODIFY_ACCOUNT_ENABLED,
                    "The user account has been administratively enabled.");
    registerMessage(MSGID_MODIFY_ACCOUNT_DISABLED,
                    "The user account has been administratively disabled.");
    registerMessage(MSGID_MODIFY_ACCOUNT_UNLOCKED,
                    "The user account has been administratively unlocked.");
    registerMessage(MSGID_MODIFY_ERROR_NOTIFYING_CHANGE_LISTENER,
                    "An unexpected error occurred while notifying a change " +
                    "notification listener of a modify operation:  %s.");
opends/src/server/org/opends/server/types/AttributeType.java
@@ -1182,13 +1182,13 @@
  /**
   * Indicates whether the provided object is equal to this attribute
   * value.  The object will be considered equal if it is an attribute
   * type.  The object will be considered equal if it is an attribute
   * type with the same OID as the current type.
   *
   * @param  o  The object for which to make the determination.
   *
   * @return  <CODE>true</CODE> if the provided object is equal to
   *          this attribute, or <CODE>false</CODE> if not.
   *          this attribute type, or <CODE>false</CODE> if not.
   */
  public boolean equals(Object o)
  {