/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.web.portal.services;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.mail.MessagingException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.enonic.esl.containers.ExtendedMap;
import com.enonic.esl.containers.MultiValueMap;
import com.enonic.esl.servlet.http.CookieUtil;
import com.enonic.esl.util.ArrayUtil;
import com.enonic.esl.util.StringUtil;
import com.enonic.vertical.engine.VerticalCreateException;
import com.enonic.vertical.engine.VerticalEngineException;
import com.enonic.vertical.engine.VerticalSecurityException;
import com.enonic.cms.api.plugin.ext.userstore.UserFields;
import com.enonic.cms.core.DeploymentPathResolver;
import com.enonic.cms.core.log.LogService;
import com.enonic.cms.core.log.LogType;
import com.enonic.cms.core.log.StoreNewLogEntryCommand;
import com.enonic.cms.core.login.LoginService;
import com.enonic.cms.core.mail.MailRecipientType;
import com.enonic.cms.core.mail.MessageSettings;
import com.enonic.cms.core.mail.SendMailService;
import com.enonic.cms.core.mail.SimpleMailTemplate;
import com.enonic.cms.core.portal.PortalInstanceKey;
import com.enonic.cms.core.portal.PortalInstanceKeyResolver;
import com.enonic.cms.core.portal.httpservices.HttpServicesException;
import com.enonic.cms.core.preference.PreferenceAccessException;
import com.enonic.cms.core.preference.PreferenceEntity;
import com.enonic.cms.core.preference.PreferenceKey;
import com.enonic.cms.core.preference.PreferenceScopeKey;
import com.enonic.cms.core.preference.PreferenceScopeKeyResolver;
import com.enonic.cms.core.preference.PreferenceScopeType;
import com.enonic.cms.core.preference.PreferenceService;
import com.enonic.cms.core.security.InvalidCredentialsException;
import com.enonic.cms.core.security.PasswordGenerator;
import com.enonic.cms.core.security.PortalSecurityHolder;
import com.enonic.cms.core.security.group.AbstractMembershipsCommand;
import com.enonic.cms.core.security.group.AddMembershipsCommand;
import com.enonic.cms.core.security.group.GroupEntity;
import com.enonic.cms.core.security.group.GroupKey;
import com.enonic.cms.core.security.group.GroupSpecification;
import com.enonic.cms.core.security.group.RemoveMembershipsCommand;
import com.enonic.cms.core.security.user.MissingRequiredUserFieldException;
import com.enonic.cms.core.security.user.QualifiedUsername;
import com.enonic.cms.core.security.user.ReadOnlyUserFieldPolicyException;
import com.enonic.cms.core.security.user.StoreNewUserCommand;
import com.enonic.cms.core.security.user.UpdateUserCommand;
import com.enonic.cms.core.security.user.User;
import com.enonic.cms.core.security.user.UserEntity;
import com.enonic.cms.core.security.user.UserKey;
import com.enonic.cms.core.security.user.UserNotFoundException;
import com.enonic.cms.core.security.user.UserSpecification;
import com.enonic.cms.core.security.user.UserStorageExistingEmailException;
import com.enonic.cms.core.security.user.UserStorageInvalidArgumentException;
import com.enonic.cms.core.security.userstore.UserStoreAccessException;
import com.enonic.cms.core.security.userstore.UserStoreConnectorPolicyBrokenException;
import com.enonic.cms.core.security.userstore.UserStoreEntity;
import com.enonic.cms.core.security.userstore.UserStoreKey;
import com.enonic.cms.core.security.userstore.UserStoreNotFoundException;
import com.enonic.cms.core.security.userstore.UserStoreParser;
import com.enonic.cms.core.security.userstore.connector.UserAlreadyExistsException;
import com.enonic.cms.core.service.UserServicesService;
import com.enonic.cms.core.servlet.ServletRequestAccessor;
import com.enonic.cms.core.structure.SiteContext;
import com.enonic.cms.core.structure.SiteKey;
import com.enonic.cms.core.structure.SitePath;
import com.enonic.cms.core.user.field.UserFieldTransformer;
import com.enonic.cms.store.dao.GroupDao;
import com.enonic.cms.store.dao.UserDao;
import com.enonic.cms.store.dao.UserStoreDao;
@Component
public final class UserServicesProcessor
extends ServicesProcessorBase
{
public static final int ERR_EMAIL_ALREADY_EXISTS = 100;
public static final int ERR_UID_ALREADY_EXISTS = 101;
public static final int ERR_USER_NOT_LOGGED_IN = 102;
public static final int ERR_USER_NOT_FOUND = 103;
public static final int ERR_MISSING_UID_PASSWD = 104;
public static final int ERR_USER_PASSWD_WRONG = 106;
public static final int ERR_PASSWORD_MISMATCH = 107;
public static final int ERR_NEW_PASSWORD_INVALID = 108;
public static final int ERR_JOIN_OR_LEAVE_GROUP_FAILED = 110;
public static final int ERR_JOIN_OR_LEAVE_GROUP_NOT_ALLOWED = 111;
public static final int ERR_SET_PREFERENCES_INVALID_PARAMS = 112;
public static final int ERR_NOT_ALLOWED = 113;
public static final int ERR_USERSTORE_NOT_FOUND = 115;
private PreferenceService preferenceService;
private SendMailService sendMailService;
private final PortalInstanceKeyResolver portalInstanceKeyResolver = new PortalInstanceKeyResolver();
private LoginService loginService;
private UserDao userDao;
private GroupDao groupDao;
private UserStoreDao userStoreDao;
private LogService logService;
protected static final String JOINGROUPKEY = "joingroupkey";
protected static final String ALLGROUPKEYS = "allgroupkeys";
private static final String FORMITEM_UID = "uid";
private static final String FORMITEM_USERNAME = "username";
private static final String FORMITEM_USERSTORE = "userstore";
private static final String FORMITEM_PASSWORD = "password";
private static final String FORMITEM_DISPLAYNAME = "display_name";
private static final String FORMITEM_EMAIL = "email";
private int autoLoginTimeout;
private int loginDelay;
public UserServicesProcessor()
{
super( "user" );
}
@Autowired
public void setLoginService( LoginService loginService )
{
this.loginService = loginService;
}
@Autowired
public void setPreferenceService( PreferenceService value )
{
this.preferenceService = value;
}
@Autowired
public void setSendMailService( final SendMailService sendMailService )
{
this.sendMailService = sendMailService;
}
@Autowired
public void setLogService( LogService logService )
{
this.logService = logService;
}
@Override
protected void handlerCustom( HttpServletRequest request, HttpServletResponse response, HttpSession session, ExtendedMap formItems,
UserServicesService userServices, SiteKey siteKey, String operation )
throws VerticalUserServicesException, VerticalEngineException, IOException, ClassNotFoundException, IllegalAccessException,
InstantiationException
{
SitePath sitePath = getSitePath( request );
SiteContext siteContext = getSiteContext( sitePath.getSiteKey() );
if ( operation.equals( "logout" ) )
{
processLogout( siteContext, request, response, formItems );
}
else if ( operation.equals( "login" ) )
{
processLogin( siteContext, request, response, formItems );
}
else if ( operation.equals( "modify" ) )
{
handlerModify( request, response, formItems );
}
else if ( operation.equals( "resetpwd" ) )
{
handlerResetPassword( request, response, formItems );
}
else if ( operation.equals( "changepwd" ) )
{
handlerChangePassword( request, response, formItems );
}
else if ( operation.equals( "emailexists" ) )
{
handlerEmailExists( request, response, formItems );
}
else if ( operation.equals( "joingroup" ) )
{
handlerJoinGroup( request, response, formItems );
}
else if ( operation.equals( "leavegroup" ) )
{
handlerLeaveGroup( request, response, formItems );
}
else if ( operation.equals( "setgroups" ) )
{
handlerSetGroups( request, response, formItems );
}
else if ( operation.equals( "setpreferences" ) )
{
handlerSetPreferences( request, response, formItems, siteKey );
}
else if ( operation.equals( "deletepreferences" ) )
{
handlerRemovePreferences( request, response, formItems, siteKey );
}
}
protected void handlerEmailExists( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
throws VerticalUserServicesException, RemoteException
{
UserStoreKey userStoreKey;
String email;
try
{
userStoreKey = parseUserStoreKeyFromUidAndUserstore( formItems );
email = formItems.getString( "email", null );
Assert.isTrue( StringUtils.isNotBlank( email ) );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
return;
}
UserSpecification userSpec = new UserSpecification();
userSpec.setEmail( email );
userSpec.setUserStoreKey( userStoreKey );
List<UserEntity> usersWithEmail = userDao.findBySpecification( userSpec );
boolean exists = !usersWithEmail.isEmpty();
MultiValueMap queryParams = new MultiValueMap();
queryParams.put( "exists", String.valueOf( exists ) );
queryParams.put( "email", email );
UserStoreEntity userStore = userStoreService.getUserStore( userStoreKey );
queryParams.put( "userstore", userStore.getName() );
redirectToPage( request, response, formItems, queryParams );
}
protected void handlerSetGroups( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
throws VerticalUserServicesException, RemoteException
{
UserEntity loggedInUser = securityService.getLoggedInPortalUserAsEntity();
if ( loggedInUser == null || loggedInUser.isAnonymous() )
{
String message = "User must be logged in.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
String[] requiredParameters = new String[]{ALLGROUPKEYS};
List<String> missingParameters = findMissingRequiredParameters( requiredParameters, formItems, true );
if ( !missingParameters.isEmpty() )
{
String message = createMissingParametersMessage( "Set groups", missingParameters );
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_PARAMETERS_MISSING );
return;
}
UpdateUserCommand updateUserCommand = createUpdateUserCommandForGroupHandling( loggedInUser );
addGroupsFromSetGroupsConfig( formItems, updateUserCommand, loggedInUser );
try
{
userStoreService.updateUser( updateUserCommand );
updateUserInSession( ServletRequestAccessor.getSession() );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
return;
}
redirectToPage( request, response, formItems );
}
protected void handlerJoinGroup( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
throws VerticalUserServicesException, RemoteException
{
UserEntity user = securityService.getLoggedInPortalUserAsEntity();
if ( user == null )
{
String message = "User must be logged in.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
String[] requiredParameters = new String[]{"key"};
List<String> missingParameters = findMissingRequiredParameters( requiredParameters, formItems, true );
if ( !missingParameters.isEmpty() )
{
String message = createMissingParametersMessage( "Join group", missingParameters );
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_PARAMETERS_MISSING );
return;
}
List<GroupKey> groupKeysToAdd = getSubmittedGroupKeys( formItems, "key" );
List<GroupKey> existingKeysForUser = getExistingDirectMembershipsForUser( user );
groupKeysToAdd.removeAll( existingKeysForUser );
if ( groupKeysToAdd.size() >= 1 )
{
GroupSpecification userGroupForLoggedInUser = new GroupSpecification();
userGroupForLoggedInUser.setKey( user.getUserGroupKey() );
AddMembershipsCommand addMembershipCommand = new AddMembershipsCommand( userGroupForLoggedInUser, user.getKey() );
addMembershipCommand.setUpdateOpenGroupsOnly( true );
addMembershipCommand.setRespondWithException( true );
for ( GroupKey groupKeyToAdd : groupKeysToAdd )
{
addMembershipCommand.addGroupToAddTo( groupKeyToAdd );
}
try
{
userStoreService.addMembershipsToGroup( addMembershipCommand );
updateUserInSession( ServletRequestAccessor.getSession() );
}
catch ( UserStoreAccessException e )
{
String message = "Not allowed to add user to group: %t";
VerticalUserServicesLogger.warn( message, e );
redirectToErrorPage( request, response, ERR_JOIN_OR_LEAVE_GROUP_NOT_ALLOWED );
return;
}
catch ( RuntimeException e )
{
String message = "Failed to add user to group: %t";
VerticalUserServicesLogger.warn( message, e );
redirectToErrorPage( request, response, ERR_JOIN_OR_LEAVE_GROUP_FAILED );
return;
}
}
redirectToPage( request, response, formItems );
}
private UpdateUserCommand createUpdateUserCommandForGroupHandling( User user )
{
UserSpecification spec = new UserSpecification();
spec.setKey( user.getKey() );
spec.setDeletedStateNotDeleted();
UpdateUserCommand updateUserCommand = new UpdateUserCommand( user.getKey(), spec );
updateUserCommand.setupModifyStrategy();
updateUserCommand.setSyncMemberships( true );
updateUserCommand.setUpdateOpenGroupsOnly( true );
updateUserCommand.setAllowUpdateSelf( true );
return updateUserCommand;
}
private void addSubmittedGroups( List<GroupKey> groupKeys, AbstractMembershipsCommand userCommand )
{
for ( GroupKey newGroupKey : groupKeys )
{
final GroupEntity newGroup = groupDao.find( newGroupKey.toString() );
if ( newGroup != null && !newGroup.isRestricted() )
{
userCommand.addMembership( newGroupKey );
}
else if ( newGroup == null )
{
VerticalUserServicesLogger.warn( "Not able to join group with key: " + newGroupKey.toString() + ", not found" );
}
else
{
VerticalUserServicesLogger.warn( "Not able to join group with key: " + newGroupKey.toString() + ", not allowed" );
}
}
}
private List<GroupKey> getExistingDirectMembershipsForUser( UserEntity user )
{
ArrayList<GroupKey> existingMemberships = new ArrayList<GroupKey>();
for ( GroupEntity existingGroup : user.getDirectMemberships() )
{
existingMemberships.add( existingGroup.getGroupKey() );
}
return existingMemberships;
}
protected void addGroupsFromSetGroupsConfig( ExtendedMap formItems, UpdateUserCommand updateUserCommand, UserEntity user )
{
List<GroupKey> toBeAdded = getSubmittedGroupKeys( formItems, JOINGROUPKEY );
List<GroupKey> toBeConsidered = getSubmittedGroupKeys( formItems, ALLGROUPKEYS );
addSubmittedGroups( toBeAdded, updateUserCommand );
for ( GroupEntity existingGroup : user.getDirectMemberships() )
{
if ( !toBeConsidered.contains( existingGroup.getGroupKey() ) )
{
updateUserCommand.addMembership( existingGroup.getGroupKey() );
}
}
}
private List<GroupKey> getSubmittedGroupKeys( ExtendedMap formItems, String key )
{
List<GroupKey> groupKeys = new ArrayList<GroupKey>();
if ( formItems.getString( key, null ) == null )
{
return groupKeys;
}
String[] groupKeysAsStrings;
if ( isArrayFormItem( formItems, key ) )
{
groupKeysAsStrings = formItems.getStringArray( key );
}
else
{
groupKeysAsStrings = StringUtil.splitString( formItems.getString( key ), "," );
}
for ( String groupKeyAsString : groupKeysAsStrings )
{
groupKeys.add( new GroupKey( groupKeyAsString ) );
}
return groupKeys;
}
protected void handlerLeaveGroup( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
throws VerticalUserServicesException, RemoteException
{
UserEntity user = securityService.getLoggedInPortalUserAsEntity();
if ( user == null )
{
String message = "User must be logged in.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
String[] requiredParameters = new String[]{"key"};
List<String> missingParameters = findMissingRequiredParameters( requiredParameters, formItems, true );
if ( !missingParameters.isEmpty() )
{
String message = createMissingParametersMessage( "Leave group", missingParameters );
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_PARAMETERS_MISSING );
return;
}
List<GroupKey> submittedGroupKeysToRemove = getSubmittedGroupKeys( formItems, "key" );
List<GroupKey> existingKeysForUser = getExistingDirectMembershipsForUser( user );
submittedGroupKeysToRemove.retainAll( existingKeysForUser );
if ( submittedGroupKeysToRemove.size() >= 1 )
{
GroupSpecification userGroupForLoggedInUser = new GroupSpecification();
userGroupForLoggedInUser.setKey( user.getUserGroupKey() );
RemoveMembershipsCommand removeMembershipsCommand = new RemoveMembershipsCommand( userGroupForLoggedInUser, user.getKey() );
removeMembershipsCommand.setUpdateOpenGroupsOnly( true );
removeMembershipsCommand.setRespondWithException( true );
for ( GroupKey groupKeyToRemove : submittedGroupKeysToRemove )
{
removeMembershipsCommand.addGroupToRemoveFrom( groupKeyToRemove );
}
try
{
userStoreService.removeMembershipsFromGroup( removeMembershipsCommand );
updateUserInSession( ServletRequestAccessor.getSession() );
}
catch ( UserStoreAccessException e )
{
String message = "Not allowed to remove user from group: %t";
VerticalUserServicesLogger.warn( message, e );
redirectToErrorPage( request, response, ERR_JOIN_OR_LEAVE_GROUP_NOT_ALLOWED );
return;
}
catch ( RuntimeException e )
{
VerticalUserServicesLogger.warn( e.getMessage(), e );
redirectToErrorPage( request, response, ERR_JOIN_OR_LEAVE_GROUP_FAILED );
return;
}
}
redirectToPage( request, response, formItems );
}
protected void handlerChangePassword( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
{
delayLogin();
User loggedInUser = securityService.getLoggedInPortalUser();
String uid = parseUsername( formItems );
UserStoreKey userStoreKey;
try
{
userStoreKey = parseUserStoreKeyFromUidAndUserstore( formItems );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
return;
}
if ( loggedInUser != null && StringUtils.isBlank( uid ) )
{
uid = loggedInUser.getName();
userStoreKey = loggedInUser.getUserStoreKey();
}
try
{
if ( loggedInUser == null || loggedInUser.getName().equals( uid ) )
{
// Either the user is trying to update its own password, or the user is not
// logged in. We need to check the old password
String password = formItems.getString( FORMITEM_PASSWORD, null );
if ( StringUtils.isBlank( password ) )
{
String message = "Missing user name and/or password.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_MISSING_UID_PASSWD );
return;
}
securityService.loginPortalUser( new QualifiedUsername( userStoreKey, uid ), password );
loggedInUser = securityService.getLoggedInPortalUser();
}
String newPassword1 = formItems.getString( "newpassword1", "" );
String newPassword2 = formItems.getString( "newpassword2", "" );
if ( !newPassword1.equals( newPassword2 ) )
{
String message = "Passwords don't match.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_PASSWORD_MISMATCH );
return;
}
if ( newPassword1.length() == 0 )
{
String message = "New password is invalid.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_NEW_PASSWORD_INVALID );
return;
}
if ( loggedInUser.isEnterpriseAdmin() || loggedInUser.getName().equals( uid ) )
{
securityService.changePassword( new QualifiedUsername( userStoreKey, uid ), newPassword1 );
}
else
{
String message = "Not allowed to update user password.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_NOT_ALLOWED );
return;
}
}
catch ( InvalidCredentialsException ice )
{
String message = "User name and/or password is wrong: {0}";
VerticalUserServicesLogger.warn( message, uid, null );
redirectToErrorPage( request, response, ERR_USER_PASSWD_WRONG );
return;
}
catch ( VerticalSecurityException vue )
{
String message = "User id and/or password incorrect: %t";
VerticalUserServicesLogger.warn( message, vue );
redirectToErrorPage( request, response, ERR_USER_PASSWD_WRONG );
return;
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
return;
}
redirectToPage( request, response, formItems );
}
protected void handlerResetPassword( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
{
UserStoreKey userStoreKey;
String uid;
String email = null;
try
{
userStoreKey = parseUserStoreKeyFromUidAndUserstore( formItems );
uid = parseUsername( formItems );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
return;
}
if ( StringUtils.isBlank( uid ) )
{
email = parseEmailForResetPassword( formItems );
}
boolean neitherEmailOrUidSet = StringUtils.isBlank( uid ) && StringUtils.isBlank( email );
if ( neitherEmailOrUidSet )
{
redirectToErrorPage( request, response, ERR_USER_NOT_FOUND );
return;
}
boolean missingMailBodyOrFromEmail = !( formItems.containsKey( "mail_body" ) && formItems.containsKey( "from_email" ) );
if ( missingMailBodyOrFromEmail )
{
VerticalUserServicesLogger.warn( "Missing either 'mail_body' or 'from_email' parameter." );
redirectToErrorPage( request, response, ERR_PARAMETERS_MISSING );
return;
}
QualifiedUsername qualifiedUsername;
if ( StringUtils.isNotBlank( email ) )
{
UserSpecification userSpecification = new UserSpecification();
userSpecification.setUserStoreKey( userStoreKey );
userSpecification.setEmail( email );
userSpecification.setDeletedStateNotDeleted();
UserEntity userEntity = userDao.findSingleBySpecification( userSpecification );
if ( userEntity == null )
{
redirectToErrorPage( request, response, ERR_USER_NOT_FOUND );
return;
}
qualifiedUsername = new QualifiedUsername( userStoreKey, userEntity.getName() );
}
else
{
qualifiedUsername = new QualifiedUsername( userStoreKey, uid );
}
final String password = PasswordGenerator.generateNewPassword();
try
{
securityService.changePassword( qualifiedUsername, password );
}
catch ( IllegalArgumentException e )
{
if ( e.getMessage() != null && e.getMessage().startsWith( "Could not find user" ) )
{
String message = "User not found: " + uid;
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_USER_NOT_FOUND );
return;
}
else
{
String message = "Not allowed to change password for user: " + uid;
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_NOT_ALLOWED );
return;
}
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
return;
}
final MessageSettings messageSettings = new MessageSettings();
messageSettings.setFromName( formItems.getString( "from_name", null ) );
messageSettings.setFromMail( formItems.getString( "from_email", null ) );
messageSettings.setSubject( formItems.getString( "mail_subject", null ) );
String mailBody = formItems.getString( "mail_body", "" );
mailBody = fixLinebreaks( mailBody );
messageSettings.setBody( mailBody );
sendMailService.sendChangePasswordMail( qualifiedUsername, password, messageSettings );
redirectToPage( request, response, formItems );
}
private String fixLinebreaks( String mailBody )
{
mailBody = mailBody.replaceAll( "\\\\n", "\n" );
return mailBody;
}
private String parseEmailForResetPassword( ExtendedMap formItems )
{
String email = parseEmail( formItems );
if ( StringUtils.isBlank( email ) )
{
email = formItems.getString( "id", null );
}
return email;
}
protected void handlerModify( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
{
UserEntity loggedInUser = securityService.getLoggedInPortalUserAsEntity();
if ( loggedInUser == null || loggedInUser.isAnonymous() )
{
String msg = "User not logged in.";
VerticalUserServicesLogger.warn( msg );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
try
{
final UserSpecification updateUserSpecification = createUserSpecificationForUpdate( formItems );
final UpdateUserCommand updateUserCommand = new UpdateUserCommand( loggedInUser.getKey(), updateUserSpecification );
final String email = parseEmail( formItems );
if ( email != null )
{
updateUserCommand.setEmail( email );
}
final String displayName = parseDisplayName( formItems );
if ( displayName != null )
{
updateUserCommand.setDisplayName( displayName );
}
updateUserCommand.setUserFields( new UserFieldTransformer().toUserFields( formItems ) );
updateUserCommand.setAllowUpdateSelf( true );
updateUserCommand.setUpdateOpenGroupsOnly( true );
updateUserCommand.setupModifyStrategy();
updateGroupsInUpdateCommand( formItems, loggedInUser, updateUserCommand );
userStoreService.updateUser( updateUserCommand );
redirectToPage( request, response, formItems );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
}
}
private void handleExceptions( Exception e, HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
{
if ( e instanceof UserAlreadyExistsException )
{
String msg = "username already exists: {0}";
String userId =
formItems.containsKey( FORMITEM_UID ) ? formItems.getString( FORMITEM_UID ) : formItems.getString( FORMITEM_USERNAME, "" );
VerticalUserServicesLogger.warn( msg, userId, null );
redirectToErrorPage( request, response, ERR_UID_ALREADY_EXISTS );
}
else if ( e instanceof IllegalArgumentException )
{
String message = StringUtils.isNotBlank( e.getMessage() ) ? e.getMessage() : "Illegal arguments: %t";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_PARAMETERS_INVALID );
}
else if ( e instanceof MissingRequiredUserFieldException )
{
VerticalUserServicesLogger.warn( e.getMessage() );
redirectToErrorPage( request, response, ERR_PARAMETERS_MISSING );
}
else if ( e instanceof ReadOnlyUserFieldPolicyException )
{
VerticalUserServicesLogger.warn( e.getMessage() );
redirectToErrorPage( request, response, ERR_PARAMETERS_INVALID );
}
else if ( e instanceof UserStorageExistingEmailException )
{
VerticalUserServicesLogger.warn( e.getMessage() );
redirectToErrorPage( request, response, ERR_EMAIL_ALREADY_EXISTS );
}
else if ( e instanceof UserNotFoundException )
{
VerticalUserServicesLogger.warn( e.getMessage() );
redirectToErrorPage( request, response, ERR_USER_NOT_FOUND );
}
else if ( e instanceof UserStorageInvalidArgumentException )
{
VerticalUserServicesLogger.warn( e.getMessage() );
redirectToErrorPage( request, response, ERR_PARAMETERS_INVALID );
}
else if ( e instanceof UserStoreAccessException )
{
VerticalUserServicesLogger.warn( e.getMessage() );
redirectToErrorPage( request, response, ERR_NOT_ALLOWED );
}
else if ( e instanceof UnsupportedEncodingException )
{
String message = "Un-supported encoding: %t";
VerticalUserServicesLogger.error( message, e );
redirectToErrorPage( request, response, ERR_EMAIL_SEND_FAILED );
}
else if ( e instanceof MessagingException )
{
String message = "Failed to send order received mail: %t";
VerticalUserServicesLogger.error( message, e );
redirectToErrorPage( request, response, ERR_EMAIL_SEND_FAILED );
}
else if ( e instanceof UserStoreNotFoundException )
{
String message = "Userstore not found";
VerticalUserServicesLogger.warn( message, e );
redirectToErrorPage( request, response, ERR_USERSTORE_NOT_FOUND );
}
else if ( e instanceof UserStoreConnectorPolicyBrokenException )
{
String msg = e.getMessage();
VerticalUserServicesLogger.warn( msg );
redirectToErrorPage( request, response, ERR_SECURITY_EXCEPTION );
}
else
{
String message = e.getMessage() == null ? "Error" : e.getMessage();
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_OPERATION_BACKEND );
}
}
private void updateGroupsInUpdateCommand( ExtendedMap formItems, UserEntity user, UpdateUserCommand updateUserCommand )
{
if ( formItems.containsKey( JOINGROUPKEY ) || formItems.containsKey( ALLGROUPKEYS ) )
{
updateUserCommand.setSyncMemberships( true );
addGroupsFromSetGroupsConfig( formItems, updateUserCommand, user );
}
}
@Override
protected void handlerCreate( HttpServletRequest request, HttpServletResponse response, HttpSession session, ExtendedMap formItems,
UserServicesService userServices, SiteKey siteKey )
throws VerticalUserServicesException, VerticalCreateException, VerticalSecurityException, RemoteException
{
String[] requiredParameters = new String[]{"email"};
List<String> missingParameters = findMissingRequiredParameters( requiredParameters, formItems, false );
if ( !missingParameters.isEmpty() )
{
String message = createMissingParametersMessage( "Create User", missingParameters );
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_PARAMETERS_MISSING );
return;
}
try
{
StoreNewUserCommand storeNewUserCommand = new StoreNewUserCommand();
final String username = formItems.getString( FORMITEM_USERNAME, null );
storeNewUserCommand.setUsername( username );
final UserStoreKey userStoreKey = parseUserStoreKeyFromUserstore( formItems );
storeNewUserCommand.setUserStoreKey( userStoreKey );
storeNewUserCommand.setEmail( parseEmail( formItems ) );
storeNewUserCommand.setDisplayName( parseDisplayName( formItems ) );
storeNewUserCommand.setPassword( parsePassword( formItems ) );
storeNewUserCommand.setStorer( securityService.getLoggedInPortalUser().getKey() );
final UserFieldTransformer fieldTransformer = new UserFieldTransformer();
final UserFields userFields = fieldTransformer.toUserFields( formItems );
storeNewUserCommand.setUserFields( userFields );
storeNewUserCommand.setAllowAnyUserAccess( true );
List<GroupKey> submittedGroups = getSubmittedGroupKeys( formItems, JOINGROUPKEY );
if ( !submittedGroups.isEmpty() )
{
addSubmittedGroups( submittedGroups, storeNewUserCommand );
}
UserKey userKey = userStoreService.storeNewUser( storeNewUserCommand );
sendCreatedNewUserMail( formItems, userKey, storeNewUserCommand );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
return;
}
updateUserInSession( session );
redirectToPage( request, response, formItems );
}
private void sendCreatedNewUserMail( ExtendedMap formItems, UserKey userKey, StoreNewUserCommand command )
throws IOException, MessagingException
{
UserSpecification userSpec = new UserSpecification();
userSpec.setKey( userKey );
//userSpec.setUserStoreKey( command.getUserStoreKey() );
userSpec.setDeletedStateNotDeleted();
UserEntity newUser = userDao.findSingleBySpecification( userSpec );
sendMailToNewUser( formItems, newUser, command.getPassword() );
sendMailToAdmin( formItems, newUser );
}
private void sendMailToAdmin( ExtendedMap formItems, UserEntity newUser )
throws IOException, MessagingException
{
String[] adminEmailRequiredParameters = {"admin_email", "admin_mail_body"};
if ( formItems.containsKeys( adminEmailRequiredParameters, false ) )
{
formItems.put( FORMITEM_UID, newUser.getName() );
formItems.put( FORMITEM_DISPLAYNAME, newUser.getDisplayName() );
formItems.put( FORMITEM_USERSTORE, newUser.getUserStore().getName() );
final SimpleMailTemplate adminMail = new SimpleMailTemplate();
adminMail.addRecipient( formItems.getString( "admin_name", "" ), formItems.getString( "admin_email" ),
MailRecipientType.TO_RECIPIENT );
adminMail.setFrom( formItems.getString( "from_name", "" ), formItems.getString( "from_email", "" ) );
String mailSubject = formItems.getString( "admin_mail_subject", "" );
mailSubject = replaceKeys( formItems, mailSubject, new String[]{FORMITEM_PASSWORD} );
mailSubject = removeTokens( mailSubject );
adminMail.setSubject( mailSubject );
String mailBody = formItems.getString( "admin_mail_body" );
mailBody = replaceKeys( formItems, mailBody, new String[]{FORMITEM_PASSWORD} );
mailBody = removeTokens( mailBody );
adminMail.setMessage( mailBody );
sendMailService.sendMail( adminMail );
}
}
private void sendMailToNewUser( ExtendedMap formItems, UserEntity newUser, String password )
throws IOException, MessagingException
{
String[] sendEmailRequiredParameters = {"user_mail_body", "from_email", "email"};
if ( formItems.containsKeys( sendEmailRequiredParameters, false ) )
{
formItems.put( FORMITEM_USERNAME, newUser.getName() );
formItems.put( FORMITEM_PASSWORD, password );
formItems.put( FORMITEM_DISPLAYNAME, newUser.getDisplayName() );
formItems.put( FORMITEM_USERSTORE, newUser.getUserStore().getName() );
final SimpleMailTemplate userMail = new SimpleMailTemplate();
userMail.addRecipient( newUser.getDisplayName(), formItems.getString( "email" ), MailRecipientType.TO_RECIPIENT );
userMail.setFrom( formItems.getString( "from_name", "" ), formItems.getString( "from_email" ) );
String mailSubject = formItems.getString( "user_mail_subject", "" );
mailSubject = replaceKeys( formItems, mailSubject, new String[]{FORMITEM_PASSWORD} );
mailSubject = removeTokens( mailSubject );
userMail.setSubject( mailSubject );
String mailBody = formItems.getString( "user_mail_body" );
mailBody = replaceKeys( formItems, mailBody, null );
mailBody = removeTokens( mailBody );
userMail.setMessage( mailBody );
sendMailService.sendMail( userMail );
}
}
private String parseDisplayName( ExtendedMap formItems )
{
return formItems.containsKey( FORMITEM_DISPLAYNAME ) ? formItems.getString( FORMITEM_DISPLAYNAME ) : null;
}
private String parseEmail( ExtendedMap formItems )
{
return formItems.containsKey( "email" ) ? formItems.getString( "email" ) : null;
}
private String parsePassword( ExtendedMap formItems )
{
String password;
if ( formItems.containsKey( FORMITEM_PASSWORD ) )
{
password = formItems.getString( FORMITEM_PASSWORD );
if ( StringUtils.isNotBlank( password ) )
{
return password;
}
}
return PasswordGenerator.generateNewPassword();
}
@Override
protected void handlerUpdate( HttpServletRequest request, HttpServletResponse response, HttpSession session, ExtendedMap formItems,
UserServicesService userServices, SiteKey siteKey )
{
UserEntity loggedInUser = securityService.getLoggedInPortalUserAsEntity();
if ( loggedInUser == null || loggedInUser.isAnonymous() )
{
String msg = "User not logged in.";
VerticalUserServicesLogger.warn( msg );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
try
{
final UserSpecification updateUserSpecification = createUserSpecificationForUpdate( formItems );
final UpdateUserCommand updateUserCommand = new UpdateUserCommand( loggedInUser.getKey(), updateUserSpecification );
updateUserCommand.setEmail( parseEmail( formItems ) );
updateUserCommand.setDisplayName( parseDisplayName( formItems ) );
final UserFields userFields = new UserFieldTransformer().toUserFields( formItems );
updateUserCommand.setUserFields( userFields );
updateUserCommand.setAllowUpdateSelf( true );
updateUserCommand.setUpdateOpenGroupsOnly( true );
updateUserCommand.setupUpdateStrategy();
updateGroupsInUpdateCommand( formItems, loggedInUser, updateUserCommand );
userStoreService.updateUser( updateUserCommand );
redirectToPage( request, response, formItems );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
}
}
private UserSpecification createUserSpecificationForUpdate( final ExtendedMap formItems )
{
final UserSpecification spec = new UserSpecification();
spec.setDeletedStateNotDeleted();
String username = parseUsername( formItems );
if ( StringUtils.isNotBlank( username ) )
{
spec.setName( username );
spec.setUserStoreKey( parseUserStoreKeyFromUidAndUserstore( formItems ) );
}
else
{
User loggedInUser = securityService.getLoggedInPortalUser();
spec.setKey( loggedInUser.getKey() );
spec.setName( loggedInUser.getName() );
}
return spec;
}
private void processLogin( SiteContext siteContext, HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
throws VerticalUserServicesException, RemoteException
{
String username = null;
delayLogin();
try
{
UserStoreKey userStoreKey = parseUserStoreKeyFromUidAndUserstore( formItems );
username = parseUsername( formItems );
if ( StringUtils.isBlank( username ) && formItems.containsKey( FORMITEM_EMAIL ) )
{
UserEntity foundUser = getUserFromEmail( formItems, userStoreKey );
if ( foundUser == null )
{
throw new InvalidCredentialsException( "Not able to log in user: " + formItems.getString( FORMITEM_EMAIL ) );
}
username = foundUser.getName();
}
String password = formItems.getString( FORMITEM_PASSWORD, null );
if ( StringUtils.isBlank( username ) || StringUtils.isBlank( password ) )
{
String message = "Missing user name and/or password.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_MISSING_UID_PASSWD );
return;
}
securityService.loginPortalUser( new QualifiedUsername( userStoreKey, username ), password );
User user = securityService.getLoggedInPortalUser();
if ( user == null )
{
throw new InvalidCredentialsException( "Not able to log in user: " + username );
}
if ( siteContext.isAuthenticationLoggingEnabled() )
{
logLogin( siteContext, user, request.getRemoteAddr() );
}
ServletRequestAccessor.getSession().setAttribute( "vertical_uid", username );
PortalSecurityHolder.setLoggedInUser( user.getKey() );
boolean rememberUser = parseRememberUser( formItems );
String deploymentPath = DeploymentPathResolver.getSiteDeploymentPath( request );
String cookieName = "guid-" + siteContext.getSiteKey();
if ( rememberUser )
{
applyRememberUser( siteContext, response, formItems, user, deploymentPath, cookieName );
}
else
{
removeGuidCookie( response, deploymentPath, siteContext );
}
redirectToPage( request, response, formItems );
}
catch ( InvalidCredentialsException ice )
{
if ( username == null )
{
username = formItems.getString( FORMITEM_EMAIL, null );
}
logLoginFailed( siteContext, username, request.getRemoteAddr() );
String message = "User name and/or password is wrong: {0}";
VerticalUserServicesLogger.warn( message, username, null );
redirectToErrorPage( request, response, ERR_USER_PASSWD_WRONG );
}
catch ( VerticalSecurityException vse )
{
if ( username == null )
{
username = formItems.getString( FORMITEM_EMAIL, null );
}
logLoginFailed( siteContext, username, request.getRemoteAddr() );
String message = "No rights to handle request: " + vse.getMessage();
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_SECURITY_EXCEPTION );
}
catch ( Exception e )
{
handleExceptions( e, request, response, formItems );
}
}
private void delayLogin()
{
try
{
Thread.sleep( this.loginDelay );
}
catch ( InterruptedException e )
{
// Do nothing
}
}
private void applyRememberUser( SiteContext siteContext, HttpServletResponse response, ExtendedMap formItems, User user,
String deploymentPath, String cookieName )
{
boolean resetGuid = false;
if ( formItems.getString( "resetguid", "false" ).equals( "true" ) || formItems.getString( "resetguid", "off" ).equals( "on" ) )
{
resetGuid = true;
}
String guid = loginService.rememberLogin( user.getKey(), siteContext.getSiteKey(), resetGuid );
long maxAge = 60L * 60 * 24 * autoLoginTimeout;
if ( maxAge > Integer.MAX_VALUE )
{
maxAge = Integer.MAX_VALUE;
}
CookieUtil.setCookie( response, cookieName, guid, (int) maxAge, deploymentPath );
}
private boolean parseRememberUser( ExtendedMap formItems )
{
boolean rememberUser = false;
if ( formItems.getString( "rememberme", "false" ).equals( "true" ) || formItems.getString( "rememberme", "off" ).equals( "on" ) )
{
rememberUser = true;
}
return rememberUser;
}
private UserEntity getUserFromEmail( ExtendedMap formItems, UserStoreKey userStoreKey )
{
String email = formItems.getString( FORMITEM_EMAIL, null );
if ( StringUtils.isBlank( email ) )
{
return null;
}
UserSpecification userSpecification = new UserSpecification();
userSpecification.setEmail( email );
userSpecification.setUserStoreKey( userStoreKey );
userSpecification.setDeletedStateNotDeleted();
return userDao.findSingleBySpecification( userSpecification );
}
private String parseUsername( ExtendedMap formItems )
{
String submittedUid = formItems.getString( FORMITEM_UID, null );
if ( StringUtils.isNotBlank( submittedUid ) )
{
QualifiedUsername qualifiedUserName = QualifiedUsername.parse( submittedUid );
if ( qualifiedUserName != null )
{
return qualifiedUserName.getUsername();
}
}
return null;
}
private UserStoreKey parseUserStoreKeyFromUidAndUserstore( ExtendedMap formItems )
{
return doParseUserStoreKey( formItems, true );
}
private UserStoreKey parseUserStoreKeyFromUserstore( ExtendedMap formItems )
{
return doParseUserStoreKey( formItems, false );
}
private UserStoreKey doParseUserStoreKey( ExtendedMap formItems, boolean parseUserstoreFromItem )
{
if ( formItems.containsKey( FORMITEM_UID ) && parseUserstoreFromItem )
{
QualifiedUsername qualifiedUsername = QualifiedUsername.parse( formItems.getString( FORMITEM_UID ) );
if ( qualifiedUsername.hasUserStoreNameSet() )
{
UserStoreEntity userStoreEntity =
new UserStoreParser( userStoreDao ).parseUserStore( qualifiedUsername.getUserStoreName() );
if ( userStoreEntity != null )
{
return userStoreEntity.getKey();
}
}
}
if ( formItems.containsKey( FORMITEM_USERSTORE ) && StringUtils.isNotBlank( formItems.getString( FORMITEM_USERSTORE ) ) )
{
UserStoreEntity userStoreEntity =
new UserStoreParser( userStoreDao ).parseUserStore( formItems.getString( FORMITEM_USERSTORE ) );
if ( userStoreEntity != null )
{
return userStoreEntity.getKey();
}
}
return userStoreService.getDefaultUserStore().getKey();
}
private void removeGuidCookie( HttpServletResponse response, String deploymentPath, SiteContext siteContext )
{
String cookieName = "guid-" + siteContext.getSiteKey();
CookieUtil.setCookie( response, cookieName, null, 0, deploymentPath );
}
private void logLogin( final SiteContext site, final User user, final String remoteIp )
{
final StoreNewLogEntryCommand command = new StoreNewLogEntryCommand();
command.setType( LogType.LOGIN );
command.setInetAddress( remoteIp );
command.setTitle( user.getDisplayName() + " (" + user.getName() + ")" );
command.setUser( user.getKey() );
command.setSite( this.siteDao.findByKey( site.getSiteKey() ) );
this.logService.storeNew( command );
}
private void logLogout( final SiteContext site, final User user, final String remoteIp )
{
final StoreNewLogEntryCommand command = new StoreNewLogEntryCommand();
command.setType( LogType.LOGOUT );
command.setInetAddress( remoteIp );
command.setTitle( user.getDisplayName() + " (" + user.getName() + ")" );
command.setUser( user.getKey() );
command.setSite( this.siteDao.findByKey( site.getSiteKey() ) );
this.logService.storeNew( command );
}
private void logLoginFailed( final SiteContext site, final String uid, final String remoteIp )
{
final StoreNewLogEntryCommand command = new StoreNewLogEntryCommand();
command.setType( LogType.LOGIN_FAILED );
command.setInetAddress( remoteIp );
command.setTitle( uid );
command.setUser( this.securityService.getAnonymousUserKey() );
command.setSite( this.siteDao.findByKey( site.getSiteKey() ) );
this.logService.storeNew( command );
}
private void processLogout( SiteContext siteContext, HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems )
throws VerticalUserServicesException, RemoteException
{
final HttpSession session = ServletRequestAccessor.getSession( false );
if ( session != null )
{
// Create log entry:
User user = securityService.getLoggedInPortalUser();
if ( user != null && !user.isAnonymous() )
{
if ( siteContext.isAuthenticationLoggingEnabled() )
{
logLogout( siteContext, user, request.getRemoteAddr() );
}
}
else
{
String message = "User is not logged in.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
// Remove GUID cookie if present
String cookieName = "guid-" + siteContext.getSiteKey();
Cookie cookie = CookieUtil.getCookie( request, cookieName );
if ( cookie != null )
{
cookie.setValue( null );
response.addCookie( cookie );
}
removeGuidCookie( response, DeploymentPathResolver.getSiteDeploymentPath( request ), siteContext );
this.securityService.logoutPortalUser();
this.loginService.removeRememberedLogin( user.getKey() );
redirectToPage( request, response, formItems );
}
}
private void updateUserInSession( HttpSession session )
throws RemoteException
{
// It is only needed to update logged in user in session when we store the whole user object in the session
// this we do not do anymore...
// Still, we leave this method here as a reminder in case we change the strategy around this.
/*
UserEntity user = securityService.getUser();
if ( user != null )
{
session.setAttribute( "vertical_user", user.getKey() );
}
*/
}
private void handlerSetPreferences( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems, SiteKey siteKey )
{
User olduser = securityService.getLoggedInPortalUser();
if ( olduser == null )
{
String message = "User is not logged in.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
PortalInstanceKey instanceKey =
portalInstanceKeyResolver.resolvePortalInstanceKey( formItems.getString( "_instanceKey", null ), siteKey );
instanceKey.setSite( siteKey );
UserEntity user = securityService.getUser( olduser.getKey() );
String defaultScope = getDefaultScope( instanceKey );
for ( Object keyObj : formItems.keySet() )
{
String key = (String) keyObj;
if ( key.startsWith( "_" ) )
{
// System parameters
continue;
}
String value = formItems.getString( key );
try
{
PreferenceKey preferenceKey = resolvePreferenceKey( user.getKey(), instanceKey, key, defaultScope );
if ( preferenceKey != null )
{
PreferenceEntity preference = new PreferenceEntity();
preference.setKey( preferenceKey );
preference.setValue( value );
preferenceService.setPreference( preference );
}
}
catch ( IllegalArgumentException iae )
{
String message = "Illegal arguments to setPreferences: " + iae.getMessage();
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_SET_PREFERENCES_INVALID_PARAMS );
return;
}
catch ( PreferenceAccessException e )
{
String message = e.getMessage();
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_NOT_ALLOWED );
return;
}
}
redirectToPage( request, response, formItems );
}
private String getDefaultScope( PortalInstanceKey instanceKey )
{
if ( instanceKey.isWindow() )
{
return PreferenceScopeType.WINDOW.name();
}
if ( instanceKey.isMenuItem() )
{
return PreferenceScopeType.PAGE.name();
}
if ( instanceKey.getSiteKey() != null )
{
return PreferenceScopeType.SITE.name();
}
return "";
}
private void handlerRemovePreferences( HttpServletRequest request, HttpServletResponse response, ExtendedMap formItems,
SiteKey siteKey )
{
User olduser = securityService.getLoggedInPortalUser();
if ( olduser == null )
{
String message = "User is not logged in.";
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_USER_NOT_LOGGED_IN );
return;
}
PortalInstanceKey instanceKey =
portalInstanceKeyResolver.resolvePortalInstanceKey( formItems.getString( "_instanceKey", null ), siteKey );
instanceKey.setSite( siteKey );
UserEntity user = securityService.getUser( olduser.getKey() );
String defaultScope = getDefaultScope( instanceKey );
String[] preferenceKeys = formItems.getStringArray( "preferenceKey" );
for ( String preferenceKeyStr : preferenceKeys )
{
try
{
PreferenceKey preferenceKey = resolvePreferenceKey( user.getKey(), instanceKey, preferenceKeyStr, defaultScope );
if ( preferenceKey != null )
{
PreferenceEntity preferenceEntity = preferenceService.getPreference( preferenceKey );
preferenceService.removePreference( preferenceEntity );
}
}
catch ( IllegalArgumentException iae )
{
String message = "Illegal arguments to removePreferences: " + iae.getMessage();
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_SET_PREFERENCES_INVALID_PARAMS );
return;
}
catch ( PreferenceAccessException e )
{
String message = e.getMessage();
VerticalUserServicesLogger.warn( message );
redirectToErrorPage( request, response, ERR_NOT_ALLOWED );
return;
}
}
redirectToPage( request, response, formItems );
}
private PreferenceKey resolvePreferenceKey( UserKey userKey, PortalInstanceKey instanceKey, String key, String defaultScope )
{
if ( key == null || key.length() == 0 )
{
// return null;
throw new IllegalArgumentException( "Preference cannot be null or empty" );
}
String preferenceKeyStr;
String scopeName;
if ( key.contains( "$" ) )
{
scopeName = key.substring( 0, key.indexOf( "$" ) );
preferenceKeyStr = key.substring( key.indexOf( "$" ) + 1 );
}
else
{
preferenceKeyStr = key;
scopeName = defaultScope;
}
PreferenceScopeType scopeType = PreferenceScopeType.parse( scopeName );
if ( scopeType == null )
{
throw new IllegalArgumentException( "Scope " + scopeName + " is not valid" );
}
PreferenceScopeKey scopeKey = resolveScopeKey( instanceKey, scopeType );
return new PreferenceKey( userKey, scopeType, scopeKey, preferenceKeyStr );
}
private PreferenceScopeKey resolveScopeKey( PortalInstanceKey instanceKey, PreferenceScopeType scopeType )
{
boolean submitFromPageTemplate = instanceKey.getPortletKey() == null;
if ( submitFromPageTemplate && ( scopeType == PreferenceScopeType.WINDOW || scopeType == PreferenceScopeType.PORTLET ) )
{
throw new IllegalArgumentException( "Scope " + scopeType.getName() + " can only be used from a portlet" );
}
return PreferenceScopeKeyResolver.resolve( scopeType, instanceKey, instanceKey.getSiteKey() );
}
@Autowired
public void setUserDao( final UserDao userDao )
{
this.userDao = userDao;
}
@Autowired
public void setGroupDao( final GroupDao groupDao )
{
this.groupDao = groupDao;
}
@Autowired
public void setUserStoreDao( final UserStoreDao userStoreDao )
{
this.userStoreDao = userStoreDao;
}
private static String replaceKeys( ExtendedMap formItems, String inText, String[] excludeKeys )
{
String outText = inText;
for ( Object o : formItems.keySet() )
{
String key = (String) o;
Pattern p = Pattern.compile( ".*%" + key + "%.*", Pattern.DOTALL );
Matcher m = p.matcher( outText );
if ( ( excludeKeys == null || !ArrayUtil.arrayContains( key, excludeKeys ) ) && m.matches() && formItems.containsKey( key ) )
{
String regexp = "%" + key + "%";
outText = outText.replaceAll( regexp, formItems.getString( key, "" ) );
}
}
return outText;
}
private static String removeTokens( String inText )
{
return inText.replaceAll( "%[^%]+%", "" );
}
@Value("${com.enonic.vertical.presentation.autologinTimeout}")
public void setAutoLoginTimeout( final int autoLoginTimeout )
{
this.autoLoginTimeout = autoLoginTimeout;
}
@Value("${cms.security.login.delay}")
public void setLoginDelay( final int loginDelay )
{
this.loginDelay = loginDelay;
}
@Override
public Integer httpResponseCodeTranslator( final Integer[] errorCodes )
{
if ( errorCodes.length != 1 )
{
throw new HttpServicesException( ERR_OPERATION_BACKEND );
}
Integer errorCode = errorCodes[0];
switch ( errorCode )
{
case ERR_EMAIL_ALREADY_EXISTS:
case ERR_UID_ALREADY_EXISTS:
case ERR_USER_NOT_FOUND:
case ERR_MISSING_UID_PASSWD:
case ERR_PASSWORD_MISMATCH:
case ERR_NEW_PASSWORD_INVALID:
case ERR_JOIN_OR_LEAVE_GROUP_FAILED:
case ERR_SET_PREFERENCES_INVALID_PARAMS:
case ERR_USERSTORE_NOT_FOUND:
return HTTP_STATUS_BAD_REQUEST;
case ERR_USER_NOT_LOGGED_IN:
case ERR_USER_PASSWD_WRONG:
return HTTP_STATUS_UNAUTHORIZED;
case ERR_JOIN_OR_LEAVE_GROUP_NOT_ALLOWED:
return HTTP_STATUS_FORBIDDEN;
case ERR_NOT_ALLOWED:
if ( securityService.getLoggedInPortalUserAsEntity().isAnonymous() )
{
return HTTP_STATUS_UNAUTHORIZED;
}
else
{
return HTTP_STATUS_FORBIDDEN;
}
default:
return super.httpResponseCodeTranslator( errorCodes );
}
}
}