001package com.pingidentity.ds.virtualAttribute; 002 003import com.unboundid.directory.sdk.common.types.Entry; 004import com.unboundid.directory.sdk.common.types.OperationContext; 005import com.unboundid.directory.sdk.ds.api.VirtualAttributeProvider; 006import com.unboundid.directory.sdk.ds.config.VirtualAttributeProviderConfig; 007import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; 008import com.unboundid.ldap.sdk.*; 009import com.unboundid.ldap.sdk.unboundidds.extensions.PasswordPolicyStateExtendedRequest; 010import com.unboundid.ldap.sdk.unboundidds.extensions.PasswordPolicyStateExtendedResult; 011import com.unboundid.ldap.sdk.unboundidds.extensions.PasswordPolicyStateOperation; 012import com.unboundid.util.args.*; 013 014import java.text.ParseException; 015import java.text.SimpleDateFormat; 016import java.util.Date; 017import java.util.List; 018 019/** 020 * 021 */ 022public class PasswordExpirationTime extends VirtualAttributeProvider { 023 024 public static final String DATE_FORMAT_ARGUMENT = "date-format"; 025 private SimpleDateFormat dateFormat = null; 026 027 @Override 028 public String getExtensionName() { 029 return "PasswordExpirationTimeVirtualAttributeProvider"; 030 } 031 032 @Override 033 public String[] getExtensionDescription() { 034 return new String[]{"A virtual attribute provider that computes the password expiration time based on a user's password last changed time and the expiration time configured in the password policy it is assigned to."}; 035 } 036 037 038 @Override 039 public void defineConfigArguments(ArgumentParser parser) throws ArgumentException { 040 StringArgument stringArgument = new StringArgument(null, DATE_FORMAT_ARGUMENT, false, 1, "{regex}", "The format to use to generate the virtual attribute. (default: yyyyMMddHHmmss.SSSZ)"); 041 stringArgument.addValueValidator(new ArgumentValueValidator() { 042 @Override 043 public void validateArgumentValue(Argument argument, String datePattern) throws ArgumentException { 044 try { 045 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern); 046 } catch (IllegalArgumentException iae) { 047 throw new ArgumentException(iae.getMessage(), iae); 048 } 049 } 050 }); 051 parser.addArgument(stringArgument); 052 } 053 054 @Override 055 public ResultCode applyConfiguration(VirtualAttributeProviderConfig config, ArgumentParser parser, List<String> adminActionsRequired, List<String> messages) { 056 StringArgument dateFormatArgument = parser.getStringArgument(DATE_FORMAT_ARGUMENT); 057 if (dateFormatArgument != null && dateFormatArgument.isPresent()) { 058 String dateFormatString = dateFormatArgument.getValue(); 059 dateFormat = new SimpleDateFormat(dateFormatString); 060 } 061 return ResultCode.SUCCESS; 062 } 063 064 @Override 065 public void initializeVirtualAttributeProvider(DirectoryServerContext serverContext, VirtualAttributeProviderConfig config, ArgumentParser parser) throws LDAPException { 066 applyConfiguration(config, parser, null, null); 067 } 068 069 @Override 070 public boolean isMultiValued() { 071 return false; 072 } 073 074 @Override 075 public Attribute generateAttribute(OperationContext operationContext, Entry entry, String attributeName) { 076 try { 077 Control[] controls = null; 078 PasswordPolicyStateOperation getPasswordExpirationTimeOperation = PasswordPolicyStateOperation.createGetPasswordExpirationTimeOperation(); 079 ExtendedResult extendedResult = operationContext.getInternalUserConnection().processExtendedOperation(new 080 PasswordPolicyStateExtendedRequest(entry.getDN(), controls, getPasswordExpirationTimeOperation)); 081 PasswordPolicyStateExtendedResult pwpResult = new PasswordPolicyStateExtendedResult(extendedResult); 082 if (ResultCode.SUCCESS == pwpResult.getResultCode()) { 083 PasswordPolicyStateOperation operation = pwpResult.getOperation(getPasswordExpirationTimeOperation.getOperationType()); 084 if (dateFormat == null) { 085 return new Attribute(attributeName, operation.getRawValues()); 086 } else { 087 return new Attribute(attributeName, dateFormat.format(operation.getGeneralizedTimeValue())); 088 } 089 } 090 } catch (LDAPException e) { 091 System.err.println(e.getDiagnosticMessage()); 092 } catch (ParseException pe) { 093 System.err.println(pe.getMessage()); 094 } 095 return null; 096 } 097}