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

1   package org.apache.archiva.redback.role.validator;
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.role.RoleManagerException;
23  import org.apache.archiva.redback.role.model.ModelApplication;
24  import org.apache.archiva.redback.role.model.ModelOperation;
25  import org.apache.archiva.redback.role.model.ModelPermission;
26  import org.apache.archiva.redback.role.model.ModelResource;
27  import org.apache.archiva.redback.role.model.ModelRole;
28  import org.apache.archiva.redback.role.model.ModelTemplate;
29  import org.apache.archiva.redback.role.model.RedbackRoleModel;
30  import org.apache.archiva.redback.role.util.RoleModelUtils;
31  import org.codehaus.plexus.util.dag.CycleDetectedException;
32  import org.springframework.stereotype.Service;
33  
34  import java.util.ArrayList;
35  import java.util.List;
36  
37  /**
38   * DefaultRoleModelValidator: validates completeness of the model
39   *
40   * @author: Jesse McConnell <jesse@codehaus.org>
41   *
42   */
43  @Service( "roleModelValidator" )
44  public class DefaultRoleModelValidator
45      implements RoleModelValidator
46  {
47      private List<String> validationErrors;
48  
49      public boolean validate( RedbackRoleModel model )
50          throws RoleManagerException
51      {
52          validationErrors = null;
53  
54          validateRequiredStructure( model );
55          validateResourceClosure( model );
56          validateOperationClosure( model );
57          validateChildRoleClosure( model );
58          validateParentRoleClosure( model );
59          validateTemplateClosure( model );
60          validateNoRoleCycles( model );
61          validateNoTemplateCycles( model );
62  
63          if ( validationErrors == null )
64          {
65              return true;
66          }
67          else
68          {
69              return false;
70          }
71      }
72  
73      public List<String> getValidationErrors()
74      {
75          return validationErrors;
76      }
77  
78      private void addValidationError( String error )
79      {
80          if ( validationErrors == null )
81          {
82              validationErrors = new ArrayList<String>( 0 );
83          }
84  
85          validationErrors.add( error );
86      }
87  
88      /**
89       * FIXME this should be taken care of by <required/> in modello, figure out why its not
90       * in the meantime, implement the basics
91       *
92       * @param model
93       */
94      @SuppressWarnings( "unchecked" )
95      private void validateRequiredStructure( RedbackRoleModel model )
96      {
97          // validate model has name
98  
99          for ( ModelApplication application : model.getApplications() )
100         {
101             if ( application.getId() == null )
102             {
103                 addValidationError( "model is missing application name" );
104             }
105 
106             // validate model has version
107             if ( application.getVersion() == null )
108             {
109                 addValidationError( application.getId() + " is missing version" );
110             }
111 
112             // validate resource bits
113             for ( ModelResource resource : application.getResources() )
114             {
115                 if ( resource.getName() == null )
116                 {
117                     addValidationError( resource.toString() + " missing name" );
118                 }
119 
120                 if ( resource.getId() == null )
121                 {
122                     addValidationError( resource.toString() + " missing id" );
123                 }
124             }
125 
126             // validate the operations
127             for ( ModelOperation operation : application.getOperations() )
128             {
129                 if ( operation.getName() == null )
130                 {
131                     addValidationError( operation.toString() + " missing name" );
132                 }
133 
134                 if ( operation.getId() == null )
135                 {
136                     addValidationError( operation.toString() + " missing id" );
137                 }
138             }
139 
140             for ( ModelRole role : application.getRoles() )
141             {
142                 if ( role.getId() == null )
143                 {
144                     addValidationError( role.toString() + " missing id" );
145                 }
146 
147                 if ( role.getName() == null )
148                 {
149                     addValidationError( role.toString() + " missing name" );
150                 }
151 
152                 if ( role.getPermissions() != null )
153                 {
154                     for ( ModelPermission permission : role.getPermissions() )
155                     {
156                         if ( permission.getName() == null )
157                         {
158                             addValidationError( permission.toString() + " missing name" );
159                         }
160 
161                         if ( permission.getId() == null )
162                         {
163                             addValidationError( permission.toString() + " missing id" );
164                         }
165 
166                         if ( permission.getOperation() == null )
167                         {
168                             addValidationError( permission.toString() + " missing operations" );
169                         }
170 
171                         if ( permission.getResource() == null )
172                         {
173                             addValidationError( permission.toString() + " missing resource" );
174                         }
175                     }
176                 }
177             }
178 
179             for ( ModelTemplate template : application.getTemplates() )
180             {
181                 if ( template.getId() == null )
182                 {
183                     addValidationError( template.toString() + " missing id" );
184                 }
185 
186                 if ( template.getNamePrefix() == null )
187                 {
188                     addValidationError( template.toString() + " missing name prefix" );
189                 }
190 
191                 if ( template.getPermissions() != null )
192                 {
193                     for ( ModelPermission permission : template.getPermissions() )
194                     {
195                         if ( permission.getName() == null )
196                         {
197                             addValidationError( permission.toString() + " missing name" );
198                         }
199 
200                         if ( permission.getId() == null )
201                         {
202                             addValidationError( permission.toString() + " missing id" );
203                         }
204 
205                         if ( permission.getOperation() == null )
206                         {
207                             addValidationError( permission.toString() + " missing operations" );
208                         }
209 
210                         if ( permission.getResource() == null )
211                         {
212                             addValidationError( permission.toString() + " missing resource" );
213                         }
214                     }
215                 }
216             }
217         }
218     }
219 
220     /**
221      * validate all operations in all declared permissions exist as declared in the operations section
222      *
223      * @param model
224      */
225     private void validateOperationClosure( RedbackRoleModel model )
226     {
227         List<String> operationIdList = RoleModelUtils.getOperationIdList( model );
228 
229         // check the operations in role permissions
230         for ( ModelApplication application : model.getApplications() )
231         {
232             for ( ModelRole role : application.getRoles() )
233             {
234                 if ( role.getPermissions() != null )
235                 {
236                     for ( ModelPermission permission : role.getPermissions() )
237                     {
238                         if ( !operationIdList.contains( permission.getOperation() ) )
239                         {
240                             addValidationError( "missing operation: " + permission.getOperation() + " in permission "
241                                                     + permission.getId() );
242                         }
243                     }
244                 }
245             }
246 
247             // check the operations in template permissions
248             for ( ModelTemplate template : application.getTemplates() )
249             {
250                 if ( template.getPermissions() != null )
251                 {
252                     for ( ModelPermission permission : template.getPermissions() )
253                     {
254                         if ( !operationIdList.contains( permission.getOperation() ) )
255                         {
256                             addValidationError( "missing operation: " + permission.getOperation() + " in permission "
257                                                     + permission.getId() );
258                         }
259                     }
260                 }
261             }
262         }
263     }
264 
265     private void validateResourceClosure( RedbackRoleModel model )
266     {
267         List<String> resourceIdList = RoleModelUtils.getResourceIdList( model );
268         for ( ModelApplication application : model.getApplications() )
269         {
270             for ( ModelRole role : application.getRoles() )
271             {
272                 if ( role.getPermissions() != null )
273                 {
274                     for ( ModelPermission permission : role.getPermissions() )
275                     {
276                         if ( !resourceIdList.contains( permission.getResource() ) )
277                         {
278                             addValidationError( "missing operation: " + permission.getResource() + " in permission "
279                                                     + permission.getId() );
280                         }
281                     }
282                 }
283             }
284         }
285     }
286 
287     private void validateChildRoleClosure( RedbackRoleModel model )
288     {
289         List<String> roleIdList = RoleModelUtils.getRoleIdList( model );
290         for ( ModelApplication application : model.getApplications() )
291         {
292             for ( ModelRole role : application.getRoles() )
293             {
294                 if ( role.getChildRoles() != null )
295                 {
296                     for ( String childRoleId : role.getChildRoles() )
297                     {
298                         if ( !roleIdList.contains( childRoleId ) )
299                         {
300                             addValidationError(
301                                 "missing role id: " + childRoleId + " in child roles of role " + role.getId() );
302                         }
303                     }
304                 }
305             }
306 
307             for ( ModelTemplate template : application.getTemplates() )
308             {
309                 if ( template.getChildRoles() != null )
310                 {
311                     for ( String childRoleId : template.getChildRoles() )
312                     {
313                         if ( !roleIdList.contains( childRoleId ) )
314                         {
315                             addValidationError(
316                                 "missing role id: " + childRoleId + " in child roles of template " + template.getId() );
317                         }
318                     }
319                 }
320             }
321         }
322     }
323 
324     @SuppressWarnings( "unchecked" )
325     private void validateParentRoleClosure( RedbackRoleModel model )
326     {
327         List roleIdList = RoleModelUtils.getRoleIdList( model );
328 
329         for ( ModelApplication application : model.getApplications() )
330         {
331             for ( ModelRole role : application.getRoles() )
332             {
333                 if ( role.getParentRoles() != null )
334                 {
335                     for ( String parentRoleId : role.getParentRoles() )
336                     {
337                         if ( !roleIdList.contains( parentRoleId ) )
338                         {
339                             addValidationError(
340                                 "missing role id: " + parentRoleId + " in parent roles of role " + role.getId() );
341                         }
342                     }
343                 }
344             }
345 
346             for ( ModelTemplate template : application.getTemplates() )
347             {
348                 if ( template.getParentRoles() != null )
349                 {
350                     for ( String parentRoleId : template.getParentRoles() )
351                     {
352                         if ( !roleIdList.contains( parentRoleId ) )
353                         {
354                             addValidationError( "missing role id: " + parentRoleId + " in parent roles of template "
355                                                     + template.getId() );
356                         }
357                     }
358                 }
359             }
360         }
361     }
362 
363     private void validateTemplateClosure( RedbackRoleModel model )
364     {
365         List templateIdList = RoleModelUtils.getTemplateIdList( model );
366 
367         // template name prefix must be unique
368         List<String> templateNamePrefixList = new ArrayList<String>();
369 
370         for ( ModelApplication application : model.getApplications() )
371         {
372             for ( ModelTemplate template : application.getTemplates() )
373             {
374                 if ( template.getParentTemplates() != null )
375                 {
376                     for ( String parentTemplateId : template.getParentTemplates() )
377                     {
378                         if ( !templateIdList.contains( parentTemplateId ) )
379                         {
380                             addValidationError(
381                                 "missing template id: " + parentTemplateId + " in parent templates of template "
382                                     + template.getId() );
383                         }
384                     }
385                 }
386 
387                 if ( template.getChildTemplates() != null )
388                 {
389                     for ( String childTemplateId : template.getChildTemplates() )
390                     {
391                         if ( !templateIdList.contains( childTemplateId ) )
392                         {
393                             addValidationError(
394                                 "missing template id: " + childTemplateId + " in child templates of template "
395                                     + template.getId() );
396                         }
397                     }
398                 }
399 
400                 if ( !templateNamePrefixList.contains( template.getNamePrefix() ) )
401                 {
402                     templateNamePrefixList.add( template.getNamePrefix() );
403                 }
404                 else
405                 {
406                     addValidationError( "duplicate name prefix detected: " + template.getNamePrefix() );
407                 }
408             }
409         }
410     }
411 
412     /**
413      * We are not allowed to have cycles between roles, this method is to detect and raise a red flag when that happens.
414      *
415      * @param model
416      */
417     private void validateNoRoleCycles( RedbackRoleModel model )
418     {
419         try
420         {
421             RoleModelUtils.generateRoleGraph( model );
422         }
423         catch ( CycleDetectedException e )
424         {
425             addValidationError( "cycle detected: " + e.getMessage() );
426         }
427     }
428 
429     /**
430      * We are not allowed to have cycles between template either, this method is to detect and
431      * raise a red flag when that happens.  Templates are a bit more complex since they have both
432      * child and parent roles, as well as runtime parent and child templates
433      * <p/>
434      * the id should be sufficient to test cycles here even though in runtime the id's do not need to be
435      * unique since it is the binding of a namePrefix and a resource that makes them unique
436      *
437      * @param model
438      */
439     private void validateNoTemplateCycles( RedbackRoleModel model )
440     {
441         try
442         {
443             RoleModelUtils.generateTemplateGraph( model );
444         }
445         catch ( CycleDetectedException e )
446         {
447             addValidationError( "template cycle detected: " + e.getMessage() );
448         }
449     }
450 }