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

neil_a_wilson
26.35.2007 dfdd9440011d222f12e6e336ed6ab6e59ee2be4b
Make a change to the account status notification handler API so that it is
possible to provide additional properties along with the notification. This
makes it possible to develop account status notification handlers that can act
more intelligently and/or provide more useful information.

This also reverts an earlier change that migrated hard-coded strings to
localizeable messages for notification types. The set of notification types
should in fact be hard-coded strings because they may be used in the
configuration, and the contents of a configuration file should not depend on
the locale in which the server is operating.
2 files added
7 files modified
1018 ■■■■ changed files
opends/src/server/org/opends/server/api/AccountStatusNotificationHandler.java 31 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/PasswordPolicyState.java 34 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandler.java 24 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AccountStatusNotification.java 196 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AccountStatusNotificationProperty.java 235 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AccountStatusNotificationType.java 134 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java 121 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java 91 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TestAccountStatusNotificationHandler.java 152 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/AccountStatusNotificationHandler.java
@@ -25,18 +25,16 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.api;
import org.opends.messages.Message;
import java.util.List;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.
       AccountStatusNotificationHandlerCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.AccountStatusNotification;
import org.opends.server.types.AccountStatusNotificationType;
import org.opends.server.types.DN;
import org.opends.server.types.InitializationException;
@@ -133,35 +131,12 @@
  /**
   * Performs any processing that may be necessary in conjunction with
   * the provided account status notification type.
   *
   * @param  notificationType  The type for this account status
   *                           notification.
   * @param  userDN            The DN of the user entry to which this
   *                           notification applies.
   * @param  message           The human-readable message for this
   *                           notification.
   */
  public abstract void
       handleStatusNotification(
          AccountStatusNotificationType notificationType,
          DN userDN, Message message);
  /**
   * Performs any processing that may be necessary in conjunction with
   * the provided account status notification.
   *
   * @param  notification  The account status notification to be
   *                       processed.
   */
  public void handleStatusNotification(
                   AccountStatusNotification notification)
  {
    handleStatusNotification(notification.getNotificationType(),
                             notification.getUserDN(),
                             notification.getMessage());
  }
  public abstract void handleStatusNotification(
                            AccountStatusNotification notification);
}
opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -25,8 +25,7 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import java.text.SimpleDateFormat;
@@ -38,9 +37,12 @@
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn;
import org.opends.server.admin.std.server.PasswordValidatorCfg;
import org.opends.server.api.AccountStatusNotificationHandler;
@@ -55,6 +57,7 @@
import org.opends.server.schema.GeneralizedTimeSyntax;
import org.opends.server.schema.UserPasswordSyntax;
import org.opends.server.types.AccountStatusNotification;
import org.opends.server.types.AccountStatusNotificationProperty;
import org.opends.server.types.AccountStatusNotificationType;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
@@ -4596,27 +4599,22 @@
  /**
   * Generates an account status notification for this user.
   *
   * @param  notificationType  The type for the account status notification.
   * @param  userDN            The DN of the user entry to which this
   * @param  notificationType        The type for the account status
   *                                 notification.
   * @param  userEntry               The entry for the user to which this
   *                           notification applies.
   * @param  message           The human-readable message for the notification.
   * @param  message                 The human-readable message for the
   *                                 notification.
   * @param  notificationProperties  The set of properties for the notification.
   */
  public void generateAccountStatusNotification(
          AccountStatusNotificationType notificationType,
          DN userDN, Message message)
          Entry userEntry, Message message,
          Map<AccountStatusNotificationProperty,List<String>>
               notificationProperties)
  {
    Collection<AccountStatusNotificationHandler> handlers =
         passwordPolicy.getAccountStatusNotificationHandlers().values();
    if ((handlers == null) || handlers.isEmpty())
    {
      return;
    }
    for (AccountStatusNotificationHandler handler : handlers)
    {
      handler.handleStatusNotification(notificationType, userDN,
              message);
    }
    generateAccountStatusNotification(new AccountStatusNotification(
         notificationType, userEntry, message, notificationProperties));
  }
opends/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandler.java
@@ -45,11 +45,10 @@
       ErrorLogAccountStatusNotificationHandlerCfg;
import org.opends.server.api.AccountStatusNotificationHandler;
import org.opends.server.config.ConfigException;
import org.opends.server.types.AccountStatusNotification;
import org.opends.server.types.AccountStatusNotificationType;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
@@ -72,15 +71,15 @@
   * The set of names for the account status notification types that may be
   * logged by this notification handler.
   */
  private static final HashSet<Message> NOTIFICATION_TYPE_NAMES =
       new HashSet<Message>();
  private static final HashSet<String> NOTIFICATION_TYPE_NAMES =
       new HashSet<String>();
  static
  {
    for (AccountStatusNotificationType t :
         AccountStatusNotificationType.values())
    {
      NOTIFICATION_TYPE_NAMES.add(t.getNotificationName());
      NOTIFICATION_TYPE_NAMES.add(t.getName());
    }
  }
@@ -114,17 +113,14 @@
  /**
   * {@inheritDoc}
   */
  public void handleStatusNotification(AccountStatusNotificationType
          notificationType,
                                       DN userDN, Message message)
  {
    if (notificationTypes.contains(notificationType))
  public void handleStatusNotification(
                   AccountStatusNotification notification)
    {
      logError(NOTE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION.get(
                notificationType.getNotificationName(),
                String.valueOf(userDN),
                message.getDescriptor().getId(), message));
    }
                  notification.getNotificationType().getName(),
                  String.valueOf(notification.getUserDN()),
                  notification.getMessage().getDescriptor().getId(),
                  notification.getMessage()));
  }
