/** * TNTConcept Easy Enterprise Management by Autentia Real Bussiness Solution S.L. * Copyright (C) 2007 Autentia Real Bussiness Solution S.L. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.autentia.tnt.util; import java.util.Map; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.acls.Acl; import org.acegisecurity.acls.AclService; import org.acegisecurity.acls.NotFoundException; import org.acegisecurity.acls.Permission; import org.acegisecurity.acls.objectidentity.ObjectIdentity; import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategy; import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategyImpl; import org.acegisecurity.acls.sid.Sid; import org.acegisecurity.acls.sid.SidRetrievalStrategy; import org.acegisecurity.acls.sid.SidRetrievalStrategyImpl; import org.acegisecurity.context.SecurityContextHolder; import org.springframework.context.ApplicationContext; import com.autentia.tnt.dao.ITransferObject; import com.autentia.tnt.manager.security.Principal; /** * Utility Spring class * @author ivan */ public class SpringUtils { private static ApplicationContext appCtx; private static AclService aclService; private static ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy; private static SidRetrievalStrategy sidRetrievalStrategy; /** * Configure this class * @param appCtx */ public synchronized static void configureTest( ApplicationContext ctx ) { // Se permite la sobreescritura del contexto para que cada test pueda // disponer de un contexto propio. Tener en cuenta que los tests se ejecutan secuencialmente. // La solución podría dar problemas con ejecuciones concurrentes. appCtx = ctx; } @SuppressWarnings("rawtypes") public synchronized static void configure( ApplicationContext ctx ) { // Do not let configure more than once if( appCtx!=null ) { throw new IllegalStateException("Spring's application context cannot be set more than once"); } // Store application context appCtx = ctx; // Find AclService Map map = appCtx.getBeansOfType(AclService.class); if (map.size() != 1) { throw new IllegalStateException( "Found incorrect number of AclService instances in application context - you must have only have one!" ); } aclService = (AclService) map.values().iterator().next(); // Find SidRetrievalStrategy map = appCtx.getBeansOfType(SidRetrievalStrategy.class); if (map.size() == 0) { sidRetrievalStrategy = new SidRetrievalStrategyImpl(); } else if (map.size() == 1) { sidRetrievalStrategy = (SidRetrievalStrategy) map.values().iterator().next(); } else { throw new IllegalStateException( "Found incorrect number of SidRetrievalStrategy instances in application context - you must have only have one!" ); } // Find ObjectIdentityRetrievalStrategy map = appCtx.getBeansOfType(ObjectIdentityRetrievalStrategy.class); if (map.size() == 0) { objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl(); } else if (map.size() == 1) { objectIdentityRetrievalStrategy = (ObjectIdentityRetrievalStrategy) map.values().iterator().next(); } else { throw new IllegalStateException( "Found incorrect number of ObjectIdentityRetrievalStrategy instances in application context - you must have only have one!" ); } } /** * This class cannot have instances */ private SpringUtils() { } /** * Get a bean defined under Spring by its name. * @param name name of bean * @return the bean or null if it does not exist */ public static Object getSpringBean( String name ) { return appCtx.getBean(name); } /** * Get current principal * @return the current principal as reported by ACEGI */ public static Principal getPrincipal() { return (Principal)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); } /** * Get current principal, but more generic, as Object * @return the current object as reported by ACEGI */ public static Object getPrincipalAsObject() { return SecurityContextHolder.getContext().getAuthentication().getPrincipal(); } /** * Check if an ACL permission is granted for a given domain object * @param dto domain object * @param perm permission to test * @return true if permission is granted */ public static boolean isAclPermissionGranted( ITransferObject dto, Permission perm ) { Sid[] sids = sidRetrievalStrategy.getSids(SecurityContextHolder.getContext().getAuthentication()); ObjectIdentity oid = objectIdentityRetrievalStrategy.getObjectIdentity(dto); // Obtain aclEntrys applying to the current Authentication object try { Acl acl = aclService.readAclById(oid, sids); if (acl.isGranted( new Permission[] { perm }, sids, false ) ) { return true; } else { return false; } } catch (NotFoundException nfe) { return false; } } /** * Test if a given role permission is granted to current user. * @param grantedAuthority the permission to test * @return true if current user holds permission */ public static boolean isRolePermissionGranted( GrantedAuthority perm ) { boolean isGranted = true; try{ Principal principal = getPrincipal(); isGranted = principal.hasAuthority( perm ); } catch (Exception nfe){ isGranted = false; } return isGranted; } }