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

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 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 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 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 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 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 
698     @Override
699     public boolean isFinalImplementation()
700     {
701         return true;
702     }
703 
704     public String getDescriptionKey()
705     {
706         return "archiva.redback.rbacmanager.jdo";
707     }
708 
709     public boolean isReadOnly()
710     {
711         return false;
712     }
713 }