opends/src/server/org/opends/server/types/AccountStatusNotification.java
@@ -25,10 +25,24 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.types;
import org.opends.messages.Message;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opends.messages.Message;
import org.opends.server.core.PasswordPolicy;
import org.opends.server.core.PasswordPolicyState;
import static org.opends.server.types.
                   AccountStatusNotificationProperty.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines a data type for storing information associated
@@ -36,7 +50,7 @@
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=true,
     mayInstantiate=false,
     mayExtend=false,
     mayInvoke=true)
public final class AccountStatusNotification
@@ -44,8 +58,13 @@
  // The notification type for this account status notification.
  private AccountStatusNotificationType notificationType;
  // The DN of the user entry to which this notification applies.
  private DN userDN;
  // The entry for the user to whom this notification applies.
  private Entry userEntry;
  // A set of additional properties that may be useful for this
  // notification.
  private Map<AccountStatusNotificationProperty,List<String>>
               notificationProperties;
  // A message that provides additional information for this account
  // status notification.
@@ -59,18 +78,34 @@
   *
   * @param  notificationType  The type for this account status
   *                           notification.
   * @param  userDN            The DN of the user entry to which
   * @param  userEntry               The entry for the user to whom
   *                           this notification applies.
   * @param  message           The human-readable message for this
   *                           notification.
   * @param  message                 The human-readable message for
   *                                 this notification.
   * @param  notificationProperties  A set of properties that may
   *                                 include additional information
   *                                 about this notification.
   */
  public AccountStatusNotification(
              AccountStatusNotificationType notificationType,
              DN userDN, Message message)
              Entry userEntry, Message message,
              Map<AccountStatusNotificationProperty,List<String>>
                   notificationProperties)
  {
    this.notificationType = notificationType;
    this.userDN           = userDN;
    this.userEntry        = userEntry;
    this.message          = message;
    if (notificationProperties == null)
    {
      this.notificationProperties =
           new HashMap<AccountStatusNotificationProperty,
                       List<String>>(0);
    }
    else
    {
      this.notificationProperties = notificationProperties;
    }
  }
@@ -98,7 +133,19 @@
   */
  public DN getUserDN()
  {
    return userDN;
    return userEntry.getDN();
  }
  /**
   * Retrieves user entry for whom this notification applies.
   *
   * @return  The user entry for whom this notification applies.
   */
  public Entry getUserEntry()
  {
    return userEntry;
  }
