001/* 002 * Copyright 2015-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2018 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.unboundidds.extensions; 022 023 024 025import java.io.Serializable; 026import java.util.StringTokenizer; 027 028import com.unboundid.ldap.sdk.LDAPException; 029import com.unboundid.ldap.sdk.ResultCode; 030import com.unboundid.util.Debug; 031import com.unboundid.util.NotMutable; 032import com.unboundid.util.StaticUtils; 033import com.unboundid.util.ThreadSafety; 034import com.unboundid.util.ThreadSafetyLevel; 035import com.unboundid.util.Validator; 036 037import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 038 039 040 041/** 042 * This class defines a data structure that will provide information about 043 * warnings that may affect an account's usability. It includes a number of 044 * predefined warning types, but also allows for the possibility of additional 045 * warning types that have not been defined. 046 * <BR> 047 * <BLOCKQUOTE> 048 * <B>NOTE:</B> This class, and other classes within the 049 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 050 * supported for use against Ping Identity, UnboundID, and 051 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 052 * for proprietary functionality or for external specifications that are not 053 * considered stable or mature enough to be guaranteed to work in an 054 * interoperable way with other types of LDAP servers. 055 * </BLOCKQUOTE> 056 */ 057@NotMutable() 058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 059public final class PasswordPolicyStateAccountUsabilityWarning 060 implements Serializable 061{ 062 /** 063 * The numeric value for the warning type that indicates the user's account is 064 * about to expire. 065 */ 066 public static final int WARNING_TYPE_ACCOUNT_EXPIRING = 1; 067 068 069 070 /** 071 * The name for the warning type that indicates the user's account is about 072 * to expire. 073 */ 074 public static final String WARNING_NAME_ACCOUNT_EXPIRING = "account-expiring"; 075 076 077 078 /** 079 * The numeric value for the warning type that indicates the user's password 080 * is about to expire. 081 */ 082 public static final int WARNING_TYPE_PASSWORD_EXPIRING = 2; 083 084 085 086 /** 087 * The name for the warning type that indicates the user's password is about 088 * to expire. 089 */ 090 public static final String WARNING_NAME_PASSWORD_EXPIRING = 091 "password-expiring"; 092 093 094 095 /** 096 * The numeric value for the warning type that indicates the user has one or 097 * more failed authentication attempts since the last successful bind, and 098 * that the account may be locked if there are too many more failures. 099 */ 100 public static final int WARNING_TYPE_OUTSTANDING_BIND_FAILURES = 3; 101 102 103 104 /** 105 * The name for the warning type that indicates the user has one or more 106 * failed authentication attempts since the last successful bind, and that the 107 * account may be locked if there are too many more failures. 108 */ 109 public static final String WARNING_NAME_OUTSTANDING_BIND_FAILURES = 110 "outstanding-bind-failures"; 111 112 113 114 /** 115 * The numeric value for the warning type that indicates the user has not 116 * authenticated in some time, and the account may be locked in the near 117 * future if it remains idle. 118 */ 119 public static final int WARNING_TYPE_ACCOUNT_IDLE = 4; 120 121 122 123 /** 124 * The name for the warning type that indicates the user has not authenticated 125 * in some time, and the account may be locked in the near future if it 126 * remains idle. 127 */ 128 public static final String WARNING_NAME_ACCOUNT_IDLE = "account-idle"; 129 130 131 132 /** 133 * The numeric value for the warning type that indicates the user will be 134 * required to change his/her password by a specific time because the password 135 * policy requires all users to change their passwords by that time. 136 */ 137 public static final int WARNING_TYPE_REQUIRE_PASSWORD_CHANGE_BY_TIME = 5; 138 139 140 141 /** 142 * The name for the warning type that indicates the user user will be required 143 * to change his/her password by a specific time because the password policy 144 * requires all users to change their passwords by that time. 145 */ 146 public static final String WARNING_NAME_REQUIRE_PASSWORD_CHANGE_BY_TIME = 147 "require-password-change-by-time"; 148 149 150 151 /** 152 * The serial version UID for this serializable class. 153 */ 154 private static final long serialVersionUID = 4256291819633130578L; 155 156 157 158 // The integer value for this account usability warning. 159 private final int intValue; 160 161 // A human-readable message that provides specific details about this account 162 // usability warning. 163 private final String message; 164 165 // The name for this account usability warning. 166 private final String name; 167 168 // The encoded string representation for this account usability warning. 169 private final String stringRepresentation; 170 171 172 173 /** 174 * Creates a new account usability warning with the provided information. 175 * 176 * @param intValue The integer value for this account usability warning. 177 * @param name The name for this account usability warning. It must not 178 * be {@code null}. 179 * @param message A human-readable message that provides specific details 180 * about this account usability warning. It may be 181 * {@code null} if no message is available. 182 */ 183 public PasswordPolicyStateAccountUsabilityWarning(final int intValue, 184 final String name, 185 final String message) 186 { 187 Validator.ensureNotNull(name); 188 189 this.intValue = intValue; 190 this.name = name; 191 this.message = message; 192 193 final StringBuilder buffer = new StringBuilder(); 194 buffer.append("code="); 195 buffer.append(intValue); 196 buffer.append("\tname="); 197 buffer.append(name); 198 199 if (message != null) 200 { 201 buffer.append("\tmessage="); 202 buffer.append(message); 203 } 204 205 stringRepresentation = buffer.toString(); 206 } 207 208 209 210 /** 211 * Creates a new account usability warning that is decoded from the provided 212 * string representation. 213 * 214 * @param stringRepresentation The string representation of the account 215 * usability warning to decode. It must not be 216 * {@code null}. 217 * 218 * @throws LDAPException If the provided string cannot be decoded as a valid 219 * account usability warning. 220 */ 221 public PasswordPolicyStateAccountUsabilityWarning( 222 final String stringRepresentation) 223 throws LDAPException 224 { 225 this.stringRepresentation = stringRepresentation; 226 227 try 228 { 229 Integer i = null; 230 String n = null; 231 String m = null; 232 233 final StringTokenizer tokenizer = 234 new StringTokenizer(stringRepresentation, "\t"); 235 while (tokenizer.hasMoreTokens()) 236 { 237 final String token = tokenizer.nextToken(); 238 final int equalPos = token.indexOf('='); 239 final String fieldName = token.substring(0, equalPos); 240 final String fieldValue = token.substring(equalPos+1); 241 if (fieldName.equals("code")) 242 { 243 i = Integer.valueOf(fieldValue); 244 } 245 else if (fieldName.equals("name")) 246 { 247 n = fieldValue; 248 } 249 else if (fieldName.equals("message")) 250 { 251 m = fieldValue; 252 } 253 } 254 255 if (i == null) 256 { 257 throw new LDAPException(ResultCode.DECODING_ERROR, 258 ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_CANNOT_DECODE.get( 259 stringRepresentation, 260 ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_NO_CODE.get())); 261 } 262 263 if (n == null) 264 { 265 throw new LDAPException(ResultCode.DECODING_ERROR, 266 ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_CANNOT_DECODE.get( 267 stringRepresentation, 268 ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_NO_NAME.get())); 269 } 270 271 intValue = i; 272 name = n; 273 message = m; 274 } 275 catch (final LDAPException le) 276 { 277 Debug.debugException(le); 278 279 throw le; 280 } 281 catch (final Exception e) 282 { 283 Debug.debugException(e); 284 285 throw new LDAPException(ResultCode.DECODING_ERROR, 286 ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_CANNOT_DECODE.get( 287 stringRepresentation, StaticUtils.getExceptionMessage(e)), 288 e); 289 } 290 } 291 292 293 294 /** 295 * Retrieves the integer value for this account usability warning. 296 * 297 * @return The integer value for this account usability warning. 298 */ 299 public int getIntValue() 300 { 301 return intValue; 302 } 303 304 305 306 /** 307 * Retrieves the name for this account usability warning. 308 * 309 * @return The name for this account usability warning. 310 */ 311 public String getName() 312 { 313 return name; 314 } 315 316 317 318 /** 319 * Retrieves a human-readable message that provides specific details about 320 * this account usability warning. 321 * 322 * @return A human-readable message that provides specific details about this 323 * account usability warning, or {@code null} if no message is 324 * available. 325 */ 326 public String getMessage() 327 { 328 return message; 329 } 330 331 332 333 /** 334 * Retrieves a string representation of this account usability warning. 335 * 336 * @return A string representation of this account usability warning. 337 */ 338 @Override() 339 public String toString() 340 { 341 return stringRepresentation; 342 } 343}