]> source.dussan.org Git - archiva.git/blob
a7791efdae0c1e587abd221f160966e8d6a2408d
[archiva.git] /
1 package org.apache.archiva.redback.struts2.action;
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.rbac.Permission;
23 import org.apache.archiva.redback.rbac.RBACManager;
24 import org.apache.archiva.redback.rbac.Resource;
25 import org.apache.archiva.redback.rbac.Role;
26 import org.apache.archiva.redback.users.User;
27 import org.apache.archiva.redback.policy.PasswordRuleViolationException;
28 import org.apache.archiva.redback.rbac.RbacManagerException;
29 import org.apache.archiva.redback.system.SecuritySystem;
30 import org.codehaus.plexus.util.StringUtils;
31 import org.apache.archiva.redback.integration.model.UserCredentials;
32 import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
33 import org.apache.archiva.redback.integration.util.RoleSorter;
34
35 import javax.inject.Inject;
36 import javax.inject.Named;
37 import javax.mail.internet.AddressException;
38 import javax.mail.internet.InternetAddress;
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.List;
42 import java.util.Map;
43
44 /**
45  * AbstractUserCredentialsAction
46  *
47  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
48  *
49  */
50 public abstract class AbstractUserCredentialsAction
51     extends AbstractSecurityAction
52 {
53     // ------------------------------------------------------------------
54     //  Component Requirements
55     // ------------------------------------------------------------------
56
57     /**
58      *
59      */
60     @Inject
61     @Named( value = "rBACManager#cached" )
62     private RBACManager manager;
63
64     /**
65      *
66      */
67     @Inject
68     protected SecuritySystem securitySystem;
69
70     // ------------------------------------------------------------------
71     // Action Parameters
72     // ------------------------------------------------------------------
73
74     protected UserCredentials internalUser;
75
76     protected final String VALID_USERNAME_CHARS = "[a-zA-Z_0-9\\-.@]*";
77
78     public RBACManager getManager()
79     {
80         return manager;
81     }
82
83     public void setManager( RBACManager manager )
84     {
85         this.manager = manager;
86     }
87
88     public SecuritySystem getSecuritySystem()
89     {
90         return securitySystem;
91     }
92
93     public void setSecuritySystem( SecuritySystem securitySystem )
94     {
95         this.securitySystem = securitySystem;
96     }
97
98     // ------------------------------------------------------------------
99     // Action Entry Points - (aka Names)
100     // ------------------------------------------------------------------
101
102     public void validateCredentialsLoose()
103     {
104         if ( StringUtils.isEmpty( internalUser.getUsername() ) )
105         {
106             addFieldError( "user.username", getText( "username.required" ) );
107         }
108         else
109         {
110             if ( !internalUser.getUsername().matches( VALID_USERNAME_CHARS ) )
111             {
112                 addFieldError( "user.username", getText( "username.invalid.characters" ) );
113             }
114         }
115
116         if ( StringUtils.isEmpty( internalUser.getFullName() ) )
117         {
118             addFieldError( "user.fullName", getText( "fullName.required" ) );
119         }
120
121         if ( StringUtils.isEmpty( internalUser.getEmail() ) )
122         {
123             addFieldError( "user.email", getText( "email.required" ) );
124         }
125
126         if ( !StringUtils.equals( internalUser.getPassword(), internalUser.getConfirmPassword() ) )
127         {
128             addFieldError( "user.confirmPassword", getText( "passwords.does.not.match" ) );
129         }
130
131         try
132         {
133             if ( !StringUtils.isEmpty( internalUser.getEmail() ) )
134             {
135                 new InternetAddress( internalUser.getEmail(), true );
136             }
137         }
138         catch ( AddressException e )
139         {
140             addFieldError( "user.email", getText( "email.invalid" ) );
141         }
142     }
143
144     public void validateCredentialsStrict()
145     {
146         validateCredentialsLoose();
147
148         User tmpuser = internalUser.createUser( securitySystem.getUserManager() );
149
150         try
151         {
152             securitySystem.getPolicy().validatePassword( tmpuser );
153         }
154         catch ( PasswordRuleViolationException e )
155         {
156             processPasswordRuleViolations( e );
157         }
158
159         if ( ( StringUtils.isEmpty( internalUser.getPassword() ) ) )
160         {
161             addFieldError( "user.password", getText( "password.required" ) );
162         }
163     }
164
165     /**
166      * this is a hack. this is a hack around the requirements of putting RBAC constraints into the model. this adds one
167      * very major restriction to this security system, that a role name must contain the identifiers of the resource
168      * that is being constrained for adding and granting of roles, this is unacceptable in the long term and we need to
169      * get the model refactored to include this RBAC concept
170      *
171      * @param roleList
172      * @return
173      * @throws org.apache.archiva.redback.rbac.RbacManagerException
174      *
175      */
176     protected List<Role> filterRolesForCurrentUserAccess( List<Role> roleList )
177         throws RbacManagerException
178     {
179         String currentUser = getCurrentUser();
180
181         List<Role> filteredRoleList = new ArrayList<Role>();
182
183         Map<String, List<Permission>> assignedPermissionMap = manager.getAssignedPermissionMap( currentUser );
184         List<String> resourceGrants = new ArrayList<String>();
185
186         if ( assignedPermissionMap.containsKey( RedbackRoleConstants.USER_MANAGEMENT_ROLE_GRANT_OPERATION ) )
187         {
188             List<Permission> roleGrantPermissions =
189                 assignedPermissionMap.get( RedbackRoleConstants.USER_MANAGEMENT_ROLE_GRANT_OPERATION );
190
191             for ( Permission permission : roleGrantPermissions )
192             {
193                 if ( permission.getResource().getIdentifier().equals( Resource.GLOBAL ) )
194                 {
195                     // the current user has the rights to assign any given role
196                     return roleList;
197                 }
198                 else
199                 {
200                     resourceGrants.add( permission.getResource().getIdentifier() );
201                 }
202             }
203         }
204         else
205         {
206             return Collections.emptyList();
207         }
208
209         String delimiter = " - ";
210
211         // we should have a list of resourceGrants now, this will provide us with the information necessary to restrict
212         // the role list
213         for ( Role role : roleList )
214         {
215             int delimiterIndex = role.getName().indexOf( delimiter );
216             for ( String resourceIdentifier : resourceGrants )
217             {
218
219                 if ( ( role.getName().indexOf( resourceIdentifier ) != -1 ) && ( delimiterIndex != -1 ) )
220                 {
221                     String resourceName = role.getName().substring( delimiterIndex + delimiter.length() );
222                     if ( resourceName.equals( resourceIdentifier ) )
223                     {
224                         filteredRoleList.add( role );
225                     }
226                 }
227             }
228         }
229
230         Collections.sort( filteredRoleList, new RoleSorter() );
231         return filteredRoleList;
232     }
233
234     protected List<Role> getFilteredRolesForCurrentUserAccess()
235         throws RbacManagerException
236     {
237         List<Role> roles = manager.getAllRoles();
238
239         if ( roles == null )
240         {
241             return Collections.emptyList();
242         }
243
244         return filterRolesForCurrentUserAccess( roles );
245     }
246 }