@@ -118,6 +165,131 @@
  /**
   * Retrieves a set of properties that may provide additional
   * information for this account status notification.
   *
   * @return  A set of properties that may provide additional
   *          information for this account status notification.
   */
  public Map<AccountStatusNotificationProperty,List<String>>
              getNotificationProperties()
  {
    return notificationProperties;
  }
  /**
   * Creates a set of account status notification properties from the
   * provided information.
   *
   * @param  pwPolicyState     The password policy state for the user
   *                           associated with the notification.
   * @param  tempLocked        Indicates whether the user's account
   *                           has been temporarily locked.
   * @param  timeToExpiration  The length of time in seconds until the
   *                           user's password expires, or -1 if it's
   *                           not about to expire.
   * @param  oldPasswords      The set of old passwords for the user,
   *                           or {@code null} if this is not
   *                           applicable.
   * @param  newPasswords      The set of new passwords for the user,
   *                           or {@code null} if this is not
   *                           applicable.
   *
   * @return  The created set of account status notification
   *          properties.
   */
  @org.opends.server.types.PublicAPI(
       stability=org.opends.server.types.StabilityLevel.PRIVATE,
       mayInstantiate=false,
       mayExtend=false,
       mayInvoke=false)
  public static Map<AccountStatusNotificationProperty,List<String>>
                     createProperties(
                          PasswordPolicyState pwPolicyState,
                          boolean tempLocked, int timeToExpiration,
                          List<AttributeValue> oldPasswords,
                          List<AttributeValue> newPasswords)
  {
    HashMap<AccountStatusNotificationProperty,List<String>> props =
         new HashMap<AccountStatusNotificationProperty,
                     List<String>>(4);
    PasswordPolicy policy = pwPolicyState.getPolicy();
    ArrayList<String> propList = new ArrayList<String>(1);
    propList.add(policy.getConfigEntryDN().toString());
    props.put(PASSWORD_POLICY_DN, propList);
    if (tempLocked)
    {
      int secondsUntilUnlock = policy.getLockoutDuration();
      if (secondsUntilUnlock > 0)
      {
        propList = new ArrayList<String>(1);
        propList.add(String.valueOf(secondsUntilUnlock));
        props.put(SECONDS_UNTIL_UNLOCK, propList);
        propList = new ArrayList<String>(1);
        propList.add(
             secondsToTimeString(secondsUntilUnlock).toString());
        props.put(TIME_UNTIL_UNLOCK, propList);
        long unlockTime = System.currentTimeMillis() +
                          (1000*secondsUntilUnlock);
        propList = new ArrayList<String>(1);
        propList.add(new Date(unlockTime).toString());
        props.put(ACCOUNT_UNLOCK_TIME, propList);
      }
    }
    if (timeToExpiration >= 0)
    {
        propList = new ArrayList<String>(1);
        propList.add(String.valueOf(timeToExpiration));
        props.put(SECONDS_UNTIL_EXPIRATION, propList);
        propList = new ArrayList<String>(1);
        propList.add(
             secondsToTimeString(timeToExpiration).toString());
        props.put(TIME_UNTIL_EXPIRATION, propList);
        long expTime = System.currentTimeMillis() +
                       (1000*timeToExpiration);
        propList = new ArrayList<String>(1);
        propList.add(new Date(expTime).toString());
        props.put(ACCOUNT_UNLOCK_TIME, propList);
    }
    if ((oldPasswords != null) && (! oldPasswords.isEmpty()))
    {
      propList = new ArrayList<String>(oldPasswords.size());
      for (AttributeValue v : oldPasswords)
      {
        propList.add(v.getStringValue());
      }
      props.put(OLD_PASSWORD, propList);
    }
    if ((newPasswords != null) && (! newPasswords.isEmpty()))
    {
      propList = new ArrayList<String>(newPasswords.size());
      for (AttributeValue v : newPasswords)
      {
        propList.add(v.getStringValue());
      }
      props.put(NEW_PASSWORD, propList);
    }
    return props;
  }
  /**
   * Retrieves a string representation of this account status
   * notification.
   *
@@ -127,8 +299,8 @@
  public String toString()
  {
    return "AccountStatusNotification(type=" +
           notificationType.getNotificationName() + ",dn=" +
           userDN + ",message=" + message + ")";
           notificationType.getName() + ",dn=" + userEntry.getDN() +
           ",message=" + message + ")";
  }
}
opends/src/server/org/opends/server/types/AccountStatusNotificationProperty.java
New file
@@ -0,0 +1,235 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.types;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class implements an enumeration that holds the possible set of
 * additional properties that can be included in an account status
 * notification.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=false,
     mayExtend=false,
     mayInvoke=true)
public enum AccountStatusNotificationProperty
{
  /**
   * The property whose value will be the string representation of the
   * DN of the password policy for the target user.  This will be
   * available for all notification types.
   */
  PASSWORD_POLICY_DN("password-policy-dn"),
  /**
   * The property whose value will be a generalized time
   * representation of the time at which the user's account will be
   * unlocked.  This will be available for the
   * {@code ACCOUNT_TEMPORARILY_LOCKED} notification type.
   */
  ACCOUNT_UNLOCK_TIME("account-unlock-time"),
  /**
   * The property whose value will be the number of seconds until the
   * user's account is unlocked.  This will be available for the
   * {@code ACCOUNT_TEMPORARILY_LOCKED} notification type.
   */
  SECONDS_UNTIL_UNLOCK("seconds-until-unlock"),
  /**
   * The property whose value will be a localized, human-readable
   * representation of the length of time until the user's account is
   * unlocked.  This will be available for the
   * {@code ACCOUNT_TEMPORARILY_LOCKED} notification type.
   */
  TIME_UNTIL_UNLOCK("time-until-unlock"),
  /**
   * The property whose value will be the generalized time
   * representation of the time that the user's password will expire.
   * This will be available for the {@code PASSWORD_EXPIRING}
   * notification type.
   */
  PASSWORD_EXPIRATION_TIME("password-expiration-time"),
  /**
   * The property whose value will be the number of seconds until the
   * user's password expires.  This will be available for the
   * {@code PASSWORD_EXPIRING} notification type.
   */
  SECONDS_UNTIL_EXPIRATION("seconds-until-expiration"),
  /**
   * The property whose value will be a localized, human-readable
   * representation of the length of time until the user's password
   * expires.  This will be available for the
   * {@code PASSWORD_EXPIRING} notification type.
   */
  TIME_UNTIL_EXPIRATION("time-unti-expiration"),
  /**
   * The property whose value will be a clear-text representation of
   * the user's old password.  This may be available for the
   * {@code PASSWORD_RESET} and {@code PASSWORD_CHANGED} notification
   * types.
   */
  OLD_PASSWORD("old-password"),
  /**
   * The property whose value will be a clear-text representation of
   * the user's new password.  This may be available for the
   * {@code PASSWORD_RESET} and {@code PASSWORD_CHANGED} notification
   * types.
   */
  NEW_PASSWORD("new-password");
  // The notification type name.
  private String name;
  /**
   * Creates a new account status notification property with the
   * provided name.
   *
   * @param  name  The name for this account status notification
   *               property.
   */
  private AccountStatusNotificationProperty(String name)
  {
    this.name = name;
  }
  /**
   * Retrieves the account status notification type with the specified
   * name.
   *
   * @param  name  The name for the account status notification type
   *               to retrieve.
   *
   * @return  The requested account status notification type, or
   *          <CODE>null</CODE> if there is no type with the given
   *          name.
   */
  public static AccountStatusNotificationProperty forName(String name)
  {
    String lowerName = toLowerCase(name);
    if (lowerName.equals("password-policy-dn"))
    {
      return PASSWORD_POLICY_DN;
    }
    else if (lowerName.equals("account-unlock-time"))
    {
      return ACCOUNT_UNLOCK_TIME;
    }
    else if (lowerName.equals("seconds-until-unlock"))
    {
      return SECONDS_UNTIL_UNLOCK;
    }
    else if (lowerName.equals("time-until-unlock"))
    {
      return TIME_UNTIL_UNLOCK;
    }
    else if (lowerName.equals("password-expiration-time"))
    {
      return PASSWORD_EXPIRATION_TIME;
    }
    else if (lowerName.equals("seconds-until-expiration"))
    {
      return SECONDS_UNTIL_EXPIRATION;
    }
    else if (lowerName.equals("time-until-expiration"))
    {
      return TIME_UNTIL_EXPIRATION;
    }
    else if (lowerName.equals("old-password"))
    {
      return OLD_PASSWORD;
    }
    else if (lowerName.equals("new-password"))
    {
      return NEW_PASSWORD;
    }
    else
    {
      return null;
    }
  }
  /**
   * Retrieves the name for this account status notification property.
   *
   * @return  The name for this account status notification property.
   */
  public String getName()
  {
    return name;
  }
  /**
   * Retrieves a string representation of this account status
   * notification property.
   *
   * @return  A string representation of this account status
   *          notification property.
   */
  public String toString()
  {
    return name;
  }
}
opends/src/server/org/opends/server/types/AccountStatusNotificationType.java
@@ -25,13 +25,9 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.types;
import org.opends.messages.Message;
import org.opends.messages.MessageDescriptor;
import static org.opends.messages.UtilityMessages.*;
import static org.opends.server.util.StaticUtils.*;
@@ -52,8 +48,7 @@
   * whenever a user account has been temporarily locked after too
   * many failed attempts.
   */
  ACCOUNT_TEMPORARILY_LOCKED(
       INFO_ACCTNOTTYPE_ACCOUNT_TEMPORARILY_LOCKED.get()),
  ACCOUNT_TEMPORARILY_LOCKED("account-temporarily-locked"),
