1 package org.codehaus.plexus.redback.struts2.action.admin;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.commons.lang.StringEscapeUtils;
23 import org.codehaus.plexus.redback.policy.PasswordEncoder;
24 import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
25 import org.codehaus.plexus.redback.rbac.RBACManager;
26 import org.codehaus.plexus.redback.rbac.RbacManagerException;
27 import org.codehaus.plexus.redback.rbac.Resource;
28 import org.codehaus.plexus.redback.rbac.Role;
29 import org.codehaus.plexus.redback.struts2.action.AuditEvent;
30 import org.codehaus.plexus.redback.struts2.action.CancellableAction;
31 import org.codehaus.plexus.redback.system.DefaultSecuritySession;
32 import org.codehaus.plexus.redback.system.SecuritySession;
33 import org.codehaus.plexus.redback.system.SecuritySystemConstants;
34 import org.codehaus.plexus.redback.users.User;
35 import org.codehaus.plexus.redback.users.UserManager;
36 import org.codehaus.plexus.redback.users.UserNotFoundException;
37 import org.codehaus.plexus.util.StringUtils;
38 import org.codehaus.redback.integration.interceptor.SecureActionBundle;
39 import org.codehaus.redback.integration.interceptor.SecureActionException;
40 import org.codehaus.redback.integration.model.AdminEditUserCredentials;
41 import org.codehaus.redback.integration.role.RoleConstants;
42 import org.springframework.context.annotation.Scope;
43 import org.springframework.stereotype.Controller;
45 import javax.inject.Inject;
46 import javax.inject.Named;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collection;
50 import java.util.Collections;
51 import java.util.List;
56 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
59 @Controller( "redback-admin-user-edit" )
61 public class UserEditAction
62 extends AbstractAdminUserCredentialsAction
63 implements CancellableAction
69 @Named( value = "rBACManager#cached" )
70 private RBACManager rbacManager;
73 * A List of {@link org.codehaus.plexus.redback.rbac.Role} objects.
75 private List<Role> effectivelyAssignedRoles;
77 // ------------------------------------------------------------------
79 // ------------------------------------------------------------------
81 private AdminEditUserCredentials user;
83 private String updateButton;
85 private boolean emailValidationRequired;
87 private boolean hasHiddenRoles;
89 private String oldPassword;
91 private String userAdminPassword;
95 public static String CONFIRM = "confirm";
97 public static String CONFIRM_ERROR = "confirmError";
99 // ------------------------------------------------------------------
100 // Action Entry Points - (aka Names)
101 // ------------------------------------------------------------------
107 emailValidationRequired = securitySystem.getPolicy().getUserValidationSettings().isEmailValidationRequired();
109 if ( getUsername() == null )
111 addActionError( getText( "cannot.edit.user.null.username" ) );
115 if ( StringUtils.isEmpty( getUsername() ) )
117 addActionError( getText( "cannot.edit.user.empty.username" ) );
121 UserManager manager = super.securitySystem.getUserManager();
123 String escapedUsername = StringEscapeUtils.escapeXml( getUsername() );
125 if ( !manager.userExists( escapedUsername ) )
127 // Means that the role name doesn't exist.
128 // We need to fail fast and return to the previous page.
129 addActionError( getText( "user.does.not.exist", Collections.singletonList( (Object) escapedUsername ) ) );
135 User u = manager.findUser( escapedUsername );
139 addActionError( getText( "cannot.operate.on.null.user" ) );
143 user = new AdminEditUserCredentials( u );
145 // require user admin to provide his/her password if editing account of others
146 if ( getUsername().equals( getCurrentUser() ) )
153 String principal = u.getPrincipal().toString();
154 List<Role> roles = filterAssignableRoles( rbacManager.getEffectivelyAssignedRoles( principal ) );
155 effectivelyAssignedRoles = filterRolesForCurrentUserAccess( roles );
156 hasHiddenRoles = ( roles.size() > effectivelyAssignedRoles.size() );
158 catch ( RbacManagerException rme )
160 // ignore, this can happen when the user has no roles assigned
163 catch ( UserNotFoundException e )
165 addActionError( getText( "cannot.get.user", Arrays.asList( (Object) getUsername(), e.getMessage() ) ) );
172 private List<Role> filterAssignableRoles( Collection<Role> roles )
174 List<Role> assignableRoles = new ArrayList<Role>( roles.size() );
175 for ( Role r : roles )
177 if ( r.isAssignable() )
179 assignableRoles.add( r );
182 return assignableRoles;
185 public String submit()
187 if ( getUsername() == null )
189 addActionError( getText( "cannot.edit.user.null.username" ) );
193 if ( StringUtils.isEmpty( getUsername() ) )
195 addActionError( getText( "cannot.edit.user.empty.username" ) );
201 addActionError( getText( "cannot.edit.user.null.credentials" ) );
207 validateCredentialsLoose();
209 // if form errors, return with them before continuing
210 if ( hasActionErrors() || hasFieldErrors() )
215 if ( !getUsername().equals( getCurrentUser() ) )
225 // confirm user admin's password before allowing to proceed with the operation
226 public String confirmAdminPassword()
228 UserManager manager = super.securitySystem.getUserManager();
230 if ( StringUtils.isEmpty( userAdminPassword ) )
232 addActionError( getText( "user.admin.password.required" ) );
233 return CONFIRM_ERROR;
238 User currentUser = manager.findUser( getCurrentUser() );
240 // check if user admin provided correct password!
241 PasswordEncoder encoder = securitySystem.getPolicy().getPasswordEncoder();
242 if ( !encoder.isPasswordValid( currentUser.getEncodedPassword(), userAdminPassword ) )
244 addActionError( getText( "user.admin.password.does.not.match.existing" ) );
245 return CONFIRM_ERROR;
248 catch ( UserNotFoundException e )
250 addActionError( getText( "cannot.find.user", Arrays.asList( (Object) getCurrentUser(), e.getMessage() ) ) );
251 return CONFIRM_ERROR;
254 return save( false );
257 public String cancel()
262 private String save( boolean validateOldPassword )
264 UserManager manager = super.securitySystem.getUserManager();
266 if ( !manager.userExists( getUsername() ) )
268 // Means that the role name doesn't exist.
269 // We need to fail fast and return to the previous page.
270 addActionError( getText( "user.does.not.exist", Collections.singletonList( (Object) getUsername() ) ) );
276 User u = manager.findUser( getUsername() );
279 addActionError( getText( "cannot.operate.on.null.user" ) );
283 if ( validateOldPassword )
285 PasswordEncoder encoder = securitySystem.getPolicy().getPasswordEncoder();
287 if ( StringUtils.isEmpty( oldPassword ) )
290 addFieldError( "oldPassword", getText( "old.password.required" ) );
294 if ( !encoder.isPasswordValid( u.getEncodedPassword(), oldPassword ) )
297 addFieldError( "oldPassword", getText( "password.provided.does.not.match.existing" ) );
302 u.setFullName( user.getFullName() );
303 u.setEmail( user.getEmail() );
304 u.setPassword( user.getPassword() );
305 u.setLocked( user.isLocked() );
306 u.setPasswordChangeRequired( user.isPasswordChangeRequired() );
308 manager.updateUser( u, user.isPasswordChangeRequired() );
310 //check if current user then update the session
311 if ( getSecuritySession().getUser().getUsername().equals( u.getUsername() ) )
313 SecuritySession securitySession =
314 new DefaultSecuritySession( getSecuritySession().getAuthenticationResult(), u );
316 session.put( SecuritySystemConstants.SECURITY_SESSION_KEY, securitySession );
318 setSession( session );
321 catch ( UserNotFoundException e )
323 addActionError( getText( "cannot.find.user", Arrays.asList( (Object) getUsername(), e.getMessage() ) ) );
326 catch ( PasswordRuleViolationException pe )
328 processPasswordRuleViolations( pe );
331 String currentUser = getCurrentUser();
333 AuditEvent event = new AuditEvent( getText( "log.account.edit" ) );
334 event.setAffectedUser( getUsername() );
335 event.setCurrentUser( currentUser );
341 // ------------------------------------------------------------------
342 // Parameter Accessor Methods
343 // ------------------------------------------------------------------
346 public String getUpdateButton()
351 public void setUpdateButton( String updateButton )
353 this.updateButton = updateButton;
356 public AdminEditUserCredentials getUser()
361 public void setUser( AdminEditUserCredentials user )
366 public SecureActionBundle initSecureActionBundle()
367 throws SecureActionException
369 SecureActionBundle bundle = new SecureActionBundle();
370 bundle.setRequiresAuthentication( true );
371 bundle.addRequiredAuthorization( RoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION, Resource.GLOBAL );
372 bundle.addRequiredAuthorization( RoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION, getUsername() );
373 bundle.addRequiredAuthorization( RoleConstants.USER_MANAGEMENT_USER_ROLE_OPERATION, Resource.GLOBAL );
377 public List<Role> getEffectivelyAssignedRoles()
379 return effectivelyAssignedRoles;
382 public boolean isEmailValidationRequired()
384 return emailValidationRequired;
387 public boolean isHasHiddenRoles()
389 return hasHiddenRoles;
392 public void setHasHiddenRoles( boolean hasHiddenRoles )
394 this.hasHiddenRoles = hasHiddenRoles;
397 public void setOldPassword( String oldPassword )
399 this.oldPassword = oldPassword;
402 public void setUserAdminPassword( String userAdminPassword )
404 this.userAdminPassword = userAdminPassword;
407 public boolean isSelf()