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