Index: topia-service/src/java/org/codelutin/topia/taas/TaasService.java diff -u topia-service/src/java/org/codelutin/topia/taas/TaasService.java:1.8 topia-service/src/java/org/codelutin/topia/taas/TaasService.java:1.9 --- topia-service/src/java/org/codelutin/topia/taas/TaasService.java:1.8 Tue Dec 18 11:27:42 2007 +++ topia-service/src/java/org/codelutin/topia/taas/TaasService.java Thu Dec 20 14:23:52 2007 @@ -1,40 +1,42 @@ /* *##% -* Copyright (C) 2002, 2003, 2004, 2005 Code Lutin, -* Cédric Pineau, Benjamin Poussin, -* -* -* 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 2 -* of the License, or (at your option) any later version. -* -* 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, write to the Free Software -* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*##%*/ + * Copyright (C) 2002, 2003, 2004, 2005 Code Lutin, + * Cédric Pineau, Benjamin Poussin, + * + * + * 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 2 + * of the License, or (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ /* * -* TopiaSecurityVetoableListener.java -* -* Created: 10 févr. 2006 -* -* @author Arnaud Thimel -* @version $Revision: 1.8 $ -* -* Mise a jour: $Date: 2007-12-18 11:27:42 $ -* par : $Author: ruchaud $ -*/ + * TopiaSecurityVetoableListener.java + * + * Created: 10 févr. 2006 + * + * @author Arnaud Thimel + * @version $Revision: 1.9 $ + * + * Mise a jour: $Date: 2007-12-20 14:23:52 $ + * par : $Author: ruchaud $ + */ package org.codelutin.topia.taas; import java.lang.reflect.Constructor; import java.security.AccessController; import java.security.Permission; +import java.util.Collection; +import java.util.Iterator; import java.util.List; import javax.security.auth.Subject; @@ -42,8 +44,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.codelutin.topia.TopiaContext; import org.codelutin.topia.TopiaException; import org.codelutin.topia.TopiaNotFoundException; +import org.codelutin.topia.event.TopiaTransactionEvent; +import org.codelutin.topia.event.TopiaTransactionVetoable; import org.codelutin.topia.framework.TopiaContextImplementor; import org.codelutin.topia.framework.TopiaService; import org.codelutin.topia.persistence.TopiaDAO; @@ -52,11 +57,11 @@ import org.codelutin.topia.taas.entities.TaasAuthorizationImpl; import org.codelutin.topia.taas.entities.TaasPrincipalImpl; import org.codelutin.topia.taas.entities.TaasUserImpl; +import org.codelutin.topia.taas.event.TaasAccessEntity; import org.codelutin.topia.taas.jaas.TaasConfiguration; import org.codelutin.topia.taas.jaas.TaasLoginModule; import org.codelutin.topia.taas.jaas.TaasPermission; import org.codelutin.topia.taas.jaas.TaasPolicy; -import org.hibernate.Interceptor; /** * Service pour la sécurité @@ -64,17 +69,18 @@ * @author julien * */ -public class TaasService implements TopiaService { - +public class TaasService implements TopiaService, TopiaTransactionVetoable { + static private Log log = LogFactory.getLog(TaasService.class); - + public static final String SERVICE_NAME = "taas"; public static final String SERVICE_LOGIN_MODULE = TaasLoginModule.class.getName(); public static final String SERVICE_INTERCEPTOR = "topia.service.taas.interceptor"; - + private TaasPolicy policy = new TaasPolicy(this); private TopiaContextImplementor rootContext; - private TopiaContextImplementor transaction; + + private TaasAccessEntity accessEntity; /** * Contructeur par défaut @@ -91,7 +97,7 @@ TaasUserImpl.class, TaasPrincipalImpl.class, TaasAuthorizationImpl.class, - }; + }; } /* @@ -108,22 +114,48 @@ */ public boolean preInit(TopiaContextImplementor context) { rootContext = context; + initSecurity(rootContext); try { org.hibernate.cfg.Configuration configuration = rootContext.getHibernateConfiguration(); String interceptorString = configuration.getProperty(SERVICE_INTERCEPTOR); if(interceptorString != null && !"".equals(interceptorString)) { - Class interceptorClass = (Class) Class.forName(interceptorString); - Constructor interceptorConstructor = interceptorClass.getConstructor(TaasService.class); - Interceptor interceptor = interceptorConstructor.newInstance(this); - configuration.setInterceptor(interceptor); + Class interceptorClass = (Class) Class.forName(interceptorString); + Constructor interceptorConstructor = interceptorClass.getConstructor(TaasService.class); + accessEntity = interceptorConstructor.newInstance(this); } - transaction = (TopiaContextImplementor) rootContext.beginTransaction(); } catch (Exception e) { throw new SecurityException("Init security error", e); } return true; } + /** + * Attachement des vetoables sur chaque transaction + */ + public void beginTransaction(TopiaTransactionEvent event) { + TopiaContext context = event.getTopiaContext(); + initSecurity(context); + } + + /** + * Initialisation des vetoables + * @param context context topia en cours + */ + private void initSecurity(TopiaContext context) { + List entitiesClasses = rootContext.getPersistenceClasses(); + for (Class clazz : entitiesClasses) { + context.addTopiaEntityVetoable(clazz, accessEntity); + } + + Class[] noLoadClasses = getPersistenceClasses(); + for (Class clazz : noLoadClasses) { + context.addTopiaEntityVetoable(clazz, accessEntity); + } + + context.addTopiaEntitiesVetoable(accessEntity); + context.addTopiaTransactionVetoable(this); + } + /* * (non-Javadoc) * @see org.codelutin.topia.framework.TopiaService#postInit(org.codelutin.topia.framework.TopiaContextImplementor) @@ -143,6 +175,28 @@ } /** + * Permet de vérifier les authorizations sur une collection et de supprimer les données non autorisées + * @param entities collection d'entités + * @param actions actions + * @throws SecurityException en cas d'erreur de sécurité + */ + public void check(Collection entities, int actions) throws SecurityException { + Subject subject = Subject.getSubject(AccessController.getContext()); + if (subject != null) { + for (Iterator iterator = entities.iterator(); iterator.hasNext();) { + TopiaEntity entity = iterator.next(); + try { + AccessController.checkPermission(new TaasPermission(entity.getTopiaId(), actions)); + } catch (SecurityException se) { + iterator.remove(); + } + } + } else { + throw new SecurityException("Use doAs() and login first"); + } + } + + /** * Permet de vérifier les authorizations * @param entity entité * @param actions actions @@ -160,7 +214,7 @@ throw new SecurityException("Use doAs() and login first"); } } - + /** * Permet de vérifier les authorizations * @param entity entité @@ -168,10 +222,11 @@ * @throws SecurityException en cas d'erreur de sécurité */ public void checkRequestPermission(TopiaEntity entity, int actions) throws SecurityException { - List permissions = getRequestPermission(entity, actions); - Subject subject = Subject.getSubject(AccessController.getContext()); if (subject != null) { + + List permissions = getRequestPermission(entity, actions); + if(permissions == null) { try { AccessController.checkPermission(new TaasPermission(entity.getTopiaId(), actions)); @@ -194,6 +249,42 @@ } /** + * Permet de vérifier les authorizations sur une collection et de supprimer les données non autorisées + * @param entities collection d'entités + * @param actions actions + * @throws SecurityException en cas d'erreur de sécurité + */ + public void checkRequestPermission(Collection entities, int actions) throws SecurityException { + Subject subject = Subject.getSubject(AccessController.getContext()); + if (subject != null) { + + for (Iterator iterator = entities.iterator(); iterator.hasNext();) { + TopiaEntity entity = iterator.next(); + List permissions = getRequestPermission(entity, actions); + + if(permissions == null) { + try { + AccessController.checkPermission(new TaasPermission(entity.getTopiaId(), actions)); + } catch (SecurityException se) { + iterator.remove(); + } + } else { + for (Permission permission : permissions) { + try { + AccessController.checkPermission(permission); + break; + } catch (SecurityException se) { + iterator.remove(); + } + } + } + } + } else { + throw new SecurityException("Use doAs() and login first"); + } + } + + /** * Récupération des requests permissions dans les DAOs * @param entity entité * @param actions actions @@ -211,6 +302,7 @@ List permissions = null; try { + TopiaContextImplementor transaction = (TopiaContextImplementor) entity.getTopiaContext(); TopiaDAO dao = transaction.getDAO(klass); permissions = dao.getRequestPermission(topiaId, actions); } catch (TopiaException e) {