@@ -63,7 +58,7 @@
   * many failed attempts.
   */
  ACCOUNT_PERMANENTLY_LOCKED(
       INFO_ACCTNOTTYPE_ACCOUNT_PERMANENTLY_LOCKED.get()),
       "account-permanently-locked"),
@@ -71,7 +66,7 @@
   * Indicates that an account status message should be generated
   * whenever a user account has been unlocked by an administrator.
   */
  ACCOUNT_UNLOCKED(INFO_ACCTNOTTYPE_ACCOUNT_UNLOCKED.get()),
  ACCOUNT_UNLOCKED("account-unlocked"),
@@ -80,7 +75,7 @@
   * whenever a user account has been locked because it was idle for
   * too long.
   */
  ACCOUNT_IDLE_LOCKED(INFO_ACCTNOTTYPE_ACCOUNT_IDLE_LOCKED.get()),
  ACCOUNT_IDLE_LOCKED("account-idle-locked"),
@@ -90,7 +85,7 @@
   * had been reset by an administrator but not changed by the user
   * within the required interval.
   */
  ACCOUNT_RESET_LOCKED(INFO_ACCTNOTTYPE_ACCOUNT_RESET_LOCKED.get()),
  ACCOUNT_RESET_LOCKED("account-reset-locked"),
@@ -98,7 +93,7 @@
   * Indicates that an account status message should be generated
   * whenever a user account has been disabled by an administrator.
   */
  ACCOUNT_DISABLED(INFO_ACCTNOTTYPE_ACCOUNT_DISABLED.get()),
  ACCOUNT_DISABLED("account-disabled"),
@@ -106,7 +101,7 @@
   * Indicates that an account status message should be generated
   * whenever a user account has been enabled by an administrator.
   */
  ACCOUNT_ENABLED(INFO_ACCTNOTTYPE_ACCOUNT_ENABLED.get()),
  ACCOUNT_ENABLED("account-enabled"),
@@ -115,7 +110,7 @@
   * whenever a user authentication has failed because the account
   * has expired.
   */
  ACCOUNT_EXPIRED(INFO_ACCTNOTTYPE_ACCOUNT_EXPIRED.get()),
  ACCOUNT_EXPIRED("account-expired"),
@@ -124,7 +119,7 @@
   * generated whenever a user authentication has failed because the
   * password has expired.
   */
  PASSWORD_EXPIRED(INFO_ACCTNOTTYPE_PASSWORD_EXPIRED.get()),
  PASSWORD_EXPIRED("password-expired"),
@@ -134,7 +129,7 @@
   * generated the first time that a password expiration warning is
   * encountered for a user password.
   */
  PASSWORD_EXPIRING(INFO_ACCTNOTTYPE_PASSWORD_EXPIRING.get()),
  PASSWORD_EXPIRING("password-expiring"),
@@ -143,7 +138,7 @@
   * generated whenever a user's password is reset by an
   * administrator.
   */
  PASSWORD_RESET(INFO_ACCTNOTTYPE_PASSWORD_RESET.get()),
  PASSWORD_RESET("password-reset"),
