001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2008 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.extensions; 018 019import static org.opends.messages.ExtensionMessages.*; 020 021import org.forgerock.i18n.LocalizableMessage; 022import org.forgerock.i18n.slf4j.LocalizedLogger; 023 024import java.util.HashSet; 025import java.util.List; 026 027import org.opends.server.admin.server.ConfigurationChangeListener; 028import org.opends.server.admin.std.meta. 029 ErrorLogAccountStatusNotificationHandlerCfgDefn; 030import org.opends.server.admin.std.server.AccountStatusNotificationHandlerCfg; 031import org.opends.server.admin.std.server. 032 ErrorLogAccountStatusNotificationHandlerCfg; 033import org.opends.server.api.AccountStatusNotificationHandler; 034import org.forgerock.opendj.config.server.ConfigException; 035import org.opends.server.types.AccountStatusNotification; 036import org.opends.server.types.AccountStatusNotificationType; 037import org.forgerock.opendj.config.server.ConfigChangeResult; 038import org.forgerock.opendj.ldap.DN; 039import org.opends.server.types.InitializationException; 040 041/** 042 * This class defines an account status notification handler that will write 043 * information about status notifications using the Directory Server's error 044 * logging facility. 045 */ 046public class ErrorLogAccountStatusNotificationHandler 047 extends 048 AccountStatusNotificationHandler 049 <ErrorLogAccountStatusNotificationHandlerCfg> 050 implements 051 ConfigurationChangeListener 052 <ErrorLogAccountStatusNotificationHandlerCfg> 053{ 054 055 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 056 057 /** 058 * The set of names for the account status notification types that may be 059 * logged by this notification handler. 060 */ 061 private static final HashSet<String> NOTIFICATION_TYPE_NAMES = new HashSet<>(); 062 static 063 { 064 for (AccountStatusNotificationType t : AccountStatusNotificationType.values()) 065 { 066 NOTIFICATION_TYPE_NAMES.add(t.getName()); 067 } 068 } 069 070 071 /** The DN of the configuration entry for this notification handler. */ 072 private DN configEntryDN; 073 074 /** The set of notification types that should generate log messages. */ 075 private HashSet<AccountStatusNotificationType> notificationTypes; 076 077 078 079 /** {@inheritDoc} */ 080 public void initializeStatusNotificationHandler( 081 ErrorLogAccountStatusNotificationHandlerCfg configuration 082 ) 083 throws ConfigException, InitializationException 084 { 085 configuration.addErrorLogChangeListener (this); 086 configEntryDN = configuration.dn(); 087 088 // Read configuration and apply changes. 089 boolean applyChanges = true; 090 processNotificationHandlerConfig (configuration, applyChanges); 091 } 092 093 094 095 /** {@inheritDoc} */ 096 public void handleStatusNotification( 097 AccountStatusNotification notification) 098 { 099 logger.info(NOTE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION, 100 notification.getNotificationType().getName(), 101 notification.getUserDN(), 102 notification.getMessage().ordinal(), 103 notification.getMessage()); 104 } 105 106 107 108 /** {@inheritDoc} */ 109 @Override 110 public boolean isConfigurationAcceptable( 111 AccountStatusNotificationHandlerCfg configuration, 112 List<LocalizableMessage> unacceptableReasons) 113 { 114 ErrorLogAccountStatusNotificationHandlerCfg config = 115 (ErrorLogAccountStatusNotificationHandlerCfg) configuration; 116 return isConfigurationChangeAcceptable(config, unacceptableReasons); 117 } 118 119 120 121 /** {@inheritDoc} */ 122 public boolean isConfigurationChangeAcceptable( 123 ErrorLogAccountStatusNotificationHandlerCfg configuration, 124 List<LocalizableMessage> unacceptableReasons) 125 { 126 // Make sure that we can process the defined notification handler. 127 // If so, then we'll accept the new configuration. 128 boolean applyChanges = false; 129 return processNotificationHandlerConfig ( 130 configuration, applyChanges); 131 } 132 133 134 135 /** 136 * Makes a best-effort attempt to apply the configuration contained in the 137 * provided entry. Information about the result of this processing should be 138 * added to the provided message list. Information should always be added to 139 * this list if a configuration change could not be applied. If detailed 140 * results are requested, then information about the changes applied 141 * successfully (and optionally about parameters that were not changed) should 142 * also be included. 143 * 144 * @param configuration The entry containing the new configuration to 145 * apply for this component. 146 * @param detailedResults Indicates whether detailed information about the 147 * processing should be added to the list. 148 * 149 * @return Information about the result of the configuration update. 150 */ 151 public ConfigChangeResult applyConfigurationChange ( 152 ErrorLogAccountStatusNotificationHandlerCfg configuration, 153 boolean detailedResults) 154 { 155 return applyConfigurationChange(configuration); 156 } 157 158 159 160 /** {@inheritDoc} */ 161 public ConfigChangeResult applyConfigurationChange ( 162 ErrorLogAccountStatusNotificationHandlerCfg configuration 163 ) 164 { 165 // Initialize the set of notification types that should generate log messages. 166 boolean applyChanges =false; 167 processNotificationHandlerConfig (configuration, applyChanges); 168 169 return new ConfigChangeResult(); 170 } 171 172 173 /** 174 * Parses the provided configuration and configure the notification handler. 175 * 176 * @param configuration The new configuration containing the changes. 177 * @param applyChanges If true then take into account the new configuration. 178 * 179 * @return The mapping between strings of character set values and the 180 * minimum number of characters required from those sets. 181 */ 182 public boolean processNotificationHandlerConfig( 183 ErrorLogAccountStatusNotificationHandlerCfg configuration, 184 boolean applyChanges 185 ) 186 { 187 // false if the configuration is not acceptable 188 boolean isAcceptable = true; 189 190 // The set of notification types that should generate log messages. 191 HashSet<AccountStatusNotificationType> newNotificationTypes = new HashSet<>(); 192 193 // Initialize the set of notification types that should generate log messages. 194 for (ErrorLogAccountStatusNotificationHandlerCfgDefn. 195 AccountStatusNotificationType configNotificationType: 196 configuration.getAccountStatusNotificationType()) 197 { 198 newNotificationTypes.add (getNotificationType (configNotificationType)); 199 } 200 201 if (applyChanges && isAcceptable) 202 { 203 notificationTypes = newNotificationTypes; 204 } 205 206 return isAcceptable; 207 } 208 209 210 /** 211 * Gets the OpenDS notification type object that corresponds to the 212 * configuration counterpart. 213 * 214 * @param configNotificationType The configuration notification type for 215 * which to retrieve the OpenDS notification 216 * type. 217 */ 218 private AccountStatusNotificationType getNotificationType( 219 ErrorLogAccountStatusNotificationHandlerCfgDefn. 220 AccountStatusNotificationType configNotificationType 221 ) 222 { 223 AccountStatusNotificationType nt = null; 224 225 switch (configNotificationType) 226 { 227 case ACCOUNT_TEMPORARILY_LOCKED: 228 nt = AccountStatusNotificationType.ACCOUNT_TEMPORARILY_LOCKED; 229 break; 230 case ACCOUNT_PERMANENTLY_LOCKED: 231 nt = AccountStatusNotificationType.ACCOUNT_PERMANENTLY_LOCKED; 232 break; 233 case ACCOUNT_UNLOCKED: 234 nt = AccountStatusNotificationType.ACCOUNT_UNLOCKED; 235 break; 236 case ACCOUNT_IDLE_LOCKED: 237 nt = AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED; 238 break; 239 case ACCOUNT_RESET_LOCKED: 240 nt = AccountStatusNotificationType.ACCOUNT_RESET_LOCKED; 241 break; 242 case ACCOUNT_DISABLED: 243 nt = AccountStatusNotificationType.ACCOUNT_DISABLED; 244 break; 245 case ACCOUNT_ENABLED: 246 nt = AccountStatusNotificationType.ACCOUNT_ENABLED; 247 break; 248 case ACCOUNT_EXPIRED: 249 nt = AccountStatusNotificationType.ACCOUNT_EXPIRED; 250 break; 251 case PASSWORD_EXPIRED: 252 nt = AccountStatusNotificationType.PASSWORD_EXPIRED; 253 break; 254 case PASSWORD_EXPIRING: 255 nt = AccountStatusNotificationType.PASSWORD_EXPIRING; 256 break; 257 case PASSWORD_RESET: 258 nt = AccountStatusNotificationType.PASSWORD_RESET; 259 break; 260 case PASSWORD_CHANGED: 261 nt = AccountStatusNotificationType.PASSWORD_CHANGED; 262 break; 263 } 264 265 return nt; 266 } 267 268} 269