001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * docs/licenses/cddl.txt 011 * or http://www.opensource.org/licenses/cddl1.php. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * docs/licenses/cddl.txt. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Portions Copyright 2010-2024 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.ds.scripting; 028 029 030 031import java.util.List; 032 033import com.unboundid.directory.sdk.common.internal.Reconfigurable; 034import com.unboundid.directory.sdk.ds.config. 035 AccountStatusNotificationHandlerConfig; 036import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension; 037import com.unboundid.directory.sdk.ds.types.AccountStatusNotification; 038import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; 039import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension; 040import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension; 041import com.unboundid.ldap.sdk.LDAPException; 042import com.unboundid.ldap.sdk.ResultCode; 043import com.unboundid.util.Extensible; 044import com.unboundid.util.ThreadSafety; 045import com.unboundid.util.ThreadSafetyLevel; 046import com.unboundid.util.args.ArgumentException; 047import com.unboundid.util.args.ArgumentParser; 048 049 050 051/** 052 * This class defines an API that must be implemented by scripted extensions 053 * which have the ability to process notifications about events that occur that 054 * could change the status of a user account. For example, account status 055 * notification handlers may be used to notify the end user and/or 056 * administrators of a change to that user's account. The kinds of events that 057 * may trigger account status notifications are defined in the 058 * {@link com.unboundid.directory.sdk.ds.types.AccountStatusNotificationType} 059 * enum, and include things like user accounts locked due to authentication 060 * failures, password expiration errors and warnings, and administrative 061 * password resets. 062 * <BR> 063 * <H2>Configuring Groovy-Scripted Account Status Notification Handlers</H2> 064 * In order to configure a scripted account status notification handler based on 065 * this API and written in the Groovy scripting language, use a command like: 066 * <PRE> 067 * dsconfig create-account-status-notification-handler \ 068 * --handler-name "<I>{handler-name}</I>" \ 069 * --type groovy-scripted \ 070 * --set enabled:true \ 071 * --set "script-class:<I>{class-name}</I>" \ 072 * --set "script-argument:<I>{name=value}</I>" 073 * </PRE> 074 * where "<I>{handler-name}</I>" is the name to use for the account status 075 * notification handler instance, "<I>{class-name}</I>" is the fully-qualified 076 * name of the Groovy class written using this API, and "<I>{name=value}</I>" 077 * represents name-value pairs for any arguments to provide to the account 078 * status notification handler. If multiple arguments should be provided to the 079 * account status notification handler, then the 080 * "<CODE>--set script-argument:<I>{name=value}</I></CODE>" option should be 081 * provided multiple times. 082 * 083 * @see com.unboundid.directory.sdk.ds.api.AccountStatusNotificationHandler 084 */ 085@Extensible() 086@DirectoryServerExtension() 087@DirectoryProxyServerExtension(appliesToLocalContent=true, 088 appliesToRemoteContent=false) 089@SynchronizationServerExtension(appliesToLocalContent=true, 090 appliesToSynchronizedContent=false) 091@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 092public abstract class ScriptedAccountStatusNotificationHandler 093 implements Reconfigurable<AccountStatusNotificationHandlerConfig> 094{ 095 /** 096 * Creates a new instance of this account status notification handler. All 097 * account status notification handler implementations must include a default 098 * constructor, but any initialization should generally be done in the 099 * {@code initializeAccountStatusNotificationHandler} method. 100 */ 101 public ScriptedAccountStatusNotificationHandler() 102 { 103 // No implementation is required. 104 } 105 106 107 108 /** 109 * {@inheritDoc} 110 */ 111 public void defineConfigArguments(final ArgumentParser parser) 112 throws ArgumentException 113 { 114 // No arguments will be allowed by default. 115 } 116 117 118 119 /** 120 * Initializes this account status notification handler. 121 * 122 * @param serverContext A handle to the server context for the server in 123 * which this extension is running. 124 * @param config The general configuration for this account status 125 * notification handler. 126 * @param parser The argument parser which has been initialized from 127 * the configuration for this account status 128 * notification handler. 129 * 130 * @throws LDAPException If a problem occurs while initializing this account 131 * status notification handler. 132 */ 133 public void initializeAccountStatusNotificationHandler( 134 final DirectoryServerContext serverContext, 135 final AccountStatusNotificationHandlerConfig config, 136 final ArgumentParser parser) 137 throws LDAPException 138 { 139 // No initialization will be performed by default. 140 } 141 142 143 144 /** 145 * {@inheritDoc} 146 */ 147 public boolean isConfigurationAcceptable( 148 final AccountStatusNotificationHandlerConfig config, 149 final ArgumentParser parser, 150 final List<String> unacceptableReasons) 151 { 152 // No extended validation will be performed. 153 return true; 154 } 155 156 157 158 /** 159 * {@inheritDoc} 160 */ 161 public ResultCode applyConfiguration( 162 final AccountStatusNotificationHandlerConfig config, 163 final ArgumentParser parser, 164 final List<String> adminActionsRequired, 165 final List<String> messages) 166 { 167 // By default, no configuration changes will be applied. If there are any 168 // arguments, then add an admin action message indicating that the extension 169 // needs to be restarted for any changes to take effect. 170 if (! parser.getNamedArguments().isEmpty()) 171 { 172 adminActionsRequired.add( 173 "No configuration change has actually been applied. The new " + 174 "configuration will not take effect until this account " + 175 "status notification handler is disabled and re-enabled or " + 176 "until the server is restarted."); 177 } 178 179 return ResultCode.SUCCESS; 180 } 181 182 183 184 /** 185 * Performs any cleanup which may be necessary when this account status 186 * notification handler is to be taken out of service. 187 */ 188 public void finalizeAccountStatusNotificationHandler() 189 { 190 // No implementation is required. 191 } 192 193 194 195 /** 196 * Performs any processing that may be necessary in conjunction with the 197 * provided account status notification. 198 * 199 * @param notification The account status notification to be processed. 200 */ 201 public abstract void handleStatusNotification( 202 final AccountStatusNotification notification); 203}