@@ -151,72 +146,24 @@
   * Indicates whether an account status notification message should
   * be generated whenever a user changes his/her own password.
   */
  PASSWORD_CHANGED(INFO_ACCTNOTTYPE_PASSWORD_CHANGED.get());
  PASSWORD_CHANGED("password-changed");
  // The notification type message.
  private Message notificationName;
  // The notification type name.
  private String name;
  /**
   * Creates a new account status notification type with the provided
   * notification type ID.
   * name.
   *
   * @param  notification      The notification message for
   *                           this account status notification.
   * @param  name  The name for this account status notification type.
   */
  private AccountStatusNotificationType(Message notification)
  private AccountStatusNotificationType(String name)
  {
    this.notificationName = notification;
  }
  /**
   * Retrieves the account status notification type with the specified
   * notification type identifier.
   *
   * @param  notification    The notification type message for
   *                         the notification type to retrieve.
   *
   * @return  The requested account status notification type, or
   *          <CODE>null</CODE> if there is no type for the given
   *          notification type identifier.
   */
  public static AccountStatusNotificationType
                     typeForMessage(Message notification)
  {
    MessageDescriptor md = notification.getDescriptor();
    if (INFO_ACCTNOTTYPE_ACCOUNT_TEMPORARILY_LOCKED.equals(md)) {
      return ACCOUNT_TEMPORARILY_LOCKED;
    } else if (INFO_ACCTNOTTYPE_ACCOUNT_PERMANENTLY_LOCKED
            .equals(md)) {
      return ACCOUNT_PERMANENTLY_LOCKED;
    } else if (INFO_ACCTNOTTYPE_ACCOUNT_UNLOCKED.equals(md)) {
      return ACCOUNT_UNLOCKED;
    } else if (INFO_ACCTNOTTYPE_ACCOUNT_IDLE_LOCKED.equals(md)) {
      return ACCOUNT_IDLE_LOCKED;
    } else if (INFO_ACCTNOTTYPE_ACCOUNT_RESET_LOCKED.equals(md)) {
      return ACCOUNT_RESET_LOCKED;
    } else if (INFO_ACCTNOTTYPE_ACCOUNT_DISABLED.equals(md)) {
      return ACCOUNT_DISABLED;
    } else if (INFO_ACCTNOTTYPE_ACCOUNT_ENABLED.equals(md)) {
      return ACCOUNT_ENABLED;
    } else if (INFO_ACCTNOTTYPE_ACCOUNT_EXPIRED.equals(md)) {
      return ACCOUNT_EXPIRED;
    } else if (INFO_ACCTNOTTYPE_PASSWORD_EXPIRED.equals(md)) {
      return PASSWORD_EXPIRED;
    } else if (INFO_ACCTNOTTYPE_PASSWORD_EXPIRING.equals(md)) {
      return PASSWORD_EXPIRING;
    } else if (INFO_ACCTNOTTYPE_PASSWORD_RESET.equals(md)) {
      return PASSWORD_RESET;
    } else if (INFO_ACCTNOTTYPE_PASSWORD_CHANGED.equals(md)) {
      return PASSWORD_CHANGED;
    } else {
      return null;
    }
    this.name = name;
  }
@@ -234,65 +181,52 @@
   */
  public static AccountStatusNotificationType typeForName(String name)
  {
    Message lowerName = Message.raw(toLowerCase(name));
    if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_TEMPORARILY_LOCKED.get()))
    String lowerName = toLowerCase(name);
    if (lowerName.equals("account-temporarily-locked"))
    {
      return ACCOUNT_TEMPORARILY_LOCKED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_PERMANENTLY_LOCKED.get()))
    else if (lowerName.equals("account-permanently-locked"))
    {
      return ACCOUNT_PERMANENTLY_LOCKED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_UNLOCKED.get()))
    else if (lowerName.equals("account-unlocked"))
    {
      return ACCOUNT_UNLOCKED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_IDLE_LOCKED.get()))
    else if (lowerName.equals("account-idle-locked"))
    {
      return ACCOUNT_IDLE_LOCKED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_RESET_LOCKED.get()))
    else if (lowerName.equals("account-reset-locked"))
    {
      return ACCOUNT_RESET_LOCKED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_DISABLED.get()))
    else if (lowerName.equals("account-disabled"))
    {
      return ACCOUNT_DISABLED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_ENABLED.get()))
    else if (lowerName.equals("account-enabled"))
    {
      return ACCOUNT_ENABLED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_ACCOUNT_EXPIRED.get()))
    else if (lowerName.equals("account-expired"))
    {
      return ACCOUNT_EXPIRED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_PASSWORD_EXPIRED.get()))
    else if (lowerName.equals("password-expired"))
    {
      return PASSWORD_EXPIRED;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_PASSWORD_EXPIRING.get()))
    else if (lowerName.equals("password-expiring"))
    {
      return PASSWORD_EXPIRING;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_PASSWORD_RESET.get()))
    else if (lowerName.equals("password-reset"))
    {
      return PASSWORD_RESET;
    }
    else if (lowerName.equals(
            INFO_ACCTNOTTYPE_PASSWORD_CHANGED.get()))
    else if (lowerName.equals("password-changed"))
    {
      return PASSWORD_CHANGED;
    }
@@ -309,9 +243,9 @@
   *
   * @return  The name for this account status notification type.
   */
  public Message getNotificationName()
  public String getName()
  {
    return notificationName;
    return name;
  }
@@ -325,7 +259,7 @@
   */
  public String toString()
  {
    return String.valueOf(getNotificationName());
    return name;
  }
}
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -94,6 +94,7 @@
import org.opends.server.schema.BooleanSyntax;
import org.opends.server.schema.UserPasswordSyntax;
import org.opends.server.types.AcceptRejectWarn;
import org.opends.server.types.AccountStatusNotification;
import org.opends.server.types.AccountStatusNotificationType;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
@@ -2180,15 +2181,21 @@
                Message message = INFO_MODIFY_PASSWORD_CHANGED.get();
                pwPolicyState.generateAccountStatusNotification(
                    AccountStatusNotificationType.PASSWORD_CHANGED, entryDN,
                    message);
                    AccountStatusNotificationType.PASSWORD_CHANGED,
                    modifiedEntry, message,
                    AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, localOp.getCurrentPasswords(),
                         localOp.getNewPasswords()));
              }
              else
              {
                Message message = INFO_MODIFY_PASSWORD_RESET.get();
                pwPolicyState.generateAccountStatusNotification(
                    AccountStatusNotificationType.PASSWORD_RESET, entryDN,
                    message);
                    AccountStatusNotificationType.PASSWORD_RESET, modifiedEntry,
                    message,
                    AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, localOp.getCurrentPasswords(),
                         localOp.getNewPasswords()));
              }
            }
