Index: topia-security/src/java/org/codelutin/topia/security/TopiaSecurityVetoableListener.java diff -u /dev/null topia-security/src/java/org/codelutin/topia/security/TopiaSecurityVetoableListener.java:1.1 --- /dev/null Wed Sep 13 08:45:15 2006 +++ topia-security/src/java/org/codelutin/topia/security/TopiaSecurityVetoableListener.java Wed Sep 13 08:45:10 2006 @@ -0,0 +1,182 @@ +/* *##% +* 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.1 $ +* +* Mise a jour: $Date: 2006/09/13 08:45:10 $ +* par : $Author: ruchaud $ +*/ + + +package org.codelutin.topia.security; + +import static org.codelutin.topia.security.TopiaSecurityUtil.CREATE_TEXT; +import static org.codelutin.topia.security.TopiaSecurityUtil.DELETE_TEXT; +import static org.codelutin.topia.security.TopiaSecurityUtil.LOAD_TEXT; +import static org.codelutin.topia.security.TopiaSecurityUtil.UPDATE_TEXT; + +import java.security.AccessControlException; +import java.security.AccessController; + +import javax.security.auth.Subject; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.topia.TopiaException; +import org.codelutin.topia.event.TopiaVetoableEntityEvent; +import org.codelutin.topia.event.TopiaVetoableEntityListener; +import org.codelutin.topia.event.TopiaVetoableEntityLoadEvent; +import org.codelutin.topia.event.TopiaVetoableEntityLoadListener; +import org.codelutin.topia.security.entities.authorization.TopiaAssociationAuthorizationImpl; +import org.codelutin.topia.security.entities.authorization.TopiaEntityAuthorization; +import org.codelutin.topia.security.entities.authorization.TopiaEntityAuthorizationImpl; +import org.codelutin.topia.security.entities.authorization.TopiaLinkAuthorizationImpl; +import org.codelutin.topia.security.entities.user.TopiaUserImpl; +import org.codelutin.topia.security.jaas.TopiaPermission; + +/** + * Implantation pour la sécurité des Vetoable Listeners de ToPIA. Dans le cas de + * load, vrai ou faux est retourné en fonction des droits de l'utilisateur. Pour + * les autres, une exception est levée si l'utilisateur n'a pas les droits. + */ +public class TopiaSecurityVetoableListener implements + TopiaVetoableEntityListener, TopiaVetoableEntityLoadListener { + + private static Log log = LogFactory.getLog(TopiaSecurityVetoableListener.class); + + /* (non-Javadoc) + * @see org.codelutin.topia.event.TopiaVetoableEntityListener#createEntity(org.codelutin.topia.event.TopiaVetoableEntityEvent) + */ + public void createEntity(TopiaVetoableEntityEvent event) { + if (log.isDebugEnabled()) { + log.debug("[Security] create entity : " + event.getEntityClass()); + } + try { + checkPermission(event.getEntityClass(), CREATE_TEXT); + } catch (TopiaException te) { + throw new SecurityException("Access denied to entity creation", te); + } + } + + /* (non-Javadoc) + * @see org.codelutin.topia.event.TopiaVetoableEntityListener#updateEntity(org.codelutin.topia.event.TopiaVetoableEntityEvent) + */ + public void updateEntity(TopiaVetoableEntityEvent event) { + if (log.isDebugEnabled()) { + log.debug("[Security] update entity : " + event.getId()); + } + try { + checkPermission((String)event.getId(), UPDATE_TEXT); + } catch (TopiaException te) { + throw new SecurityException("Access denied to entity modification", te); + } + } + + /* (non-Javadoc) + * @see org.codelutin.topia.event.TopiaVetoableEntityListener#deleteEntity(org.codelutin.topia.event.TopiaVetoableEntityEvent) + */ + public void deleteEntity(TopiaVetoableEntityEvent event) { + if (log.isDebugEnabled()) { + log.debug("[Security] delete entity : " + event.getId()); + } + try { + checkPermission((String)event.getId(), DELETE_TEXT); + } catch (TopiaException te) { + throw new SecurityException("Access denied to entity deletion", te); + } + } + + /* (non-Javadoc) + * @see org.codelutin.topia.event.TopiaVetoableEntityLoadListener#loadEntity(org.codelutin.topia.event.TopiaVetoableEntityLoadEvent) + */ + public boolean loadEntity(TopiaVetoableEntityLoadEvent event) { + if (log.isDebugEnabled()) { + log.debug("[Security] load entity : " + event.getId()); + } + //Le chargement des utilisateurs et permissions doit etre possible pour tous + if (event.getEntityClass().equals(TopiaUserImpl.class) || + event.getEntityClass().equals(TopiaEntityAuthorizationImpl.class) || + event.getEntityClass().equals(TopiaLinkAuthorizationImpl.class) || + event.getEntityClass().equals(TopiaAssociationAuthorizationImpl.class)) { + if (log.isDebugEnabled()) { + log.debug("[Security] load granted to : " + event.getId()); + } + return true; + } + try { + checkPermission((String)event.getId(), LOAD_TEXT); + } catch (TopiaException te) { + if (log.isWarnEnabled()) { + log.warn("[Security] load denied to : " + event.getId(), te); + } + return false; + } + return true; + } + + /** + * Vérifie si l'utilisateur actuellement loggué a le droit d'accéder à + * l'entité passée en paramètre pour les actions spécifiées. + * @param entientityClassty l'entité pour laquelle on vérifie les droits + * @param actions les actions [load, read, write, admin] + * @throws TopiaSecurityException + */ + public static void checkPermission(Class entityClass, String actions) throws TopiaException { + if (log.isTraceEnabled()) { + log.trace("Checking permissions to entity class : " + entityClass); + } + if (entityClass == null) { + throw new TopiaException("Class cannot be null"); + } + String topiaId = entityClass.getName() + "#*"; + checkPermission(topiaId, actions); + } + + /** + * Vérifie si l'utilisateur actuellement loggué a le droit d'accéder à + * l'entité passée en paramètre pour les actions spécifiées. + * @param topiaId le topiaId de l'entité pour laquelle on vérifie les droits + * @param actions les actions [load, read, write, admin] + * @throws TopiaSecurityException + */ + public static void checkPermission(String topiaId, String actions) throws TopiaException { + Subject subj = Subject.getSubject(AccessController.getContext()); + if (subj == null) { + throw new TopiaException("Use doAs() and login first"); + } + try { + TopiaEntityAuthorization authorization = new TopiaEntityAuthorizationImpl( + topiaId, subj.getPrincipals(), actions); + AccessController.checkPermission(new TopiaPermission(authorization)); + } catch (AccessControlException e) { + throw new TopiaException("access denied to object \"" + topiaId + "\" for \"" + subj + "\"", e); + } + if (log.isTraceEnabled()) { + log.trace("Permission granted for entity : " + topiaId); + } + } + +} //TopiaSecurityVetoableListener Index: topia-security/src/java/org/codelutin/topia/security/TopiaSecurityManager.java diff -u /dev/null topia-security/src/java/org/codelutin/topia/security/TopiaSecurityManager.java:1.1 --- /dev/null Wed Sep 13 08:45:15 2006 +++ topia-security/src/java/org/codelutin/topia/security/TopiaSecurityManager.java Wed Sep 13 08:45:10 2006 @@ -0,0 +1,15 @@ +package org.codelutin.topia.security; + +import org.codelutin.topia.security.entities.authorization.TopiaAuthorizationDAO; +import org.codelutin.topia.security.entities.user.TopiaGroupDAO; +import org.codelutin.topia.security.entities.user.TopiaUserDAO; + +public interface TopiaSecurityManager { + + public abstract TopiaUserDAO getTopiaUserDAO(); + + public abstract TopiaGroupDAO getTopiaGroupDAO(); + + public abstract TopiaAuthorizationDAO getTopiaAuthorizationDAO(); + +} \ No newline at end of file Index: topia-security/src/java/org/codelutin/topia/security/TopiaSecurityManagerImpl.java diff -u /dev/null topia-security/src/java/org/codelutin/topia/security/TopiaSecurityManagerImpl.java:1.1 --- /dev/null Wed Sep 13 08:45:15 2006 +++ topia-security/src/java/org/codelutin/topia/security/TopiaSecurityManagerImpl.java Wed Sep 13 08:45:10 2006 @@ -0,0 +1,86 @@ +/* *##% +* 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. +*##%*/ + +package org.codelutin.topia.security; + +import javax.security.auth.login.Configuration; + +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.security.entities.authorization.TopiaAuthorizationDAO; +import org.codelutin.topia.security.entities.user.TopiaGroupDAO; +import org.codelutin.topia.security.entities.user.TopiaUserDAO; + + +public class TopiaSecurityManagerImpl implements TopiaSecurityManager { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(TopiaSecurityManagerImpl.class); + + private TopiaContext context; + + public TopiaSecurityManagerImpl(TopiaContext context) { + this.context = context; + TopiaSecurityVetoableListener securityListener = new TopiaSecurityVetoableListener(); + context.addVetoableListener(securityListener); + context.addVetoableLoadListener(securityListener); + TopiaPolicy policy = new TopiaPolicy(context); + policy.installPolicy(); + Configuration.setConfiguration(new org.codelutin.topia.security.jaas.TopiaConfiguration("topia", this)); + } + + /* (non-Javadoc) + * @see org.codelutin.topia.security.TopiaSecurityManagerInterface#getTopiaUserDAO() + */ + public TopiaUserDAO getTopiaUserDAO() { + try { + return TopiaSecurityDAOHelper.getTopiaUserDAO(context); + } catch (TopiaException te) { + log.error("Recuperation du userManager impossible", te); + } + return null; + } + + /* (non-Javadoc) + * @see org.codelutin.topia.security.TopiaSecurityManagerInterface#getTopiaGroupDAO() + */ + public TopiaGroupDAO getTopiaGroupDAO() { + try { + return TopiaSecurityDAOHelper.getTopiaGroupDAO(context); + } catch (TopiaException te) { + log.error("Recuperation du userManager impossible", te); + } + return null; + } + + /* (non-Javadoc) + * @see org.codelutin.topia.security.TopiaSecurityManagerInterface#getTopiaAuthorizationDAO() + */ + public TopiaAuthorizationDAO getTopiaAuthorizationDAO() { + try { + return TopiaSecurityDAOHelper.getTopiaAuthorizationDAO(context); + } catch (TopiaException te) { + log.error("Recuperation du userManager impossible", te); + } + return null; + } +} Index: topia-security/src/java/org/codelutin/topia/security/TopiaSecurityUtil.java diff -u /dev/null topia-security/src/java/org/codelutin/topia/security/TopiaSecurityUtil.java:1.1 --- /dev/null Wed Sep 13 08:45:15 2006 +++ topia-security/src/java/org/codelutin/topia/security/TopiaSecurityUtil.java Wed Sep 13 08:45:10 2006 @@ -0,0 +1,76 @@ +/* *##% +* 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. +*##%*/ + +/* * +* TopiaSecurityUtil.java +* +* Created: 15 févr. 2006 +* +* @author Arnaud Thimel +* @version $Revision: 1.1 $ +* +* Mise a jour: $Date: 2006/09/13 08:45:10 $ +* par : $Author: ruchaud $ +*/ + + +package org.codelutin.topia.security; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.codelutin.topia.security.jaas.TopiaLoginModule; + +public class TopiaSecurityUtil { + + public static final int LOAD = 0x1; + public static final String LOAD_TEXT = "LOAD"; + public static final int CREATE = 0x2; + public static final String CREATE_TEXT = "CREATE"; + public static final int UPDATE = 0x4; + public static final String UPDATE_TEXT = "UPDATE"; + public static final int DELETE = 0x8; + public static final String DELETE_TEXT = "DELETE"; + + public static final String SECURITY_MANAGER_KEY = "topia.app.security.manager"; + + public static final String TOPIA_LOGIN_MODULE = TopiaLoginModule.class.getName(); + + /** + * Applique un algorithme de hashage sur la chaine de caratère passée en + * paramètre + * @param msg la chaine de caratère sur laquelle on veut opérer le hashage + * @return La chaine de caractère une fois l'algorithme appliqué + */ + public static String hash(String msg) { + if (msg == null) { + return null; + } + try { + MessageDigest digest = MessageDigest.getInstance("SHA"); + byte[] bytes = msg.getBytes(); + bytes = digest.digest(bytes); + return new String(bytes); + } catch (NoSuchAlgorithmException nsee) { + return msg; + } + } + +} //TopiaSecurityUtil