This project has retired. For details please refer to its Attic page.
DefaultRoleModelProcessor xref
View Javadoc

1   package org.apache.archiva.redback.role.processor;
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.Operation;
23  import org.apache.archiva.redback.rbac.Permission;
24  import org.apache.archiva.redback.rbac.RBACManager;
25  import org.apache.archiva.redback.rbac.RbacManagerException;
26  import org.apache.archiva.redback.rbac.Resource;
27  import org.apache.archiva.redback.rbac.Role;
28  import org.apache.archiva.redback.role.RoleManagerException;
29  import org.apache.archiva.redback.role.model.ModelApplication;
30  import org.apache.archiva.redback.role.model.ModelOperation;
31  import org.apache.archiva.redback.role.model.ModelPermission;
32  import org.apache.archiva.redback.role.model.ModelResource;
33  import org.apache.archiva.redback.role.model.ModelRole;
34  import org.apache.archiva.redback.role.model.RedbackRoleModel;
35  import org.apache.archiva.redback.role.util.RoleModelUtils;
36  import org.apache.commons.lang.time.StopWatch;
37  import org.codehaus.plexus.util.dag.CycleDetectedException;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  import org.springframework.stereotype.Service;
41  
42  import javax.inject.Inject;
43  import javax.inject.Named;
44  import java.util.ArrayList;
45  import java.util.HashMap;
46  import java.util.HashSet;
47  import java.util.List;
48  import java.util.Map;
49  import java.util.Set;
50  
51  /**
52   * DefaultRoleModelProcessor: inserts the components of the model that can be populated into the rbac manager
53   *
54   * @author: Jesse McConnell <jesse@codehaus.org>
55   */
56  @Service( "roleModelProcessor" )
57  public class DefaultRoleModelProcessor
58      implements RoleModelProcessor
59  {
60      private Logger log = LoggerFactory.getLogger( DefaultRoleModelProcessor.class );
61  
62      @Inject
63      @Named( value = "rbacManager#default" )
64      private RBACManager rbacManager;
65  
66      private Map<String, Resource> resourceMap = new HashMap<String, Resource>();
67  
68      private Map<String, Operation> operationMap = new HashMap<String, Operation>();
69  
70      public void process( RedbackRoleModel model )
71          throws RoleManagerException
72      {
73          // must process resources and operations first, they are required for the
74          // permissions in the roles to add in correctly
75          processResources( model );
76          processOperations( model );
77  
78          processRoles( model );
79      }
80  
81      @SuppressWarnings( "unchecked" )
82      private void processResources( RedbackRoleModel model )
83          throws RoleManagerException
84      {
85          for ( ModelApplication application : model.getApplications() )
86          {
87              for ( ModelResource profileResource : application.getResources() )
88              {
89                  try
90                  {
91                      if ( !rbacManager.resourceExists( profileResource.getName() ) )
92                      {
93  
94                          Resource resource = rbacManager.createResource( profileResource.getName() );
95                          resource.setPermanent( profileResource.isPermanent() );
96                          resource = rbacManager.saveResource( resource );
97  
98                          // store for use in permission creation
99                          resourceMap.put( profileResource.getId(), resource );
100 
101                     }
102                     else
103                     {
104                         resourceMap.put( profileResource.getId(),
105                                          rbacManager.getResource( profileResource.getName() ) );
106                     }
107                 }
108                 catch ( RbacManagerException e )
109                 {
110                     throw new RoleManagerException( "error creating resource '" + profileResource.getName() + "'", e );
111                 }
112             }
113         }
114     }
115 
116     @SuppressWarnings( "unchecked" )
117     private void processOperations( RedbackRoleModel model )
118         throws RoleManagerException
119     {
120         for ( ModelApplication application : model.getApplications() )
121         {
122             for ( ModelOperation profileOperation : application.getOperations() )
123             {
124                 try
125                 {
126                     if ( !rbacManager.operationExists( profileOperation.getName() ) )
127                     {
128 
129                         Operation operation = rbacManager.createOperation( profileOperation.getName() );
130                         operation.setPermanent( profileOperation.isPermanent() );
131                         operation.setDescription( profileOperation.getDescription() );
132                         operation = rbacManager.saveOperation( operation );
133 
134                         // store for use in permission creation
135                         operationMap.put( profileOperation.getId(), operation );
136 
137                     }
138                     else
139                     {
140                         operationMap.put( profileOperation.getId(),
141                                           rbacManager.getOperation( profileOperation.getName() ) );
142                     }
143                 }
144                 catch ( RbacManagerException e )
145                 {
146                     throw new RoleManagerException( "error creating operation '" + profileOperation.getName() + "'",
147                                                     e );
148                 }
149             }
150         }
151     }
152 
153     @SuppressWarnings( "unchecked" )
154     private void processRoles( RedbackRoleModel model )
155         throws RoleManagerException
156     {
157         StopWatch stopWatch = new StopWatch();
158         stopWatch.reset();
159         stopWatch.start();
160         List<String> sortedGraph;
161         try
162         {
163             sortedGraph = RoleModelUtils.reverseTopologicalSortedRoleList( model );
164         }
165         catch ( CycleDetectedException e )
166         {
167             throw new RoleManagerException( "cycle detected: this should have been caught in validation", e );
168         }
169 
170         List<Role> allRoles;
171         try
172         {
173             allRoles = rbacManager.getAllRoles();
174         }
175         catch ( RbacManagerException e )
176         {
177             throw new RoleManagerException( e.getMessage(), e );
178         }
179 
180         Set<String> allRoleNames = new HashSet<String>( allRoles.size() );
181         for ( Role role : allRoles )
182         {
183             allRoleNames.add( role.getName() );
184         }
185 
186         for ( String roleId : sortedGraph )
187         {
188             ModelRole roleProfile = RoleModelUtils.getModelRole( model, roleId );
189 
190             List<Permission> permissions = processPermissions( roleProfile.getPermissions() );
191 
192             boolean roleExists = allRoleNames.contains( roleProfile.getName() );// false;
193 
194             /*try
195             {
196                 roleExists = rbacManager.roleExists( roleProfile.getName() );
197             }
198             catch ( RbacManagerException e )
199             {
200                 throw new RoleManagerException( e.getMessage(), e );
201             }*/
202 
203             if ( !roleExists )
204             {
205                 try
206                 {
207                     Role role = rbacManager.createRole( roleProfile.getName() );
208                     role.setDescription( roleProfile.getDescription() );
209                     role.setPermanent( roleProfile.isPermanent() );
210                     role.setAssignable( roleProfile.isAssignable() );
211 
212                     // add any permissions associated with this role
213                     for ( Permission permission : permissions )
214                     {
215                         role.addPermission( permission );
216                     }
217 
218                     // add child roles to this role
219                     if ( roleProfile.getChildRoles() != null )
220                     {
221                         for ( String childRoleId : roleProfile.getChildRoles() )
222                         {
223                             ModelRole childRoleProfile = RoleModelUtils.getModelRole( model, childRoleId );
224                             role.addChildRoleName( childRoleProfile.getName() );
225                         }
226                     }
227 
228                     rbacManager.saveRole( role );
229                     allRoleNames.add( role.getName() );
230 
231                     // add link from parent roles to this new role
232                     if ( roleProfile.getParentRoles() != null )
233                     {
234                         for ( String parentRoleId : roleProfile.getParentRoles() )
235                         {
236                             ModelRole parentModelRole = RoleModelUtils.getModelRole( model, parentRoleId );
237                             Role parentRole = rbacManager.getRole( parentModelRole.getName() );
238                             parentRole.addChildRoleName( role.getName() );
239                             rbacManager.saveRole( parentRole );
240                             allRoleNames.add( parentRole.getName() );
241                         }
242                     }
243 
244                 }
245                 catch ( RbacManagerException e )
246                 {
247                     throw new RoleManagerException( "error creating role '" + roleProfile.getName() + "'", e );
248                 }
249             }
250             else
251             {
252                 try
253                 {
254                     Role role = rbacManager.getRole( roleProfile.getName() );
255 
256                     boolean changed = false;
257                     for ( Permission permission : permissions )
258                     {
259                         if ( !role.getPermissions().contains( permission ) )
260                         {
261                             log.info( "Adding new permission '" + permission.getName() + "' to role '" + role.getName()
262                                           + "'" );
263                             role.addPermission( permission );
264                             changed = true;
265                         }
266                     }
267 
268                     // Copy list to avoid concurrent modification [REDBACK-220]
269                     List<Permission> oldPermissions = new ArrayList<Permission>( role.getPermissions() );
270                     for ( Permission permission : oldPermissions )
271                     {
272                         if ( !permissions.contains( permission ) )
273                         {
274                             log.info(
275                                 "Removing old permission '" + permission.getName() + "' from role '" + role.getName()
276                                     + "'" );
277                             role.removePermission( permission );
278                             changed = true;
279                         }
280                     }
281                     if ( changed )
282                     {
283                         rbacManager.saveRole( role );
284                         allRoleNames.add( role.getName() );
285                     }
286                 }
287                 catch ( RbacManagerException e )
288                 {
289                     throw new RoleManagerException( "error updating role '" + roleProfile.getName() + "'", e );
290                 }
291             }
292         }
293         stopWatch.stop();
294         log.info( "time to process roles model: {} ms", stopWatch.getTime() );
295     }
296 
297     private List<Permission> processPermissions( List<ModelPermission> permissions )
298         throws RoleManagerException
299     {
300         List<Permission> rbacPermissions = new ArrayList<Permission>( permissions.size() );
301 
302         for ( ModelPermission profilePermission : permissions )
303         {
304             try
305             {
306                 if ( !rbacManager.permissionExists( profilePermission.getName() ) )
307                 {
308 
309                     Permission permission = rbacManager.createPermission( profilePermission.getName() );
310 
311                     // get the operation out of the map we stored it in when we created it _by_ the id in the model
312                     Operation operation = (Operation) operationMap.get( profilePermission.getOperation() );
313                     // same with resource
314                     Resource resource = (Resource) resourceMap.get( profilePermission.getResource() );
315 
316                     permission.setOperation( operation );
317                     permission.setResource( resource );
318                     permission.setPermanent( profilePermission.isPermanent() );
319                     permission.setDescription( profilePermission.getDescription() );
320 
321                     permission = rbacManager.savePermission( permission );
322 
323                     rbacPermissions.add( permission );
324 
325                 }
326                 else
327                 {
328                     rbacPermissions.add( rbacManager.getPermission( profilePermission.getName() ) );
329                 }
330             }
331             catch ( RbacManagerException e )
332             {
333                 throw new RoleManagerException( "error creating permission '" + profilePermission.getName() + "'", e );
334             }
335         }
336         return rbacPermissions;
337     }
338 
339     public RBACManager getRbacManager()
340     {
341         return rbacManager;
342     }
343 
344     public void setRbacManager( RBACManager rbacManager )
345     {
346         this.rbacManager = rbacManager;
347     }
348 }
349 
350