@@ -2198,15 +2205,19 @@
              {
                Message message = INFO_MODIFY_ACCOUNT_ENABLED.get();
                pwPolicyState.generateAccountStatusNotification(
                    AccountStatusNotificationType.ACCOUNT_ENABLED, entryDN,
                    message);
                    AccountStatusNotificationType.ACCOUNT_ENABLED,
                    modifiedEntry, message,
                    AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, null, null));
              }
              else
              {
                Message message = INFO_MODIFY_ACCOUNT_DISABLED.get();
                pwPolicyState.generateAccountStatusNotification(
                    AccountStatusNotificationType.ACCOUNT_DISABLED, entryDN,
                    message);
                    AccountStatusNotificationType.ACCOUNT_DISABLED,
                    modifiedEntry, message,
                    AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, null, null));
              }
            }
@@ -2214,8 +2225,10 @@
            {
              Message message = INFO_MODIFY_ACCOUNT_UNLOCKED.get();
              pwPolicyState.generateAccountStatusNotification(
                  AccountStatusNotificationType.ACCOUNT_UNLOCKED, entryDN,
                  message);
                  AccountStatusNotificationType.ACCOUNT_UNLOCKED, modifiedEntry,
                  message,
                  AccountStatusNotification.createProperties(pwPolicyState,
                       false, -1, null, null));
            }
          }
@@ -3384,8 +3397,10 @@
              localOp.setAuthFailureReason(message);
              pwPolicyState.generateAccountStatusNotification(
                   AccountStatusNotificationType.ACCOUNT_EXPIRED, bindDN,
                      message);
                   AccountStatusNotificationType.ACCOUNT_EXPIRED, userEntry,
                   message,
                   AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, null, null));
              break bindProcessing;
            }
@@ -3417,8 +3432,10 @@
              localOp.setAuthFailureReason(message);
              pwPolicyState.generateAccountStatusNotification(
                   AccountStatusNotificationType.ACCOUNT_RESET_LOCKED, bindDN,
                      message);
                   AccountStatusNotificationType.ACCOUNT_RESET_LOCKED,
                   userEntry, message,
                   AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, null, null));
              break bindProcessing;
            }
@@ -3436,8 +3453,10 @@
              localOp.setAuthFailureReason(message);
              pwPolicyState.generateAccountStatusNotification(
                   AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED, bindDN,
                      message);
                   AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED, userEntry,
                   message,
                   AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, null, null));
              break bindProcessing;
            }
@@ -3479,8 +3498,10 @@
                  localOp.setAuthFailureReason(message);
                  pwPolicyState.generateAccountStatusNotification(
                       AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
                          message);
                       AccountStatusNotificationType.PASSWORD_EXPIRED,
                       userEntry, message,
                       AccountStatusNotification.createProperties(pwPolicyState,
                             false, -1, null, null));
                  break bindProcessing;
                }
@@ -3494,8 +3515,10 @@
                localOp.setAuthFailureReason(message);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
                        message);
                     AccountStatusNotificationType.PASSWORD_EXPIRED, userEntry,
                     message,
                     AccountStatusNotification.createProperties(pwPolicyState,
                           false, -1, null, null));
                break bindProcessing;
              }
@@ -3766,8 +3789,10 @@
                        timeToExpiration);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.PASSWORD_EXPIRING, bindDN,
                        message);
                     AccountStatusNotificationType.PASSWORD_EXPIRING, userEntry,
                     message,
                     AccountStatusNotification.createProperties(pwPolicyState,
                           false, numSeconds, null, null));
              }
              if (isGraceLogin)
@@ -3791,11 +3816,13 @@
                {
                  AccountStatusNotificationType notificationType;
                  boolean tempLocked;
                  int lockoutDuration = pwPolicyState.getSecondsUntilUnlock();
                  if (lockoutDuration > -1)
                  {
                    notificationType = AccountStatusNotificationType.
                                            ACCOUNT_TEMPORARILY_LOCKED;
                    tempLocked = true;
                    message = ERR_BIND_ACCOUNT_TEMPORARILY_LOCKED.get(
                            secondsToTimeString(lockoutDuration));
@@ -3804,13 +3831,15 @@
                  {
                    notificationType = AccountStatusNotificationType.
                                            ACCOUNT_PERMANENTLY_LOCKED;
                    tempLocked = false;
                    message = ERR_BIND_ACCOUNT_PERMANENTLY_LOCKED.get();
                  }
                  pwPolicyState.generateAccountStatusNotification(
                       notificationType, localOp.getUserEntryDN(),
                          message);
                       notificationType, userEntry, message,
                       AccountStatusNotification.createProperties(pwPolicyState,
                             tempLocked, -1, null, null));
                }
              }
            }
@@ -3990,8 +4019,10 @@
              localOp.setAuthFailureReason(message);
              pwPolicyState.generateAccountStatusNotification(
                   AccountStatusNotificationType.ACCOUNT_EXPIRED, bindDN,
                      message);
                   AccountStatusNotificationType.ACCOUNT_EXPIRED,
                   saslAuthUserEntry, message,
                   AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, null, null));
              break bindProcessing;
            }
