]> source.dussan.org Git - archiva.git/blob
cf32595697f01d2ccdfc33b9da0fa4fec889547f
[archiva.git] /
1 package org.apache.archiva.redback.role;
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.RBACManager;
23 import org.apache.archiva.redback.rbac.RbacManagerException;
24 import org.apache.archiva.redback.rbac.Role;
25 import org.apache.archiva.redback.rbac.UserAssignment;
26 import org.apache.archiva.redback.role.model.ModelApplication;
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.model.io.stax.RedbackRoleModelStaxReader;
31 import org.apache.archiva.redback.role.processor.RoleModelProcessor;
32 import org.apache.commons.io.IOUtils;
33 import org.apache.commons.lang.SystemUtils;
34 import org.apache.archiva.redback.rbac.Resource;
35 import org.apache.archiva.redback.role.template.RoleTemplateProcessor;
36 import org.apache.archiva.redback.role.util.RoleModelUtils;
37 import org.apache.archiva.redback.role.validator.RoleModelValidator;
38 import org.apache.commons.lang.time.StopWatch;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.springframework.stereotype.Service;
42
43 import javax.annotation.PostConstruct;
44 import javax.inject.Inject;
45 import javax.inject.Named;
46 import javax.xml.stream.XMLStreamException;
47 import java.io.IOException;
48 import java.io.InputStreamReader;
49 import java.net.MalformedURLException;
50 import java.net.URL;
51 import java.util.Arrays;
52 import java.util.Enumeration;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56
57 /**
58  * RoleProfileManager:
59  *
60  * @author: Jesse McConnell <jesse@codehaus.org>
61  */
62 @Service("roleManager")
63 public class DefaultRoleManager
64     implements RoleManager
65 {
66     private Logger log = LoggerFactory.getLogger( DefaultRoleManager.class );
67
68     /**
69      * the blessed model that has been validated as complete
70      */
71     private RedbackRoleModel blessedModel;
72
73     /**
74      * the merged model that can be validated as complete
75      */
76     private RedbackRoleModel unblessedModel;
77
78     /**
79      * a map of the resources, and the model that they loaded
80      */
81     private Map<String, ModelApplication> knownResources = new HashMap<String, ModelApplication>();
82
83     @Inject
84     @Named(value = "roleModelValidator")
85     private RoleModelValidator modelValidator;
86
87     @Inject
88     @Named(value = "roleModelProcessor")
89     private RoleModelProcessor modelProcessor;
90
91     @Inject
92     @Named(value = "roleTemplateProcessor")
93     private RoleTemplateProcessor templateProcessor;
94
95     @Inject
96     @Named(value = "rbacManager#cached")
97     private RBACManager rbacManager;
98
99
100     @SuppressWarnings("unchecked")
101     public void loadRoleModel( URL resource )
102         throws RoleManagerException
103     {
104         RedbackRoleModelStaxReader reader = new RedbackRoleModelStaxReader();
105
106         InputStreamReader inputStreamReader = null;
107
108         try
109         {
110
111             inputStreamReader = new InputStreamReader( resource.openStream() );
112
113             RedbackRoleModel roleModel = reader.read( inputStreamReader );
114
115             for ( ModelApplication app : roleModel.getApplications() )
116             {
117                 if ( !knownResources.containsKey( app.getId() ) )
118                 {
119                     log.info( "loading {}", app.getId() );
120                     loadApplication( app );
121                 }
122             }
123         }
124         catch ( MalformedURLException e )
125         {
126             throw new RoleManagerException( "error locating redback profile", e );
127         }
128         catch ( IOException e )
129         {
130             throw new RoleManagerException( "error reading redback profile", e );
131         }
132         catch ( XMLStreamException e )
133         {
134             throw new RoleManagerException( "error parsing redback profile", e );
135         }
136         finally
137         {
138             IOUtils.closeQuietly( inputStreamReader );
139         }
140     }
141
142     @SuppressWarnings("unchecked")
143     public void loadRoleModel( RedbackRoleModel roleModel )
144         throws RoleManagerException
145     {
146         for ( ModelApplication app : roleModel.getApplications() )
147         {
148             if ( !knownResources.containsKey( app.getId() ) )
149             {
150                 loadApplication( app );
151             }
152         }
153
154     }
155
156     public void loadApplication( ModelApplication app )
157         throws RoleManagerException
158     {
159         if ( unblessedModel == null )
160         {
161             unblessedModel = new RedbackRoleModel();
162         }
163
164         unblessedModel.addApplication( app );
165
166         if ( modelValidator.validate( unblessedModel ) )
167         {
168             blessedModel = unblessedModel;
169         }
170         else
171         {
172             StringBuilder stringBuilder = new StringBuilder( "Role Model Validation Errors:" );
173
174             for ( String error : modelValidator.getValidationErrors() )
175             {
176                 stringBuilder.append( error ).append( SystemUtils.LINE_SEPARATOR );
177             }
178
179             log.error( stringBuilder.toString() );
180
181             throw new RoleManagerException(
182                 "Role Model Validation Error " + SystemUtils.LINE_SEPARATOR + stringBuilder.toString() );
183         }
184
185         modelProcessor.process( blessedModel );
186
187         knownResources.put( app.getId(), app );
188     }
189
190     /**
191      * create a role for the given roleName using the resource passed in for
192      * resolving the ${resource} expression
193      */
194     public void createTemplatedRole( String templateId, String resource )
195         throws RoleManagerException
196     {
197         templateProcessor.create( blessedModel, templateId, resource );
198     }
199
200     /**
201      * remove the role corresponding to the role using the resource passed in for resolving the
202      * ${resource} expression
203      */
204     public void removeTemplatedRole( String templateId, String resource )
205         throws RoleManagerException
206     {
207         ModelTemplate template = RoleModelUtils.getModelTemplate( blessedModel, templateId );
208
209         String roleName = template.getNamePrefix() + template.getDelimiter() + resource;
210
211         try
212         {
213             Role role = rbacManager.getRole( roleName );
214
215             for ( UserAssignment assignment : rbacManager.getUserAssignmentsForRoles(
216                 Arrays.asList( role.getName() ) ) )
217             {
218                 assignment.removeRoleName( role );
219                 rbacManager.saveUserAssignment( assignment );
220             }
221
222         }
223         catch ( RbacManagerException e )
224         {
225             throw new RoleManagerException( "unable to remove role", e );
226         }
227
228         templateProcessor.remove( blessedModel, templateId, resource );
229     }
230
231     /**
232      * update the role from templateId from oldResource to newResource
233      * <p/>
234      * NOTE: this requires removal and creation of the role since the jdo store does not tolerate renaming
235      * because of the use of the name as an identifier
236      */
237     public void updateRole( String templateId, String oldResource, String newResource )
238         throws RoleManagerException
239     {
240         // make the new role
241         templateProcessor.create( blessedModel, templateId, newResource );
242
243         ModelTemplate template = RoleModelUtils.getModelTemplate( blessedModel, templateId );
244
245         String oldRoleName = template.getNamePrefix() + template.getDelimiter() + oldResource;
246         String newRoleName = template.getNamePrefix() + template.getDelimiter() + newResource;
247
248         try
249         {
250             Role role = rbacManager.getRole( oldRoleName );
251
252             // remove the user assignments
253             for ( UserAssignment assignment : rbacManager.getUserAssignmentsForRoles(
254                 Arrays.asList( role.getName() ) ) )
255             {
256                 assignment.removeRoleName( oldRoleName );
257                 assignment.addRoleName( newRoleName );
258                 rbacManager.saveUserAssignment( assignment );
259             }
260         }
261         catch ( RbacManagerException e )
262         {
263             throw new RoleManagerException( "unable to update role", e );
264         }
265
266         templateProcessor.remove( blessedModel, templateId, oldResource );
267     }
268
269     public void assignRole( String roleId, String principal )
270         throws RoleManagerException
271     {
272         ModelRole modelRole = RoleModelUtils.getModelRole( blessedModel, roleId );
273
274         if ( modelRole == null )
275         {
276             throw new RoleManagerException( "Unable to assign role: " + roleId + " does not exist." );
277         }
278
279         try
280         {
281             UserAssignment userAssignment;
282
283             if ( rbacManager.userAssignmentExists( principal ) )
284             {
285                 userAssignment = rbacManager.getUserAssignment( principal );
286             }
287             else
288             {
289                 userAssignment = rbacManager.createUserAssignment( principal );
290             }
291
292             userAssignment.addRoleName( modelRole.getName() );
293             rbacManager.saveUserAssignment( userAssignment );
294         }
295         catch ( RbacManagerException e )
296         {
297             throw new RoleManagerException( "Unable to assign role: unable to manage user assignment", e );
298         }
299     }
300
301     public void assignRoleByName( String roleName, String principal )
302         throws RoleManagerException
303     {
304         try
305         {
306             UserAssignment userAssignment;
307
308             if ( rbacManager.userAssignmentExists( principal ) )
309             {
310                 userAssignment = rbacManager.getUserAssignment( principal );
311             }
312             else
313             {
314                 userAssignment = rbacManager.createUserAssignment( principal );
315             }
316
317             if ( !rbacManager.roleExists( roleName ) )
318             {
319                 throw new RoleManagerException( "Unable to assign role: " + roleName + " does not exist." );
320             }
321
322             userAssignment.addRoleName( roleName );
323             rbacManager.saveUserAssignment( userAssignment );
324         }
325         catch ( RbacManagerException e )
326         {
327             throw new RoleManagerException( "Unable to assign role: unable to manage user assignment", e );
328         }
329     }
330
331     public void assignTemplatedRole( String templateId, String resource, String principal )
332         throws RoleManagerException
333     {
334         ModelTemplate modelTemplate = RoleModelUtils.getModelTemplate( blessedModel, templateId );
335
336         if ( modelTemplate == null )
337         {
338             throw new RoleManagerException( "Unable to assign role: " + templateId + " does not exist." );
339         }
340         try
341         {
342             if ( !rbacManager.resourceExists( resource ) )
343             {
344                 Resource newResource = rbacManager.createResource( resource );
345                 rbacManager.saveResource( newResource );
346             }
347
348             UserAssignment userAssignment;
349
350             if ( rbacManager.userAssignmentExists( principal ) )
351             {
352                 userAssignment = rbacManager.getUserAssignment( principal );
353             }
354             else
355             {
356                 userAssignment = rbacManager.createUserAssignment( principal );
357             }
358
359             userAssignment.addRoleName( modelTemplate.getNamePrefix() + modelTemplate.getDelimiter() + resource );
360             rbacManager.saveUserAssignment( userAssignment );
361         }
362         catch ( RbacManagerException e )
363         {
364             throw new RoleManagerException( "Unable to assign role: unable to manage user assignment", e );
365         }
366     }
367
368     public void unassignRole( String roleId, String principal )
369         throws RoleManagerException
370     {
371         ModelRole modelRole = RoleModelUtils.getModelRole( blessedModel, roleId );
372
373         if ( modelRole == null )
374         {
375             throw new RoleManagerException( "Unable to assign role: " + roleId + " does not exist." );
376         }
377
378         try
379         {
380             UserAssignment userAssignment;
381
382             if ( rbacManager.userAssignmentExists( principal ) )
383             {
384                 userAssignment = rbacManager.getUserAssignment( principal );
385             }
386             else
387             {
388                 throw new RoleManagerException(
389                     "UserAssignment for principal " + principal + "does not exist, can't unassign role." );
390             }
391
392             userAssignment.removeRoleName( modelRole.getName() );
393             rbacManager.saveUserAssignment( userAssignment );
394         }
395         catch ( RbacManagerException e )
396         {
397             throw new RoleManagerException( "Unable to unassign role: unable to manage user assignment", e );
398         }
399     }
400
401     public void unassignRoleByName( String roleName, String principal )
402         throws RoleManagerException
403     {
404         try
405         {
406             UserAssignment userAssignment;
407
408             if ( rbacManager.userAssignmentExists( principal ) )
409             {
410                 userAssignment = rbacManager.getUserAssignment( principal );
411             }
412             else
413             {
414                 throw new RoleManagerException(
415                     "UserAssignment for principal " + principal + "does not exist, can't unassign role." );
416             }
417
418             if ( !rbacManager.roleExists( roleName ) )
419             {
420                 throw new RoleManagerException( "Unable to unassign role: " + roleName + " does not exist." );
421             }
422
423             userAssignment.removeRoleName( roleName );
424             rbacManager.saveUserAssignment( userAssignment );
425         }
426         catch ( RbacManagerException e )
427         {
428             throw new RoleManagerException( "Unable to unassign role: unable to manage user assignment", e );
429         }
430     }
431
432     public boolean roleExists( String roleId )
433         throws RoleManagerException
434     {
435         ModelRole modelRole = RoleModelUtils.getModelRole( blessedModel, roleId );
436
437         if ( modelRole == null )
438         {
439             return false;
440         }
441         else
442         {
443             try
444             {
445                 if ( rbacManager.roleExists( modelRole.getName() ) )
446                 {
447                     return true;
448                 }
449                 else
450                 {
451                     // perhaps try and reload the model here?
452                     throw new RoleManagerException(
453                         "breakdown in role management, role exists in configuration but was not created in underlying store" );
454                 }
455             }
456             catch ( RbacManagerException e )
457             {
458                 throw new RoleManagerException( e.getMessage(), e );
459             }
460         }
461     }
462
463     public boolean templatedRoleExists( String templateId, String resource )
464         throws RoleManagerException
465     {
466         ModelTemplate modelTemplate = RoleModelUtils.getModelTemplate( blessedModel, templateId );
467
468         // template not existing is valid to check, it will throw exception on trying to create
469         if ( modelTemplate == null )
470         {
471             return false;
472         }
473         else
474         {
475             try
476             {
477                 if ( rbacManager.roleExists( modelTemplate.getNamePrefix() + modelTemplate.getDelimiter() + resource ) )
478                 {
479                     return true;
480                 }
481                 else
482                 {
483                     return false;
484                 }
485             }
486             catch ( RbacManagerException e )
487             {
488                 throw new RoleManagerException( e.getMessage(), e );
489             }
490         }
491     }
492
493     @PostConstruct
494     public void initialize()
495     {
496
497         StopWatch stopWatch = new StopWatch();
498         stopWatch.start();
499
500         try
501         {
502             URL baseResource = RoleManager.class.getResource( "/META-INF/redback/redback-core.xml" );
503
504             if ( baseResource == null )
505             {
506                 throw new RuntimeException( "unable to initialize role manager, missing redback-core.xml" );
507             }
508
509             loadRoleModel( baseResource );
510
511             Enumeration<URL> enumerator =
512                 RoleManager.class.getClassLoader().getResources( "META-INF/redback/redback.xml" );
513
514             while ( enumerator.hasMoreElements() )
515             {
516                 URL redbackResource = enumerator.nextElement();
517
518                 loadRoleModel( redbackResource );
519             }
520         }
521         catch ( RoleManagerException e )
522         {
523             throw new RuntimeException( "unable to initialize RoleManager", e );
524         }
525         catch ( IOException e )
526         {
527             throw new RuntimeException( "unable to initialize RoleManager, problem with redback.xml loading", e );
528         }
529
530         stopWatch.stop();
531         log.info( "DefaultRoleManager initialize time {}", stopWatch.getTime() );
532     }
533
534     public RedbackRoleModel getModel()
535     {
536         return blessedModel;
537     }
538
539     public void verifyTemplatedRole( String templateId, String resource )
540         throws RoleManagerException
541     {
542         // create also serves as update
543         templateProcessor.create( blessedModel, templateId, resource );
544     }
545
546     public RedbackRoleModel getBlessedModel()
547     {
548         return blessedModel;
549     }
550
551     public void setBlessedModel( RedbackRoleModel blessedModel )
552     {
553         this.blessedModel = blessedModel;
554     }
555
556     public RedbackRoleModel getUnblessedModel()
557     {
558         return unblessedModel;
559     }
560
561     public void setUnblessedModel( RedbackRoleModel unblessedModel )
562     {
563         this.unblessedModel = unblessedModel;
564     }
565
566     public Map<String, ModelApplication> getKnownResources()
567     {
568         return knownResources;
569     }
570
571     public void setKnownResources( Map<String, ModelApplication> knownResources )
572     {
573         this.knownResources = knownResources;
574     }
575
576     public RoleModelValidator getModelValidator()
577     {
578         return modelValidator;
579     }
580
581     public void setModelValidator( RoleModelValidator modelValidator )
582     {
583         this.modelValidator = modelValidator;
584     }
585
586     public RoleModelProcessor getModelProcessor()
587     {
588         return modelProcessor;
589     }
590
591     public void setModelProcessor( RoleModelProcessor modelProcessor )
592     {
593         this.modelProcessor = modelProcessor;
594     }
595
596     public RoleTemplateProcessor getTemplateProcessor()
597     {
598         return templateProcessor;
599     }
600
601     public void setTemplateProcessor( RoleTemplateProcessor templateProcessor )
602     {
603         this.templateProcessor = templateProcessor;
604     }
605
606     public RBACManager getRbacManager()
607     {
608         return rbacManager;
609     }
610
611     public void setRbacManager( RBACManager rbacManager )
612     {
613         this.rbacManager = rbacManager;
614     }
615 }