Add new managers
For creating/changing/deleting ACLs from business code (e.g. allowing a user to modify ACLs of his objects), a manager is also needed.
Interface
package org.appfuse.service; import java.io.Serializable; import java.util.List; import org.acegisecurity.Authentication; import org.acegisecurity.acl.AclProvider; import org.appfuse.model.acl.BaseObjectAclAware; import org.appfuse.model.acl.BasicAclObjectIdentity; import org.appfuse.model.acl.BasicAclPermission; public interface BasicAclProviderManager extends AclProvider { /** * Loads a list of permissions a User represented by auth * has on an object domainInstance * * @param domainInstance The Object to load permissions for * @param authentication Representing an user with his authorities * @return List of permissions */ public List<BasicAclPermission> getBasicPermissions(Object domainInstance, Authentication authentication); /** * Returns all permissions defined on on object represented by * the domainInstance * * @param domainInstance Representing the object * @return List of permissions */ public List getBasicPermissions(Object domainInstance); /** * Deletes all permissions owned by an user with the username * * @param username Username of the user */ public void deleteBasicAclPermissions(String username); /** * Deletes the object identity of an obejct of class clazz * with the given id * * @param clazz Class of the objet identity to delete * @param id ID of the objet identity to delete */ public void deleteBasicAclObjectIdentity(Class clazz, Serializable id); /** * Creates a new Object identity * * @param baseObject Object to create object identity for * @param parent Parent object of the new objectidentity * @return the new Object identity */ public BasicAclObjectIdentity createBasicObjectIndenty(BaseObjectAclAware baseObject, BasicAclObjectIdentity parent); /** * Creates a new Obejct Identity * * @param baseObject Object to create ObjectIdentity for * @return the new Object identity */ public BasicAclObjectIdentity createBasicObjectIndentity(BaseObjectAclAware baseObject); /** * Creates a new permission for the active user * * @param basicAclObjectIdentity Object identity to add a new permission for * @param mask Integer representing the rights of the permission */ public void createPermissionForCurrentUser(BasicAclObjectIdentity basicAclObjectIdentity, int mask); /** * Create a new permission for a specific user * * @param basicAclObjectIdentity Object identity to create a new permission for * @param mask Integer representing the value of the permission (@see SimpleACLEntry) * @param username Username of the user to add the permission for */ public void createPermissionForUser(BasicAclObjectIdentity basicAclObjectIdentity, int mask,String username); /** * Create a new permission for a specific user * * @param basicAclObjectIdentity Object identity to create a new permission for * @param mask Integer representing the value of the permission (@see SimpleACLEntry) * @param rolename Name of the role to add the permission for */ public void createPermissionForRole(BasicAclObjectIdentity basicAclObjectIdentity, int mask,String rolename); }
Implementation
package org.appfuse.service.impl; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.basic.AclObjectIdentityAware; import org.acegisecurity.acl.basic.BasicAclEntry; import org.acegisecurity.acl.basic.BasicAclProvider; import org.acegisecurity.acl.basic.SimpleAclEntry; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.userdetails.UserDetails; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.appfuse.dao.BasicAclObjectIdentityDao; import org.appfuse.dao.BasicAclPermissionDao; import org.appfuse.dao.UserDao; import org.appfuse.model.User; import org.appfuse.model.acl.BaseObjectAclAware; import org.appfuse.model.acl.BasicAclObjectIdentity; import org.appfuse.model.acl.BasicAclPermission; import org.appfuse.service.BasicAclProviderManager; import org.hibernate.Hibernate; import org.springframework.util.Assert; public class BasicAclProviderManagerImpl extends BasicAclProvider implements BasicAclProviderManager { protected final Log log = LogFactory.getLog(getClass()); protected BasicAclPermissionDao basicAclPermissionDao; protected BasicAclObjectIdentityDao basicAclObjectIdentityDao; protected UserDao userDao; public void setBasicAclObjectIdentityDao(BasicAclObjectIdentityDao basicAclObjectIdentityDao) { this.basicAclObjectIdentityDao = basicAclObjectIdentityDao; } public void setBasicAclPermissionDao(BasicAclPermissionDao basicAclPermissionDao) { this.basicAclPermissionDao = basicAclPermissionDao; setBasicAclDao(basicAclPermissionDao); } public void setUserDao(UserDao userDao) { this.userDao = userDao; } /* (non-Javadoc) * @see org.acegisecurity.acl.basic.BasicAclProvider#getAcls(java.lang.Object, org.acegisecurity.Authentication) */ @Override public AclEntry[] getAcls(Object domainInstance, Authentication authentication) { log.debug("Entering getAcls(domainInstance[" + domainInstance + "], authentication[" + authentication + "])"); List<BasicAclPermission> permissions = getBasicPermissions(domainInstance, authentication); AclEntry[] result = (BasicAclEntry[]) permissions.toArray(new BasicAclEntry[]{}); if (result.length > 0) { log.debug("Found [" + result.length + "] ACLs..."); } else { log.debug("No permissions found!"); } return result; } /* (non-Javadoc) * @see org.acegisecurity.acl.basic.BasicAclProvider#getAcls(java.lang.Object) */ @Override public AclEntry[] getAcls(Object domainInstance) { AclEntry[] result = super.getAcls(domainInstance); return result; } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#getBasicPermissions(java.lang.Object) */ public List getBasicPermissions(Object domainInstance) { if (domainInstance instanceof AclObjectIdentityAware) { AclObjectIdentityAware aclOidAware = (AclObjectIdentityAware) domainInstance; return basicAclPermissionDao.getBasicAclPermissions( ((BasicAclObjectIdentity) aclOidAware.getAclObjectIdentity()).getObjectIdentity()); } return null; } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#getBasicPermissions(java.lang.Object, org.acegisecurity.Authentication) */ public List<BasicAclPermission> getBasicPermissions(Object domainInstance,Authentication authentication) { BaseObjectAclAware baseObject = (BaseObjectAclAware) domainInstance; Set<BasicAclPermission> permissions = basicAclPermissionDao.getBasicAclPermissions(createOIDKey(baseObject), authentication); List<BasicAclPermission> toReturn = new ArrayList<BasicAclPermission>(); toReturn.addAll(permissions); return toReturn; } /** * Returns a list of permissions for an Object and user * * @param objectIdentity Identity of the Object * @param username Username of the user * @return List of permissions */ public List getBasicPermissionsByOid(String objectIdentity, String username) { return basicAclPermissionDao.getBasicAclPermissions(objectIdentity,username); } /* (non-Javadoc) * @see org.acegisecurity.acl.basic.BasicAclProvider#supports(java.lang.Object) */ @Override public boolean supports(Object domainInstance) { return domainInstance instanceof BaseObjectAclAware; } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#createBasicObjectIndentity(org.appfuse.model.acl.BaseObjectAclAware) */ public BasicAclObjectIdentity createBasicObjectIndentity(BaseObjectAclAware baseObject) { return createBasicObjectIndenty(baseObject, null); } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#createBasicObjectIndenty(org.appfuse.model.acl.BaseObjectAclAware, org.appfuse.model.acl.BasicAclObjectIdentity) */ public BasicAclObjectIdentity createBasicObjectIndenty(BaseObjectAclAware baseObject, BasicAclObjectIdentity parent) { BasicAclObjectIdentity basicAclObjectIdentity = new BasicAclObjectIdentity(); basicAclObjectIdentity.setObjectIdentity(createOIDKey(baseObject)); basicAclObjectIdentity.setAclClass(SimpleAclEntry.class.getName()); basicAclObjectIdentity.setParentObject(parent); basicAclObjectIdentityDao.saveBasicAclObjectIdentity(basicAclObjectIdentity); return basicAclObjectIdentity; } /** * Creates a new permission * * @param bo Object to create a new permission for * @param mask Integer representing the rights of the permission * @param auth Authority to add the new permission * @return Object identity with the new permission */ protected BasicAclObjectIdentity createBasicObjectIdentityAndPermission(BaseObjectAclAware bo, int mask, GrantedAuthority auth) { BasicAclObjectIdentity ident = createBasicObjectIndentity(bo); createPermission(ident, mask, auth); return ident; } /** * Creates a new permission * * @param bo Object to create a new permission for * @param mask Integer representing the rights of the permission * @param user User to create the permission for * @return Object identity with the new permission */ protected BasicAclObjectIdentity createBasicObjectIdentityAndPermission(BaseObjectAclAware bo, int mask, User user) { BasicAclObjectIdentity ident = createBasicObjectIndentity(bo); createPermission(ident, mask, user); return ident; } /** * Creates a new permission * * @param bo Object to create a new permission for * @param mask Integer representing the rights of the permission * @return the Object identity with the new permission */ protected BasicAclObjectIdentity createBOIDAndPermForCurrentUser(BaseObjectAclAware bo, int mask) { BasicAclObjectIdentity ident = createBasicObjectIndentity(bo); UserDetails user = currentUser(); createPermission(ident, mask, user); return ident; } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#createPermissionForCurrentUser(org.appfuse.model.acl.BasicAclObjectIdentity, int) */ public void createPermissionForCurrentUser(BasicAclObjectIdentity basicAclObjectIdentity, int mask) { UserDetails user = currentUser(); createPermission(basicAclObjectIdentity, mask, user); } /** * Create a new permission * * @param basicAclObjectIdentity Object identity to create a new permission for * @param mask Integer representing the value of the permission (@see SimpleACLEntry) * @param user User to add the permission for */ protected void createPermission(BasicAclObjectIdentity basicAclObjectIdentity, int mask, UserDetails user) { createPermissionForUser(basicAclObjectIdentity, mask, user.getUsername()); } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#createPermissionForUser(org.appfuse.model.acl.BasicAclObjectIdentity, int, java.lang.String) */ public void createPermissionForUser(BasicAclObjectIdentity basicAclObjectIdentity, int mask,String username) { BasicAclPermission basicACLPermission = new BasicAclPermission(); basicACLPermission.setAclObjectIdentity(basicAclObjectIdentity); basicACLPermission.setMask(mask); basicACLPermission.setRecipient(username); basicAclPermissionDao.saveBasicAclPermission(basicACLPermission); } /** * Creates a new permission * * @param basicAclObjectIdentity Object identity to create a new permission for * @param mask Integer representing the value of the permission (@see SimpleACLEntry) * @param authority Authority to add the permission for */ protected void createPermission(BasicAclObjectIdentity basicAclObjectIdentity, int mask,GrantedAuthority authority) { createPermissionForRole(basicAclObjectIdentity,mask,authority.getAuthority()); } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#createPermissionForRole(org.appfuse.model.acl.BasicAclObjectIdentity, int, java.lang.String) */ public void createPermissionForRole(BasicAclObjectIdentity basicAclObjectIdentity, int mask,String rolename) { BasicAclPermission basicACLPermission = new BasicAclPermission(); basicACLPermission.setAclObjectIdentity(basicAclObjectIdentity); basicACLPermission.setMask(mask); basicACLPermission.setRecipient(rolename); basicAclPermissionDao.saveBasicAclPermission(basicACLPermission); } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#deleteBasicAclObjectIdentity(java.lang.Class, java.io.Serializable) */ public void deleteBasicAclObjectIdentity(Class clazz, Serializable id) { BasicAclObjectIdentity ident = basicAclObjectIdentityDao.getBasicAclObjectIdentity(createOIDKey(clazz, id)); basicAclObjectIdentityDao.deleteBasicAclObjectIdentity(ident.getId()); } /** * Creates the object identifier * * @param clazz Class of the object * @param id pimary key of the object * @return String reresenting the object */ protected String createOIDKey(Class clazz, Serializable id) { String key = null; if (id == null) { key = clazz.getName(); } else { key = clazz.getName() + ":" + id; } log.debug("OID key: " + key); return key; } protected String createOIDKey(BaseObjectAclAware baseObjectAclAware) { return createOIDKey(Hibernate.getClass(baseObjectAclAware), baseObjectAclAware.getUniqueKey()); } /* (non-Javadoc) * @see org.appfuse.service.acl.BasicAclProviderManager#deleteBasicAclPermissions(java.lang.String) */ public void deleteBasicAclPermissions(String username) { List perms = basicAclPermissionDao.getBasicAclPermissionsByUsername(username); // TODO: Convert to Batch-query, will be slow with many objects for (Iterator iter = perms.iterator(); iter.hasNext(); ) { BasicAclPermission perm = (BasicAclPermission) iter.next(); BasicAclObjectIdentity oid = (BasicAclObjectIdentity) perm.getAclObjectIdentity(); oid.getPermissions().remove(perm); basicAclObjectIdentityDao.saveBasicAclObjectIdentity(oid); basicAclPermissionDao.deleteBasicAclPermission(perm.getId()); } } /** * Gets the currently active user * * @return The active user */ protected UserDetails currentUser() { SecurityContext ctx = SecurityContextHolder.getContext(); Assert.notNull(ctx); return (UserDetails) ctx.getAuthentication().getPrincipal(); } /** * Loads the object identity for an obejct * * @param boaa Object to load identity for * @return Object identity of the object */ protected BasicAclObjectIdentity getBasicAclObjectIdentity(BaseObjectAclAware boaa) { return basicAclObjectIdentityDao.getBasicAclObjectIdentity(createOIDKey(boaa.getClass(), boaa.getUniqueKey())); } }
Defining the manager in the context
The manager definition, just like the DAO's, has to be added to the file applicationContext.xml.
<bean id="basicAclProviderManager" class="org.appfuse.service.impl.BasicAclProviderManagerImpl"> <property name="basicAclObjectIdentityDao" ref="basicAclObjectIdentityDao"/> <property name="basicAclPermissionDao" ref="basicAclPermissionDao"/> <property name="userDao" ref="userDao"/> </bean>