if (null == credentials)
{
credentials = new ArrayList();
}
InternalCredential credential = getPasswordCredential(internalUser, userName );
if (null != oldPassword)
{
if ( credential != null &&
credential.getValue() != null &&
credential.isEncoded() &&
pcProvider.getEncoder() != null )
{
if ( pcProvider.getEncoder() instanceof AlgorithmUpgradeCredentialPasswordEncoder )
{
oldPassword = ((AlgorithmUpgradeCredentialPasswordEncoder)pcProvider.getEncoder()).encode(userName,oldPassword, credential);
}
else
{
oldPassword = pcProvider.getEncoder().encode(userName,oldPassword);
}
}
}
if (oldPassword != null && (credential == null || credential.getValue() == null || !credential.getValue().equals(oldPassword)))
{
// supplied PasswordCredential not defined for this user
throw new InvalidPasswordException();
}
if (!raw) // bypass validation if raw
{
if ( pcProvider.getValidator() != null )
{
try
{
pcProvider.getValidator().validate(newPassword);
}
catch (InvalidPasswordException ipe)
{
throw new InvalidNewPasswordException();
}
}
}
boolean encoded = false;
if ( pcProvider.getEncoder() != null )
{
if (!(raw)) // if raw just bypass encoding
newPassword = pcProvider.getEncoder().encode(userName, newPassword);
encoded = true;
}
boolean create = credential == null;
if ( create )
{
credential = new InternalCredentialImpl(internalUser.getPrincipalId(), newPassword, InternalCredential.PRIVATE,
pcProvider.getPasswordCredentialClass().getName());
credential.setEncoded(encoded);
credentials.add(credential);
}
else if ( oldPassword == null )
{
/* TODO: should only be allowed for admin
// User *has* an PasswordCredential: setting a new Credential without supplying
// its current one is not allowed
throw new SecurityException(SecurityException.PASSWORD_REQUIRED);
*/
}
else if ( oldPassword.equals(newPassword) )
{
throw new PasswordAlreadyUsedException();
}
if ( ipcInterceptor != null )
{
if ( create )
{
ipcInterceptor.beforeCreate(internalUser, credentials, userName, credential, newPassword );
}
else
{
ipcInterceptor.beforeSetPassword(internalUser, credentials, userName, credential, newPassword, oldPassword != null );
}
}
if (!create)
{
credential.setValue(newPassword);
credential.setEncoded(encoded);
credential.setUpdateRequired(false);
}
long time = new Date().getTime();
if ( oldPassword == null )
{
// non-user (admin) modified the password
if ( encoded && pcProvider.getEncoder() instanceof AlgorithmUpgradePasswordEncodingService )
{
// set current time in previous auth date, and clear last authentication date
// !!! While this might be a bit strange logic, it is *required* for the AlgorithmUpgradePBEPasswordEncodingService
// to be able to distinguise password changes from other changes
credential.setPreviousAuthenticationDate(new Timestamp(new Date().getTime()));
credential.setLastAuthenticationDate(null);
}
}
else
{
// authenticated password change (by user itself)
credential.setPreviousAuthenticationDate(credential.getLastAuthenticationDate());
credential.setLastAuthenticationDate(new Timestamp(time));
}
credential.setModifiedDate(new Timestamp(time));
internalUser.setModifiedDate(new Timestamp(time));
internalUser.setCredentials(credentials);
// Set the user with the new credentials.
securityAccess.setInternalUserPrincipal(internalUser, false);
}