/* * 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 * docs/licenses/cddl.txt * or http://www.opensource.org/licenses/cddl1.php. * 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 * docs/licenses/cddl.txt. 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 2010-2023 Ping Identity Corporation */ package com.unboundid.directory.sdk.examples; import java.util.Date; import java.util.List; import com.unboundid.directory.sdk.common.types.AlertSeverity; import com.unboundid.directory.sdk.ds.api.AccountStatusNotificationHandler; import com.unboundid.directory.sdk.ds.config. AccountStatusNotificationHandlerConfig; import com.unboundid.directory.sdk.ds.types.AccountStatusNotification; import com.unboundid.directory.sdk.ds.types.AccountStatusNotificationProperty; import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; import com.unboundid.ldap.sdk.LDAPException; import com.unboundid.util.StaticUtils; import com.unboundid.util.args.ArgumentParser; /** * This class provides a simple example of an account status notification * handler which will generate an administrative alert any time a user account * has been locked as a result of too many failed bind attempts. */ public final class ExampleAccountStatusNotificationHandler extends AccountStatusNotificationHandler { // The server context for the server in which this extension is running. private DirectoryServerContext serverContext = null; /** * Creates a new instance of this account status notification handler. All * account status notification handler implementations must include a default * constructor, but any initialization should generally be done in the * {@code initializeAccountStatusNotificationHandler} method. */ public ExampleAccountStatusNotificationHandler() { // No implementation required. } /** * Retrieves a human-readable name for this extension. * * @return A human-readable name for this extension. */ @Override() public String getExtensionName() { return "Example Account Status Notification Handler"; } /** * Retrieves a human-readable description for this extension. Each element * of the array that is returned will be considered a separate paragraph in * generated documentation. * * @return A human-readable description for this extension, or {@code null} * or an empty array if no description should be available. */ @Override() public String[] getExtensionDescription() { return new String[] { "This account status notification handler serves as an example that " + "may be used to demonstrate the process for creating a " + "third-party account status notification handler. It will " + "generate an administrative alert any time a user account is " + "locked as a result of too many failed bind attempts." }; } /** * Initializes this account status notification handler. * * @param serverContext A handle to the server context for the server in * which this extension is running. * @param config The general configuration for this account status * notification handler. * @param parser The argument parser which has been initialized from * the configuration for this account status * notification handler. * * @throws LDAPException If a problem occurs while initializing this account * status notification handler. */ @Override() public void initializeAccountStatusNotificationHandler( final DirectoryServerContext serverContext, final AccountStatusNotificationHandlerConfig config, final ArgumentParser parser) throws LDAPException { serverContext.debugInfo( "Beginning account status notification handler initialization"); this.serverContext = serverContext; } /** * Performs any processing that may be necessary in conjunction with the * provided account status notification. * * @param notification The account status notification to be processed. */ @Override() public void handleStatusNotification( final AccountStatusNotification notification) { switch (notification.getNotificationType()) { case ACCOUNT_PERMANENTLY_LOCKED: case ACCOUNT_TEMPORARILY_LOCKED: // These notification types will result in administrative alerts. That // will be done later in this method. break; default: // We will not generate an alert for these notification types. return; } // See if there is an unlock time. Date unlockTime = null; try { final List<String> unlockTimeValues = notification.getNotificationProperty( AccountStatusNotificationProperty.ACCOUNT_UNLOCK_TIME); if ((unlockTimeValues != null) && (! unlockTimeValues.isEmpty())) { unlockTime = StaticUtils.decodeGeneralizedTime(unlockTimeValues.get(0)); } } catch (final Exception e) { serverContext.debugCaught(e); } // Generate a message to include in the alert. final StringBuilder alertMessage = new StringBuilder(); alertMessage.append("User account '"); alertMessage.append(notification.getUserDN()); alertMessage.append("' has been locked as a result of too many failed "+ "authentication attempts. The account will remain locked until "); if (unlockTime != null) { alertMessage.append(unlockTime); alertMessage.append(" or until "); } alertMessage.append("an administrator resets the user's password."); serverContext.sendAlert(AlertSeverity.INFO, alertMessage.toString()); } }