]> source.dussan.org Git - archiva.git/blob
b9728c9f535635f07c8508742120a884dcf636aa
[archiva.git] /
1 package org.apache.archiva.redback.struts2.action.admin;
2
3 /*
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
22 import org.apache.archiva.redback.policy.PasswordEncoder;
23 import org.apache.archiva.redback.rbac.RBACManager;
24 import org.apache.archiva.redback.rbac.Resource;
25 import org.apache.archiva.redback.struts2.action.AuditEvent;
26 import org.apache.archiva.redback.struts2.action.CancellableAction;
27 import org.apache.archiva.redback.users.User;
28 import org.apache.archiva.redback.users.UserNotFoundException;
29 import org.apache.commons.lang.StringEscapeUtils;
30 import org.apache.archiva.redback.policy.PasswordRuleViolationException;
31 import org.apache.archiva.redback.rbac.RbacManagerException;
32 import org.apache.archiva.redback.rbac.Role;
33 import org.apache.archiva.redback.system.DefaultSecuritySession;
34 import org.apache.archiva.redback.system.SecuritySession;
35 import org.apache.archiva.redback.system.SecuritySystemConstants;
36 import org.apache.archiva.redback.users.UserManager;
37 import org.codehaus.plexus.util.StringUtils;
38 import org.apache.archiva.redback.integration.interceptor.SecureActionBundle;
39 import org.apache.archiva.redback.integration.interceptor.SecureActionException;
40 import org.apache.archiva.redback.integration.model.AdminEditUserCredentials;
41 import org.apache.archiva.redback.integration.role.RoleConstants;
42 import org.springframework.context.annotation.Scope;
43 import org.springframework.stereotype.Controller;
44
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;
52
53 /**
54  * UserEditAction
55  *
56  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
57  *
58  */
59 @Controller( "redback-admin-user-edit" )
60 @Scope( "prototype" )
61 public class UserEditAction
62     extends AbstractAdminUserCredentialsAction
63     implements CancellableAction
64 {
65     /**
66      *  role-hint="cached"
67      */
68     @Inject
69     @Named( value = "rBACManager#cached" )
70     private RBACManager rbacManager;
71
72     /**
73      * A List of {@link org.apache.archiva.redback.rbac.Role} objects.
74      */
75     private List<Role> effectivelyAssignedRoles;
76
77     // ------------------------------------------------------------------
78     // Action Parameters
79     // ------------------------------------------------------------------
80
81     private AdminEditUserCredentials user;
82
83     private String updateButton;
84
85     private boolean emailValidationRequired;
86
87     private boolean hasHiddenRoles;
88
89     private String oldPassword;
90
91     private String userAdminPassword;
92
93     private boolean self;
94
95     public static String CONFIRM = "confirm";
96
97     public static String CONFIRM_ERROR = "confirmError";
98
99     // ------------------------------------------------------------------
100     // Action Entry Points - (aka Names)
101     // ------------------------------------------------------------------
102
103     public String edit()
104     {
105         oldPassword = "";
106
107         emailValidationRequired = securitySystem.getPolicy().getUserValidationSettings().isEmailValidationRequired();
108
109         if ( getUsername() == null )
110         {
111             addActionError( getText( "cannot.edit.user.null.username" ) );
112             return ERROR;
113         }
114
115         if ( StringUtils.isEmpty( getUsername() ) )
116         {
117             addActionError( getText( "cannot.edit.user.empty.username" ) );
118             return ERROR;
119         }
120
121         UserManager manager = super.securitySystem.getUserManager();
122
123         String escapedUsername = StringEscapeUtils.escapeXml( getUsername() );
124
125         if ( !manager.userExists( escapedUsername ) )
126         {
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 ) ) );
130             return ERROR;
131         }
132
133         try
134         {
135             User u = manager.findUser( escapedUsername );
136
137             if ( u == null )
138             {
139                 addActionError( getText( "cannot.operate.on.null.user" ) );
140                 return ERROR;
141             }
142
143             user = new AdminEditUserCredentials( u );
144
145             // require user admin to provide his/her password if editing account of others
146             if ( getUsername().equals( getCurrentUser() ) )
147             {
148                 self = true;
149             }
150
151             try
152             {
153                 String principal = u.getPrincipal().toString();
154                 List<Role> roles = filterAssignableRoles( rbacManager.getEffectivelyAssignedRoles( principal ) );
155                 effectivelyAssignedRoles = filterRolesForCurrentUserAccess( roles );
156                 hasHiddenRoles = ( roles.size() > effectivelyAssignedRoles.size() );
157             }
158             catch ( RbacManagerException rme )
159             {
160                 // ignore, this can happen when the user has no roles assigned  
161             }
162         }
163         catch ( UserNotFoundException e )
164         {
165             addActionError( getText( "cannot.get.user", Arrays.asList( (Object) getUsername(), e.getMessage() ) ) );
166             return ERROR;
167         }
168
169         return INPUT;
170     }
171
172     private List<Role> filterAssignableRoles( Collection<Role> roles )
173     {
174         List<Role> assignableRoles = new ArrayList<Role>( roles.size() );
175         for ( Role r : roles )
176         {
177             if ( r.isAssignable() )
178             {
179                 assignableRoles.add( r );
180             }
181         }
182         return assignableRoles;
183     }
184
185     public String submit()
186     {
187         if ( getUsername() == null )
188         {
189             addActionError( getText( "cannot.edit.user.null.username" ) );
190             return ERROR;
191         }
192
193         if ( StringUtils.isEmpty( getUsername() ) )
194         {
195             addActionError( getText( "cannot.edit.user.empty.username" ) );
196             return ERROR;
197         }
198
199         if ( user == null )
200         {
201             addActionError( getText( "cannot.edit.user.null.credentials" ) );
202             return ERROR;
203         }
204
205         internalUser = user;
206
207         validateCredentialsLoose();
208
209         // if form errors, return with them before continuing
210         if ( hasActionErrors() || hasFieldErrors() )
211         {
212             return ERROR;
213         }
214
215         if ( !getUsername().equals( getCurrentUser() ) )
216         {
217             return CONFIRM;
218         }
219         else
220         {
221             return save( true );
222         }
223     }
224
225     // confirm user admin's password before allowing to proceed with the operation
226     public String confirmAdminPassword()
227     {
228         UserManager manager = super.securitySystem.getUserManager();
229
230         if ( StringUtils.isEmpty( userAdminPassword ) )
231         {
232             addActionError( getText( "user.admin.password.required" ) );
233             return CONFIRM_ERROR;
234         }
235
236         try
237         {
238             User currentUser = manager.findUser( getCurrentUser() );
239
240             // check if user admin provided correct password!
241             PasswordEncoder encoder = securitySystem.getPolicy().getPasswordEncoder();
242             if ( !encoder.isPasswordValid( currentUser.getEncodedPassword(), userAdminPassword ) )
243             {
244                 addActionError( getText( "user.admin.password.does.not.match.existing" ) );
245                 return CONFIRM_ERROR;
246             }
247         }
248         catch ( UserNotFoundException e )
249         {
250             addActionError( getText( "cannot.find.user", Arrays.asList( (Object) getCurrentUser(), e.getMessage() ) ) );
251             return CONFIRM_ERROR;
252         }
253
254         return save( false );
255     }
256
257     public String cancel()
258     {
259         return CANCEL;
260     }
261
262     private String save( boolean validateOldPassword )
263     {
264         UserManager manager = super.securitySystem.getUserManager();
265
266         if ( !manager.userExists( getUsername() ) )
267         {
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() ) ) );
271             return ERROR;
272         }
273
274         try
275         {
276             User u = manager.findUser( getUsername() );
277             if ( u == null )
278             {
279                 addActionError( getText( "cannot.operate.on.null.user" ) );
280                 return ERROR;
281             }
282
283             if ( validateOldPassword )
284             {
285                 PasswordEncoder encoder = securitySystem.getPolicy().getPasswordEncoder();
286
287                 if ( StringUtils.isEmpty( oldPassword ) )
288                 {
289                     self = true;
290                     addFieldError( "oldPassword", getText( "old.password.required" ) );
291                     return ERROR;
292                 }
293
294                 if ( !encoder.isPasswordValid( u.getEncodedPassword(), oldPassword ) )
295                 {
296                     self = true;
297                     addFieldError( "oldPassword", getText( "password.provided.does.not.match.existing" ) );
298                     return ERROR;
299                 }
300             }
301
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() );
307
308             manager.updateUser( u, user.isPasswordChangeRequired() );
309
310             //check if current user then update the session
311             if ( getSecuritySession().getUser().getUsername().equals( u.getUsername() ) )
312             {
313                 SecuritySession securitySession =
314                     new DefaultSecuritySession( getSecuritySession().getAuthenticationResult(), u );
315
316                 session.put( SecuritySystemConstants.SECURITY_SESSION_KEY, securitySession );
317
318                 setSession( session );
319             }
320         }
321         catch ( UserNotFoundException e )
322         {
323             addActionError( getText( "cannot.find.user", Arrays.asList( (Object) getUsername(), e.getMessage() ) ) );
324             return ERROR;
325         }
326         catch ( PasswordRuleViolationException pe )
327         {
328             processPasswordRuleViolations( pe );
329             return ERROR;
330         }
331         String currentUser = getCurrentUser();
332
333         AuditEvent event = new AuditEvent( getText( "log.account.edit" ) );
334         event.setAffectedUser( getUsername() );
335         event.setCurrentUser( currentUser );
336         event.log();
337
338         return SUCCESS;
339     }
340
341     // ------------------------------------------------------------------
342     // Parameter Accessor Methods
343     // ------------------------------------------------------------------
344
345
346     public String getUpdateButton()
347     {
348         return updateButton;
349     }
350
351     public void setUpdateButton( String updateButton )
352     {
353         this.updateButton = updateButton;
354     }
355
356     public AdminEditUserCredentials getUser()
357     {
358         return user;
359     }
360
361     public void setUser( AdminEditUserCredentials user )
362     {
363         this.user = user;
364     }
365
366     public SecureActionBundle initSecureActionBundle()
367         throws SecureActionException
368     {
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 );
374         return bundle;
375     }
376
377     public List<Role> getEffectivelyAssignedRoles()
378     {
379         return effectivelyAssignedRoles;
380     }
381
382     public boolean isEmailValidationRequired()
383     {
384         return emailValidationRequired;
385     }
386
387     public boolean isHasHiddenRoles()
388     {
389         return hasHiddenRoles;
390     }
391
392     public void setHasHiddenRoles( boolean hasHiddenRoles )
393     {
394         this.hasHiddenRoles = hasHiddenRoles;
395     }
396
397     public void setOldPassword( String oldPassword )
398     {
399         this.oldPassword = oldPassword;
400     }
401
402     public void setUserAdminPassword( String userAdminPassword )
403     {
404         this.userAdminPassword = userAdminPassword;
405     }
406
407     public boolean isSelf()
408     {
409         return self;
410     }
411 }