@@ -4037,8 +4068,10 @@
              localOp.setAuthFailureReason(message);
              pwPolicyState.generateAccountStatusNotification(
                   AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED, bindDN,
                      message);
                   AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED,
                   saslAuthUserEntry, message,
                   AccountStatusNotification.createProperties(pwPolicyState,
                         false, -1, null, null));
              break bindProcessing;
            }
@@ -4060,8 +4093,10 @@
                localOp.setAuthFailureReason(message);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.ACCOUNT_RESET_LOCKED, bindDN,
                        message);
                     AccountStatusNotificationType.ACCOUNT_RESET_LOCKED,
                     saslAuthUserEntry, message,
                     AccountStatusNotification.createProperties(pwPolicyState,
                           false, -1, null, null));
                break bindProcessing;
              }
@@ -4101,8 +4136,10 @@
                    localOp.setAuthFailureReason(message);
                    pwPolicyState.generateAccountStatusNotification(
                         AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
                            message);
                         AccountStatusNotificationType.PASSWORD_EXPIRED,
                         saslAuthUserEntry, message,
                         AccountStatusNotification.createProperties(
                              pwPolicyState, false, -1, null, null));
                    break bindProcessing;
                  }
@@ -4116,8 +4153,10 @@
                  localOp.setAuthFailureReason(message);
                  pwPolicyState.generateAccountStatusNotification(
                       AccountStatusNotificationType.PASSWORD_EXPIRED, bindDN,
                          message);
                       AccountStatusNotificationType.PASSWORD_EXPIRED,
                       saslAuthUserEntry, message,
                       AccountStatusNotification.createProperties(pwPolicyState,
                             false, -1, null, null));
                  break bindProcessing;
                }
@@ -4169,8 +4208,10 @@
                        timeToExpiration);
                pwPolicyState.generateAccountStatusNotification(
                     AccountStatusNotificationType.PASSWORD_EXPIRING, bindDN,
                        message);
                     AccountStatusNotificationType.PASSWORD_EXPIRING,
                     saslAuthUserEntry, message,
                     AccountStatusNotification.createProperties(pwPolicyState,
                           false, numSeconds, null, null));
              }
              if (isGraceLogin)
@@ -4369,6 +4410,7 @@
                  if (pwPolicyState.lockedDueToFailures())
                  {
                    AccountStatusNotificationType notificationType;
                    boolean tempLocked;
                    Message message;
                    int lockoutDuration = pwPolicyState.getSecondsUntilUnlock();
@@ -4376,6 +4418,7 @@
                    {
                      notificationType = AccountStatusNotificationType.
                                              ACCOUNT_TEMPORARILY_LOCKED;
                      tempLocked = true;
                      message = ERR_BIND_ACCOUNT_TEMPORARILY_LOCKED.get(
                              secondsToTimeString(lockoutDuration));
                    }
@@ -4383,12 +4426,14 @@
                    {
                      notificationType = AccountStatusNotificationType.
                                              ACCOUNT_PERMANENTLY_LOCKED;
                      tempLocked = false;
                      message = ERR_BIND_ACCOUNT_PERMANENTLY_LOCKED.get();
                    }
                    pwPolicyState.generateAccountStatusNotification(
                         notificationType, localOp.getUserEntryDN(),
                            message);
                         notificationType, saslAuthUserEntry, message,
                         AccountStatusNotification.createProperties(
                              pwPolicyState, tempLocked, -1, null, null));
                  }
                }
              }
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java
@@ -28,6 +28,9 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.testng.annotations.BeforeClass;
@@ -45,6 +48,10 @@
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicy;
import org.opends.server.core.PasswordPolicyState;
import org.opends.server.types.AccountStatusNotification;
import org.opends.server.types.AccountStatusNotificationProperty;
import org.opends.server.types.AccountStatusNotificationType;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
@@ -52,6 +59,9 @@
import static org.testng.Assert.*;
import static org.opends.server.types.AccountStatusNotificationType.*;
import static org.opends.server.types.AccountStatusNotificationProperty.*;
/**
@@ -213,6 +223,9 @@
  /**
   * Tests the <CODE>handleStatusNotification</CODE> method.
   *
   * @param  notificationType  The account status notification type to be
   *                           tested.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "notificationTypes")
@@ -220,6 +233,19 @@
                   AccountStatusNotificationType notificationType)
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
      "dn: uid=test.user,o=test",
      "objectClass: top",
      "objectClass: person",
      "objectClass: organizationalPerson",
      "objectClass: inetOrgPerson",
      "uid: test.user",
      "givenName: Test",
      "sn: User",
      "cn: Test User",
      "userPassword: password");
    String dnStr = "cn=Error Log Handler,cn=Account Status Notification " +
                        "Handlers,cn=config";
    DN handlerDN = DN.decode(dnStr);
@@ -227,9 +253,68 @@
         DirectoryServer.getAccountStatusNotificationHandler(handlerDN);
    assertNotNull(handler);
    DN userDN = DN.decode("uid=test.user,o=test");
    handler.handleStatusNotification(notificationType, userDN,
            Message.raw("Test Notification"));
    Entry userEntry =
               DirectoryServer.getEntry(DN.decode("uid=test.user,o=test"));
    PasswordPolicyState pwPolicyState =
         new PasswordPolicyState(userEntry, false, false);
    PasswordPolicy policy = pwPolicyState.getPolicy();
    HashMap<AccountStatusNotificationProperty,List<String>>
         notificationProperties =
              new HashMap<AccountStatusNotificationProperty,List<String>>();
    ArrayList<String> propList = new ArrayList<String>(1);
    propList.add(policy.getConfigEntryDN().toString());
    notificationProperties.put(PASSWORD_POLICY_DN, propList);
    if (notificationType == ACCOUNT_TEMPORARILY_LOCKED)
    {
      propList = new ArrayList<String>(1);
      propList.add("300");
      notificationProperties.put(SECONDS_UNTIL_UNLOCK, propList);
      propList = new ArrayList<String>(1);
      propList.add("5 minutes");
      notificationProperties.put(TIME_UNTIL_UNLOCK, propList);
      propList = new ArrayList<String>(1);
      propList.add(new Date(System.currentTimeMillis() + 300000L).toString());
      notificationProperties.put(ACCOUNT_UNLOCK_TIME, propList);
    }
    else if (notificationType == PASSWORD_EXPIRING)
    {
      propList = new ArrayList<String>(1);
      propList.add("86400");
      notificationProperties.put(SECONDS_UNTIL_EXPIRATION, propList);
      propList = new ArrayList<String>(1);
      propList.add("1 day");
      notificationProperties.put(TIME_UNTIL_EXPIRATION, propList);
      propList = new ArrayList<String>(1);
      propList.add(new Date(System.currentTimeMillis() + 86400000L).toString());
      notificationProperties.put(PASSWORD_EXPIRATION_TIME, propList);
    }
    else if ((notificationType == PASSWORD_CHANGED) ||
             (notificationType == PASSWORD_RESET))
    {
      propList = new ArrayList<String>(1);
      propList.add("oldpassword");
      notificationProperties.put(OLD_PASSWORD, propList);
      propList = new ArrayList<String>(1);
      propList.add("newpassword");
      notificationProperties.put(NEW_PASSWORD, propList);
    }
    AccountStatusNotification notification =
         new AccountStatusNotification(notificationType, userEntry,
                                       Message.raw("Test Modification"),
                                       notificationProperties);
    handler.handleStatusNotification(notification);
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TestAccountStatusNotificationHandler.java
New file
@@ -0,0 +1,152 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.extensions;
import java.util.concurrent.atomic.AtomicInteger;
import org.opends.server.admin.std.server.
       AccountStatusNotificationHandlerCfg;
import org.opends.server.api.AccountStatusNotificationHandler;
import org.opends.server.types.AccountStatusNotification;
import static org.testng.Assert.*;
import static org.opends.server.types.AccountStatusNotificationProperty.*;
/**
 * This class implements a simple account status notification handler that may
 * be used to ensure that all notifications are generated properly.
 */
