1 package org.codehaus.plexus.redback.rbac.jdo;
4 * Copyright 2005 The Apache Software Foundation.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
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;
44 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
45 * @author Jesse McConnell <jmcconnell@apache.org>
48 @Service( "rBACManager#jdo" )
49 public class JdoRbacManager
50 extends AbstractRBACManager
51 implements RBACManagerListener
56 private boolean enableCache = true;
58 // private static final String ROLE_DETAIL = "role-child-detail";
59 private static final String ROLE_DETAIL = null;
61 // ----------------------------------------------------------------------
63 // ----------------------------------------------------------------------
66 * Creates an implementation specific {@link Role}.
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
72 * @param name the name.
73 * @return the new {@link Role} object with an empty (non-null) {@link Role#getChildRoleNames()} object.
74 * @throws RbacManagerException
76 public Role createRole( String name )
82 role = getRole( name );
84 catch ( RbacManagerException e )
98 public Role saveRole( Role role )
99 throws RbacObjectInvalidException, RbacManagerException
101 RBACObjectAssertions.assertValid( role );
103 return (Role) jdo.saveObject( role, new String[]{ ROLE_DETAIL } );
106 public boolean roleExists( Role role )
108 return jdo.objectExists( role );
111 public boolean roleExists( String name )
115 return jdo.objectExistsById( JdoRole.class, name );
117 catch ( RbacManagerException e )
126 * @throws RbacObjectNotFoundException
127 * @throws RbacManagerException
129 public Role getRole( String roleName )
130 throws RbacObjectNotFoundException, RbacManagerException
132 return (Role) jdo.getObjectById( JdoRole.class, roleName, ROLE_DETAIL );
138 @SuppressWarnings( "unchecked" )
139 public List<Role> getAllRoles()
140 throws RbacManagerException
142 return (List<Role>) jdo.getAllObjects( JdoRole.class );
145 public void removeRole( Role role )
146 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
148 RBACObjectAssertions.assertValid( role );
150 if ( role.isPermanent() )
152 throw new RbacPermanentException( "Unable to delete permanent role [" + role.getName() + "]" );
155 jdo.removeObject( role );
158 public void saveRoles( Collection<Role> roles )
159 throws RbacObjectInvalidException, RbacManagerException
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.
170 PersistenceManager pm = jdo.getPersistenceManager();
171 Transaction tx = pm.currentTransaction();
177 for ( Role role : roles )
179 if ( ( JDOHelper.getObjectId( role ) != null ) && !JDOHelper.isDetached( role ) )
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 );
186 RBACObjectAssertions.assertValid( role );
188 pm.makePersistent( role );
195 jdo.rollbackIfActive( tx );
199 // ----------------------------------------------------------------------
200 // Permission methods
201 // ----------------------------------------------------------------------
204 * Creates an implementation specific {@link Permission}.
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.
210 * @param name the name.
211 * @return the new Permission.
212 * @throws RbacManagerException
214 public Permission createPermission( String name )
215 throws RbacManagerException
217 Permission permission;
221 permission = getPermission( name );
222 log.debug( "Create Permission [{}] Returning Existing.", name );
224 catch ( RbacObjectNotFoundException e )
226 permission = new JdoPermission();
227 permission.setName( name );
228 log.debug( "Create Permission [{}] New JdoPermission.", name );
235 * Creates an implementation specific {@link Permission} with specified {@link Operation},
236 * and {@link Resource} identifiers.
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.
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
248 public Permission createPermission( String name, String operationName, String resourceIdentifier )
249 throws RbacManagerException
251 Permission permission = new JdoPermission();
252 permission.setName( name );
257 operation = getOperation( operationName );
259 catch ( RbacObjectNotFoundException e )
261 operation = new JdoOperation();
262 operation.setName( operationName );
264 permission.setOperation( operation );
269 resource = getResource( resourceIdentifier );
271 catch ( RbacObjectNotFoundException e )
273 resource = new JdoResource();
274 resource.setIdentifier( resourceIdentifier );
276 permission.setResource( resource );
281 public Permission savePermission( Permission permission )
282 throws RbacObjectInvalidException, RbacManagerException
284 RBACObjectAssertions.assertValid( permission );
286 return (Permission) jdo.saveObject( permission, null );
289 public boolean permissionExists( Permission permission )
291 return jdo.objectExists( permission );
294 public boolean permissionExists( String name )
298 return jdo.objectExistsById( JdoPermission.class, name );
300 catch ( RbacManagerException e )
306 public Permission getPermission( String permissionName )
307 throws RbacObjectNotFoundException, RbacManagerException
309 return (Permission) jdo.getObjectById( JdoPermission.class, permissionName, null );
312 @SuppressWarnings( "unchecked" )
313 public List<Permission> getAllPermissions()
314 throws RbacManagerException
316 return (List<Permission>) jdo.getAllObjects( JdoPermission.class );
319 public void removePermission( Permission permission )
320 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
322 RBACObjectAssertions.assertValid( permission );
324 if ( permission.isPermanent() )
326 throw new RbacPermanentException( "Unable to delete permanent permission [" + permission.getName() + "]" );
329 jdo.removeObject( permission );
332 // ----------------------------------------------------------------------
334 // ----------------------------------------------------------------------
337 * Creates an implementation specific {@link Operation}.
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.
343 * @param name the name.
344 * @return the new Operation.
345 * @throws RbacManagerException
347 public Operation createOperation( String name )
348 throws RbacManagerException
354 operation = getOperation( name );
356 catch ( RbacObjectNotFoundException e )
358 operation = new JdoOperation();
359 operation.setName( name );
365 public Operation saveOperation( Operation operation )
366 throws RbacObjectInvalidException, RbacManagerException
368 RBACObjectAssertions.assertValid( operation );
369 return (Operation) jdo.saveObject( operation, null );
372 public boolean operationExists( Operation operation )
374 return jdo.objectExists( operation );
377 public boolean operationExists( String name )
381 return jdo.objectExistsById( JdoOperation.class, name );
383 catch ( RbacManagerException e )
389 public Operation getOperation( String operationName )
390 throws RbacObjectNotFoundException, RbacManagerException
392 return (Operation) jdo.getObjectById( JdoOperation.class, operationName, null );
395 @SuppressWarnings( "unchecked" )
396 public List<Operation> getAllOperations()
397 throws RbacManagerException
399 return (List<Operation>) jdo.getAllObjects( JdoOperation.class );
402 public void removeOperation( Operation operation )
403 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
405 RBACObjectAssertions.assertValid( operation );
407 if ( operation.isPermanent() )
409 throw new RbacPermanentException( "Unable to delete permanent operation [" + operation.getName() + "]" );
412 jdo.removeObject( operation );
415 // ----------------------------------------------------------------------
417 // ----------------------------------------------------------------------
420 * Creates an implementation specific {@link Resource}.
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.
426 * @param identifier the identifier.
427 * @return the new Resource.
428 * @throws RbacManagerException
430 public Resource createResource( String identifier )
431 throws RbacManagerException
437 resource = getResource( identifier );
438 log.debug( "Create Resource [ {} ] Returning Existing.", identifier );
440 catch ( RbacObjectNotFoundException e )
442 resource = new JdoResource();
443 resource.setIdentifier( identifier );
444 log.debug( "Create Resource [ {} ] New JdoResource.", identifier );
450 public Resource saveResource( Resource resource )
451 throws RbacObjectInvalidException, RbacManagerException
453 RBACObjectAssertions.assertValid( resource );
454 return (Resource) jdo.saveObject( resource, null );
457 public boolean resourceExists( Resource resource )
459 return jdo.objectExists( resource );
462 public boolean resourceExists( String identifier )
466 return jdo.objectExistsById( JdoResource.class, identifier );
468 catch ( RbacManagerException e )
474 public Resource getResource( String resourceIdentifier )
475 throws RbacObjectNotFoundException, RbacManagerException
477 return (Resource) jdo.getObjectById( JdoResource.class, resourceIdentifier, null );
480 @SuppressWarnings( "unchecked" )
481 public List<Resource> getAllResources()
482 throws RbacManagerException
484 return (List<Resource>) jdo.getAllObjects( JdoResource.class );
487 public void removeResource( Resource resource )
488 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
490 RBACObjectAssertions.assertValid( resource );
492 if ( resource.isPermanent() )
494 throw new RbacPermanentException(
495 "Unable to delete permanent resource [" + resource.getIdentifier() + "]" );
498 jdo.removeObject( resource );
501 // ----------------------------------------------------------------------
502 // User Assignment methods
503 // ----------------------------------------------------------------------
506 * Creates an implementation specific {@link UserAssignment}.
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.
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
516 public UserAssignment createUserAssignment( String principal )
522 ua = getUserAssignment( principal );
524 catch ( RbacManagerException e )
526 ua = new JdoUserAssignment();
527 ua.setPrincipal( principal );
534 * Method addUserAssignment
536 * @param userAssignment
538 public UserAssignment saveUserAssignment( UserAssignment userAssignment )
539 throws RbacObjectInvalidException, RbacManagerException
541 RBACObjectAssertions.assertValid( "Save User Assignment", userAssignment );
543 fireRbacUserAssignmentSaved( userAssignment );
545 return (UserAssignment) jdo.saveObject( userAssignment, new String[]{ ROLE_DETAIL } );
548 public boolean userAssignmentExists( String principal )
552 return jdo.objectExistsById( JdoUserAssignment.class, principal );
554 catch ( RbacManagerException e )
560 public boolean userAssignmentExists( UserAssignment assignment )
562 return jdo.objectExists( assignment );
565 public UserAssignment getUserAssignment( String principal )
566 throws RbacObjectNotFoundException, RbacManagerException
568 return (UserAssignment) jdo.getObjectById( JdoUserAssignment.class, principal, ROLE_DETAIL );
572 * Method getAssignments
574 @SuppressWarnings( "unchecked" )
575 public List<UserAssignment> getAllUserAssignments()
576 throws RbacManagerException
578 return (List<UserAssignment>) jdo.getAllObjects( JdoUserAssignment.class );
582 * Method getUserAssignmentsForRoles
584 @SuppressWarnings( "unchecked" )
585 public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
586 throws RbacManagerException
588 return (List<UserAssignment>) jdo.getUserAssignmentsForRoles( JdoUserAssignment.class, null, roleNames );
592 * Method removeAssignment
594 * @param userAssignment
596 public void removeUserAssignment( UserAssignment userAssignment )
597 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
599 RBACObjectAssertions.assertValid( userAssignment );
601 if ( userAssignment.isPermanent() )
603 throw new RbacPermanentException(
604 "Unable to delete permanent user assignment [" + userAssignment.getPrincipal() + "]" );
607 fireRbacUserAssignmentRemoved( userAssignment );
609 jdo.removeObject( userAssignment );
612 public void eraseDatabase()
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 );
624 public void initialize()
628 jdo.setListener( this );
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 );
639 public void rbacInit( boolean freshdb )
641 fireRbacInit( freshdb );
644 public void rbacPermissionRemoved( Permission permission )
646 fireRbacPermissionRemoved( permission );
649 public void rbacPermissionSaved( Permission permission )
651 fireRbacPermissionSaved( permission );
654 public void rbacRoleRemoved( Role role )
656 fireRbacRoleRemoved( role );
659 public void rbacRoleSaved( Role role )
661 fireRbacRoleSaved( role );
665 public void rbacUserAssignmentSaved( UserAssignment userAssignment )
667 fireRbacUserAssignmentSaved( userAssignment );
670 public void rbacUserAssignmentRemoved( UserAssignment userAssignment )
672 fireRbacUserAssignmentRemoved( userAssignment );
675 public JdoTool getJdo()
680 public void setJdo( JdoTool jdo )
685 public boolean isEnableCache()
690 public void setEnableCache( boolean enableCache )
692 this.enableCache = enableCache;