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