public class TestAccountStatusNotificationHandler
extends AccountStatusNotificationHandler<AccountStatusNotificationHandlerCfg>
{
  // The number of notifications that this handler has processed.
  private static AtomicInteger notificationsProcessed = new AtomicInteger(0);
  /**
   * Creates a new instance of this test account status notification handler.
   */
  public TestAccountStatusNotificationHandler()
  {
    // No implementation is required.
  }
  /**
   * {@inheritDoc}
   */
  public void initializeStatusNotificationHandler(
                   AccountStatusNotificationHandlerCfg configuration)
  {
    // No implementation is required.
  }
  /**
   * {@inheritDoc}
   */
  public void handleStatusNotification(AccountStatusNotification notification)
  {
    notificationsProcessed.incrementAndGet();
    assertNotNull(notification);
    assertNotNull(notification.getNotificationType());
    assertNotNull(notification.getUserDN());
    assertNotNull(notification.getUserEntry());
    assertNotNull(notification.getMessage());
    assertNotNull(notification.getNotificationProperties());
    assertNotNull(
         notification.getNotificationProperties().get(PASSWORD_POLICY_DN));
    switch (notification.getNotificationType())
    {
      case ACCOUNT_TEMPORARILY_LOCKED:
        assertNotNull(
             notification.getNotificationProperties().get(ACCOUNT_UNLOCK_TIME));
        assertNotNull(
             notification.getNotificationProperties().get(
                  SECONDS_UNTIL_UNLOCK));
        assertNotNull(
             notification.getNotificationProperties().get(TIME_UNTIL_UNLOCK));
        break;
      case PASSWORD_EXPIRING:
        assertNotNull(
             notification.getNotificationProperties().get(
                  PASSWORD_EXPIRATION_TIME));
        assertNotNull(
             notification.getNotificationProperties().get(
                  SECONDS_UNTIL_EXPIRATION));
        assertNotNull(
             notification.getNotificationProperties().get(
                  TIME_UNTIL_EXPIRATION));
        break;
      case PASSWORD_CHANGED:
      case PASSWORD_RESET:
        // Note that the old password may not always be available, so we
        // can't check for it.
        assertNotNull(
             notification.getNotificationProperties().get(NEW_PASSWORD));
        break;
    }
  }
  /**
   * Retrieves the number of account status notifications that this handler has
   * processed.
   *
   * @return  The number of account status notifications that this handler has
   *          processed.
   */
  public static int getNotificationsProcessed()
  {
    return notificationsProcessed.get();
  }
  /**
   * Resets the counter used to keep track fo the number of account status
   * notfications that this handler has processed.
   */
  public static void resetCount()
  {
    notificationsProcessed.set(0);
  }
}