001/* 002 * Copyright 2007-2017 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2008-2017 UnboundID Corp. 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.controls; 022 023 024 025import com.unboundid.asn1.ASN1OctetString; 026import com.unboundid.ldap.sdk.Control; 027import com.unboundid.ldap.sdk.DecodeableControl; 028import com.unboundid.ldap.sdk.LDAPException; 029import com.unboundid.ldap.sdk.LDAPResult; 030import com.unboundid.ldap.sdk.ResultCode; 031import com.unboundid.util.NotMutable; 032import com.unboundid.util.ThreadSafety; 033import com.unboundid.util.ThreadSafetyLevel; 034 035import static com.unboundid.ldap.sdk.controls.ControlMessages.*; 036import static com.unboundid.util.Debug.*; 037 038 039 040/** 041 * This class provides an implementation of the expiring expiring control as 042 * described in draft-vchu-ldap-pwd-policy. It may be used to indicate that the 043 * authenticated user's password will expire in the near future. The value of 044 * this control includes the length of time in seconds until the user's 045 * password actually expires. 046 * <BR><BR> 047 * No request control is required to trigger the server to send the password 048 * expiring response control. If the server supports the use of this control 049 * and the user's password will expire within a time frame that the server 050 * considers to be the near future, then it will be included in the bind 051 * response returned to the client. 052 * <BR><BR> 053 * See the documentation for the {@link PasswordExpiredControl} to see an 054 * example that demonstrates the use of both the password expiring and password 055 * expired controls. 056 */ 057@NotMutable() 058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 059public final class PasswordExpiringControl 060 extends Control 061 implements DecodeableControl 062{ 063 /** 064 * The OID (2.16.840.1.113730.3.4.5) for the password expiring response 065 * control. 066 */ 067 public static final String PASSWORD_EXPIRING_OID = "2.16.840.1.113730.3.4.5"; 068 069 070 071 /** 072 * The serial version UID for this serializable class. 073 */ 074 private static final long serialVersionUID = 1250220480854441338L; 075 076 077 078 // The length of time in seconds until the password expires. 079 private final int secondsUntilExpiration; 080 081 082 083 /** 084 * Creates a new empty control instance that is intended to be used only for 085 * decoding controls via the {@code DecodeableControl} interface. 086 */ 087 PasswordExpiringControl() 088 { 089 secondsUntilExpiration = -1; 090 } 091 092 093 094 /** 095 * Creates a new password expiring control with the provided information. 096 * 097 * @param secondsUntilExpiration The length of time in seconds until the 098 * password expires. 099 */ 100 public PasswordExpiringControl(final int secondsUntilExpiration) 101 { 102 super(PASSWORD_EXPIRING_OID, false, 103 new ASN1OctetString(String.valueOf(secondsUntilExpiration))); 104 105 this.secondsUntilExpiration = secondsUntilExpiration; 106 } 107 108 109 110 /** 111 * Creates a new password expiring control with the provided information. 112 * 113 * @param oid The OID for the control. 114 * @param isCritical Indicates whether the control should be marked 115 * critical. 116 * @param value The encoded value for the control. This may be 117 * {@code null} if no value was provided. 118 * 119 * @throws LDAPException If the provided control cannot be decoded as a 120 * password expiring response control. 121 */ 122 public PasswordExpiringControl(final String oid, final boolean isCritical, 123 final ASN1OctetString value) 124 throws LDAPException 125 { 126 super(oid, isCritical, value); 127 128 if (value == null) 129 { 130 throw new LDAPException(ResultCode.DECODING_ERROR, 131 ERR_PW_EXPIRING_NO_VALUE.get()); 132 } 133 134 try 135 { 136 secondsUntilExpiration = Integer.parseInt(value.stringValue()); 137 } 138 catch (NumberFormatException nfe) 139 { 140 debugException(nfe); 141 throw new LDAPException(ResultCode.DECODING_ERROR, 142 ERR_PW_EXPIRING_VALUE_NOT_INTEGER.get(), nfe); 143 } 144 } 145 146 147 148 /** 149 * {@inheritDoc} 150 */ 151 public PasswordExpiringControl 152 decodeControl(final String oid, final boolean isCritical, 153 final ASN1OctetString value) 154 throws LDAPException 155 { 156 return new PasswordExpiringControl(oid, isCritical, value); 157 } 158 159 160 161 /** 162 * Extracts a password expiring control from the provided result. 163 * 164 * @param result The result from which to retrieve the password expiring 165 * control. 166 * 167 * @return The password expiring control contained in the provided result, or 168 * {@code null} if the result did not contain a password expiring 169 * control. 170 * 171 * @throws LDAPException If a problem is encountered while attempting to 172 * decode the password expiring control contained in 173 * the provided result. 174 */ 175 public static PasswordExpiringControl get(final LDAPResult result) 176 throws LDAPException 177 { 178 final Control c = result.getResponseControl(PASSWORD_EXPIRING_OID); 179 if (c == null) 180 { 181 return null; 182 } 183 184 if (c instanceof PasswordExpiringControl) 185 { 186 return (PasswordExpiringControl) c; 187 } 188 else 189 { 190 return new PasswordExpiringControl(c.getOID(), c.isCritical(), 191 c.getValue()); 192 } 193 } 194 195 196 197 /** 198 * Retrieves the length of time in seconds until the password expires. 199 * 200 * @return The length of time in seconds until the password expires. 201 */ 202 public int getSecondsUntilExpiration() 203 { 204 return secondsUntilExpiration; 205 } 206 207 208 209 /** 210 * {@inheritDoc} 211 */ 212 @Override() 213 public String getControlName() 214 { 215 return INFO_CONTROL_NAME_PW_EXPIRING.get(); 216 } 217 218 219 220 /** 221 * {@inheritDoc} 222 */ 223 @Override() 224 public void toString(final StringBuilder buffer) 225 { 226 buffer.append("PasswordExpiringControl(secondsUntilExpiration="); 227 buffer.append(secondsUntilExpiration); 228 buffer.append(", isCritical="); 229 buffer.append(isCritical()); 230 buffer.append(')'); 231 } 232}