]> source.dussan.org Git - archiva.git/blob
ae52d209b59470ae52f1f0f7cda2f7f2ed89897a
[archiva.git] /
1 package org.apache.archiva.redback.rbac.jdo;
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.AbstractRBACManager;
23 import org.apache.archiva.redback.rbac.Operation;
24 import org.apache.archiva.redback.rbac.RBACManagerListener;
25 import org.apache.archiva.redback.rbac.RbacManagerException;
26 import org.apache.archiva.redback.rbac.RbacObjectInvalidException;
27 import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
28 import org.apache.archiva.redback.rbac.RbacPermanentException;
29 import org.apache.archiva.redback.rbac.Resource;
30 import org.apache.archiva.redback.rbac.Role;
31 import org.apache.archiva.redback.rbac.UserAssignment;
32 import org.apache.archiva.redback.rbac.Permission;
33 import org.apache.archiva.redback.rbac.RBACObjectAssertions;
34 import org.springframework.stereotype.Service;
35
36 import javax.annotation.PostConstruct;
37 import javax.inject.Inject;
38 import javax.jdo.JDOHelper;
39 import javax.jdo.PersistenceManager;
40 import javax.jdo.Transaction;
41 import java.util.Collection;
42 import java.util.List;
43
44 /**
45  * JdoRbacManager:
46  *
47  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
48  * @author Jesse McConnell <jmcconnell@apache.org>
49  *
50  */
51 @Service( "rbacManager#jdo" )
52 public class JdoRbacManager
53     extends AbstractRBACManager
54     implements RBACManagerListener
55 {
56     @Inject
57     private JdoTool jdo;
58
59     private boolean enableCache = true;
60
61     // private static final String ROLE_DETAIL = "role-child-detail";
62     private static final String ROLE_DETAIL = null;
63
64     // ----------------------------------------------------------------------
65     // Role methods
66     // ----------------------------------------------------------------------
67
68     /**
69      * Creates an implementation specific {@link Role}.
70      * <p/>
71      * Note: this method does not add the {@link Role} to the underlying store.
72      * a call to {@link #saveRole(Role)} is required to track the role created with this
73      * method call.
74      *
75      * @param name the name.
76      * @return the new {@link Role} object with an empty (non-null) {@link Role#getChildRoleNames()} object.
77      * @throws RbacManagerException
78      */
79     public Role createRole( String name )
80     {
81         Role role;
82
83         try
84         {
85             role = getRole( name );
86         }
87         catch ( RbacManagerException e )
88         {
89             role = new JdoRole();
90             role.setName( name );
91         }
92
93         return role;
94     }
95
96     /**
97      * Method addRole
98      *
99      * @param role
100      */
101     public Role saveRole( Role role )
102         throws RbacObjectInvalidException, RbacManagerException
103     {
104         RBACObjectAssertions.assertValid( role );
105
106         return (Role) jdo.saveObject( role, new String[]{ ROLE_DETAIL } );
107     }
108
109     public boolean roleExists( Role role )
110     {
111         return jdo.objectExists( role );
112     }
113
114     public boolean roleExists( String name )
115     {
116         try
117         {
118             return jdo.objectExistsById( JdoRole.class, name );
119         }
120         catch ( RbacManagerException e )
121         {
122             return false;
123         }
124     }
125
126     /**
127      * @param roleName
128      * @return
129      * @throws RbacObjectNotFoundException
130      * @throws RbacManagerException
131      */
132     public Role getRole( String roleName )
133         throws RbacObjectNotFoundException, RbacManagerException
134     {
135         return jdo.getObjectById( JdoRole.class, roleName, ROLE_DETAIL );
136     }
137
138     /**
139      * Method getRoles
140      */
141     @SuppressWarnings( "unchecked" )
142     public List<Role> getAllRoles()
143         throws RbacManagerException
144     {
145         return (List<Role>) jdo.getAllObjects( JdoRole.class );
146     }
147
148     public void removeRole( Role role )
149         throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
150     {
151         RBACObjectAssertions.assertValid( role );
152
153         if ( role.isPermanent() )
154         {
155             throw new RbacPermanentException( "Unable to delete permanent role [" + role.getName() + "]" );
156         }
157
158         jdo.removeObject( role );
159     }
160
161     public void saveRoles( Collection<Role> roles )
162         throws RbacObjectInvalidException, RbacManagerException
163     {
164         if ( roles == null )
165         {
166             // Nothing to do.
167             return;
168         }
169
170         // This is done in JdoRbacManager as opposed to JdoTool as we need to assertValid() on each role and
171         // also wrap the entire collection into a single atomic save/makePersistent.
172
173         PersistenceManager pm = jdo.getPersistenceManager();
174         Transaction tx = pm.currentTransaction();
175
176         try
177         {
178             tx.begin();
179
180             for ( Role role : roles )
181             {
182                 if ( ( JDOHelper.getObjectId( role ) != null ) && !JDOHelper.isDetached( role ) )
183                 {
184                     // This is a fatal error that means we need to fix our code.
185                     // Leave it as a JDOUserException, it's intentional.
186                     throw new RbacManagerException( "Existing Role is not detached: " + role );
187                 }
188
189                 RBACObjectAssertions.assertValid( role );
190
191                 pm.makePersistent( role );
192             }
193
194             tx.commit();
195         }
196         finally
197         {
198             jdo.rollbackIfActive( tx );
199         }
200     }
201
202     // ----------------------------------------------------------------------
203     // Permission methods
204     // ----------------------------------------------------------------------
205
206     /**
207      * Creates an implementation specific {@link Permission}.
208      * <p/>
209      * Note: this method does not add the {@link Permission} to the underlying store.
210      * a call to {@link #savePermission(Permission)} is required to track the permission created
211      * with this method call.
212      *
213      * @param name the name.
214      * @return the new Permission.
215      * @throws RbacManagerException
216      */
217     public Permission createPermission( String name )
218         throws RbacManagerException
219     {
220         Permission permission;
221
222         try
223         {
224             permission = getPermission( name );
225             log.debug( "Create Permission [{}] Returning Existing.", name );
226         }
227         catch ( RbacObjectNotFoundException e )
228         {
229             permission = new JdoPermission();
230             permission.setName( name );
231             log.debug( "Create Permission [{}] New JdoPermission.", name );
232         }
233
234         return permission;
235     }
236
237     /**
238      * Creates an implementation specific {@link Permission} with specified {@link Operation},
239      * and {@link Resource} identifiers.
240      * <p/>
241      * Note: this method does not add the Permission, Operation, or Resource to the underlying store.
242      * a call to {@link #savePermission(Permission)} is required to track the permission, operation,
243      * or resource created with this method call.
244      *
245      * @param name               the name.
246      * @param operationName      the {@link Operation#setName(String)} value
247      * @param resourceIdentifier the {@link Resource#setIdentifier(String)} value
248      * @return the new Permission.
249      * @throws RbacManagerException
250      */
251     public Permission createPermission( String name, String operationName, String resourceIdentifier )
252         throws RbacManagerException
253     {
254         Permission permission = new JdoPermission();
255         permission.setName( name );
256
257         Operation operation;
258         try
259         {
260             operation = getOperation( operationName );
261         }
262         catch ( RbacObjectNotFoundException e )
263         {
264             operation = new JdoOperation();
265             operation.setName( operationName );
266         }
267         permission.setOperation( operation );
268
269         Resource resource;
270         try
271         {
272             resource = getResource( resourceIdentifier );
273         }
274         catch ( RbacObjectNotFoundException e )
275         {
276             resource = new JdoResource();
277             resource.setIdentifier( resourceIdentifier );
278         }
279         permission.setResource( resource );
280
281         return permission;
282     }
283
284     public Permission savePermission( Permission permission )
285         throws RbacObjectInvalidException, RbacManagerException
286     {
287         RBACObjectAssertions.assertValid( permission );
288
289         return (Permission) jdo.saveObject( permission, null );
290     }
291
292     public boolean permissionExists( Permission permission )
293     {
294         return jdo.objectExists( permission );
295     }
296
297     public boolean permissionExists( String name )
298     {
299         try
300         {
301             return jdo.objectExistsById( JdoPermission.class, name );
302         }
303         catch ( RbacManagerException e )
304         {
305             return false;
306         }
307     }
308
309     public Permission getPermission( String permissionName )
310         throws RbacObjectNotFoundException, RbacManagerException
311     {
312         return jdo.getObjectById( JdoPermission.class, permissionName, null );
313     }
314
315     @SuppressWarnings( "unchecked" )
316     public List<Permission> getAllPermissions()
317         throws RbacManagerException
318     {
319         return (List<Permission>) jdo.getAllObjects( JdoPermission.class );
320     }
321
322     public void removePermission( Permission permission )
323         throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
324     {
325         RBACObjectAssertions.assertValid( permission );
326
327         if ( permission.isPermanent() )
328         {
329             throw new RbacPermanentException( "Unable to delete permanent permission [" + permission.getName() + "]" );
330         }
331
332         jdo.removeObject( permission );
333     }
334
335     // ----------------------------------------------------------------------
336     // Operation methods
337     // ----------------------------------------------------------------------
338
339     /**
340      * Creates an implementation specific {@link Operation}.
341      * <p/>
342      * Note: this method does not add the {@link Operation} to the underlying store.
343      * a call to {@link #saveOperation(Operation)} is required to track the operation created
344      * with this method call.
345      *
346      * @param name the name.
347      * @return the new Operation.
348      * @throws RbacManagerException
349      */
350     public Operation createOperation( String name )
351         throws RbacManagerException
352     {
353         Operation operation;
354
355         try
356         {
357             operation = getOperation( name );
358         }
359         catch ( RbacObjectNotFoundException e )
360         {
361             operation = new JdoOperation();
362             operation.setName( name );
363         }
364
365         return operation;
366     }
367
368     public Operation saveOperation( Operation operation )
369         throws RbacObjectInvalidException, RbacManagerException
370     {
371         RBACObjectAssertions.assertValid( operation );
372         return (Operation) jdo.saveObject( operation, null );
373     }
374
375     public boolean operationExists( Operation operation )
376     {
377         return jdo.objectExists( operation );
378     }
379
380     public boolean operationExists( String name )
381     {
382         try
383         {
384             return jdo.objectExistsById( JdoOperation.class, name );
385         }
386         catch ( RbacManagerException e )
387         {
388             return false;
389         }
390     }
391
392     public Operation getOperation( String operationName )
393         throws RbacObjectNotFoundException, RbacManagerException
394     {
395         return jdo.getObjectById( JdoOperation.class, operationName, null );
396     }
397
398     @SuppressWarnings( "unchecked" )
399     public List<Operation> getAllOperations()
400         throws RbacManagerException
401     {
402         return (List<Operation>) jdo.getAllObjects( JdoOperation.class );
403     }
404
405     public void removeOperation( Operation operation )
406         throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
407     {
408         RBACObjectAssertions.assertValid( operation );
409
410         if ( operation.isPermanent() )
411         {
412             throw new RbacPermanentException( "Unable to delete permanent operation [" + operation.getName() + "]" );
413         }
414
415         jdo.removeObject( operation );
416     }
417
418     // ----------------------------------------------------------------------
419     // Resource methods
420     // ----------------------------------------------------------------------
421
422     /**
423      * Creates an implementation specific {@link Resource}.
424      * <p/>
425      * Note: this method does not add the {@link Resource} to the underlying store.
426      * a call to {@link #saveResource(Resource)} is required to track the resource created
427      * with this method call.
428      *
429      * @param identifier the identifier.
430      * @return the new Resource.
431      * @throws RbacManagerException
432      */
433     public Resource createResource( String identifier )
434         throws RbacManagerException
435     {
436         Resource resource;
437
438         try
439         {
440             resource = getResource( identifier );
441             log.debug( "Create Resource [ {} ] Returning Existing.", identifier );
442         }
443         catch ( RbacObjectNotFoundException e )
444         {
445             resource = new JdoResource();
446             resource.setIdentifier( identifier );
447             log.debug( "Create Resource [ {} ] New JdoResource.", identifier );
448         }
449
450         return resource;
451     }
452
453     public Resource saveResource( Resource resource )
454         throws RbacObjectInvalidException, RbacManagerException
455     {
456         RBACObjectAssertions.assertValid( resource );
457         return (Resource) jdo.saveObject( resource, null );
458     }
459
460     public boolean resourceExists( Resource resource )
461     {
462         return jdo.objectExists( resource );
463     }
464
465     public boolean resourceExists( String identifier )
466     {
467         try
468         {
469             return jdo.objectExistsById( JdoResource.class, identifier );
470         }
471         catch ( RbacManagerException e )
472         {
473             return false;
474         }
475     }
476
477     public Resource getResource( String resourceIdentifier )
478         throws RbacObjectNotFoundException, RbacManagerException
479     {
480         return jdo.getObjectById( JdoResource.class, resourceIdentifier, null );
481     }
482
483     @SuppressWarnings( "unchecked" )
484     public List<Resource> getAllResources()
485         throws RbacManagerException
486     {
487         return (List<Resource>) jdo.getAllObjects( JdoResource.class );
488     }
489
490     public void removeResource( Resource resource )
491         throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
492     {
493         RBACObjectAssertions.assertValid( resource );
494
495         if ( resource.isPermanent() )
496         {
497             throw new RbacPermanentException(
498                 "Unable to delete permanent resource [" + resource.getIdentifier() + "]" );
499         }
500
501         jdo.removeObject( resource );
502     }
503
504     // ----------------------------------------------------------------------
505     // User Assignment methods
506     // ----------------------------------------------------------------------
507
508     /**
509      * Creates an implementation specific {@link UserAssignment}.
510      * <p/>
511      * Note: this method does not add the {@link UserAssignment} to the underlying store.
512      * a call to {@link #saveUserAssignment(UserAssignment)} is required to track the user
513      * assignment created with this method call.
514      *
515      * @param principal the principal reference to the user.
516      * @return the new UserAssignment with an empty (non-null) {@link UserAssignment#getRoleNames()} object.
517      * @throws RbacManagerException
518      */
519     public UserAssignment createUserAssignment( String principal )
520     {
521         UserAssignment ua;
522
523         try
524         {
525             ua = getUserAssignment( principal );
526         }
527         catch ( RbacManagerException e )
528         {
529             ua = new JdoUserAssignment();
530             ua.setPrincipal( principal );
531         }
532
533         return ua;
534     }
535
536     /**
537      * Method addUserAssignment
538      *
539      * @param userAssignment
540      */
541     public UserAssignment saveUserAssignment( UserAssignment userAssignment )
542         throws RbacObjectInvalidException, RbacManagerException
543     {
544         RBACObjectAssertions.assertValid( "Save User Assignment", userAssignment );
545
546         fireRbacUserAssignmentSaved( userAssignment );
547
548         return (UserAssignment) jdo.saveObject( userAssignment, new String[]{ ROLE_DETAIL } );
549     }
550
551     public boolean userAssignmentExists( String principal )
552     {
553         try
554         {
555             return jdo.objectExistsById( JdoUserAssignment.class, principal );
556         }
557         catch ( RbacManagerException e )
558         {
559             return false;
560         }
561     }
562
563     public boolean userAssignmentExists( UserAssignment assignment )
564     {
565         return jdo.objectExists( assignment );
566     }
567
568     public UserAssignment getUserAssignment( String principal )
569         throws RbacObjectNotFoundException, RbacManagerException
570     {
571         return jdo.getObjectById( JdoUserAssignment.class, principal, ROLE_DETAIL );
572     }
573
574     /**
575      * Method getAssignments
576      */
577     @SuppressWarnings( "unchecked" )
578     public List<UserAssignment> getAllUserAssignments()
579         throws RbacManagerException
580     {
581         return (List<UserAssignment>) jdo.getAllObjects( JdoUserAssignment.class );
582     }
583
584     /**
585      * Method getUserAssignmentsForRoles
586      */
587     @SuppressWarnings( "unchecked" )
588     public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
589         throws RbacManagerException
590     {
591         return (List<UserAssignment>) jdo.getUserAssignmentsForRoles( JdoUserAssignment.class, null, roleNames );
592     }
593
594     /**
595      * Method removeAssignment
596      *
597      * @param userAssignment
598      */
599     public void removeUserAssignment( UserAssignment userAssignment )
600         throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
601     {
602         RBACObjectAssertions.assertValid( userAssignment );
603
604         if ( userAssignment.isPermanent() )
605         {
606             throw new RbacPermanentException(
607                 "Unable to delete permanent user assignment [" + userAssignment.getPrincipal() + "]" );
608         }
609
610         fireRbacUserAssignmentRemoved( userAssignment );
611
612         jdo.removeObject( userAssignment );
613     }
614
615     public void eraseDatabase()
616     {
617         // Must delete in order so that FK constraints don't get violated
618         jdo.removeAll( JdoRole.class );
619         jdo.removeAll( JdoPermission.class );
620         jdo.removeAll( JdoOperation.class );
621         jdo.removeAll( JdoResource.class );
622         jdo.removeAll( JdoUserAssignment.class );
623         jdo.removeAll( RbacJdoModelModelloMetadata.class );
624     }
625
626     @PostConstruct
627     public void initialize()
628     {
629         super.initialize();
630
631         jdo.setListener( this );
632         if ( enableCache )
633         {
634             jdo.enableCache( JdoRole.class );
635             jdo.enableCache( JdoOperation.class );
636             jdo.enableCache( JdoResource.class );
637             jdo.enableCache( JdoUserAssignment.class );
638             jdo.enableCache( JdoPermission.class );
639         }
640     }
641
642     public void rbacInit( boolean freshdb )
643     {
644         fireRbacInit( freshdb );
645     }
646
647     public void rbacPermissionRemoved( Permission permission )
648     {
649         fireRbacPermissionRemoved( permission );
650     }
651
652     public void rbacPermissionSaved( Permission permission )
653     {
654         fireRbacPermissionSaved( permission );
655     }
656
657     public void rbacRoleRemoved( Role role )
658     {
659         fireRbacRoleRemoved( role );
660     }
661
662     public void rbacRoleSaved( Role role )
663     {
664         fireRbacRoleSaved( role );
665     }
666
667
668     public void rbacUserAssignmentSaved( UserAssignment userAssignment )
669     {
670         fireRbacUserAssignmentSaved( userAssignment );
671     }
672
673     public void rbacUserAssignmentRemoved( UserAssignment userAssignment )
674     {
675         fireRbacUserAssignmentRemoved( userAssignment );
676     }
677
678     public JdoTool getJdo()
679     {
680         return jdo;
681     }
682
683     public void setJdo( JdoTool jdo )
684     {
685         this.jdo = jdo;
686     }
687
688     public boolean isEnableCache()
689     {
690         return enableCache;
691     }
692
693     public void setEnableCache( boolean enableCache )
694     {
695         this.enableCache = enableCache;
696     }
697 }