Index: topia-security/src/java/org/codelutin/topia/security/util/TopiaSecurityFilterList.java diff -u /dev/null topia-security/src/java/org/codelutin/topia/security/util/TopiaSecurityFilterList.java:1.1 --- /dev/null Mon Sep 25 13:24:45 2006 +++ topia-security/src/java/org/codelutin/topia/security/util/TopiaSecurityFilterList.java Mon Sep 25 13:24:40 2006 @@ -0,0 +1,65 @@ +/* *##% +* 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.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.topia.TopiaException; +import org.codelutin.topia.persistence.TopiaEntity; + +/** + * La classe permet d'encapsuler une collection d'entités et de filtrer son contenu + * par rapport à une permission. + * @author ruchaud + * @param + */ +public class TopiaSecurityFilterList extends ArrayList { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(TopiaSecurityUtil.class); + + private static final long serialVersionUID = 1L; + + public TopiaSecurityFilterList(Collection entities, int actions) { + super(entities); + for (Iterator iterator = this.iterator(); iterator.hasNext();) { + TopiaEntity entity = (TopiaEntity) iterator.next(); + try { + TopiaSecurityUtil.checkPermission(entity.getTopiaId(), actions); + } catch (TopiaException e) { + iterator.remove(); + if(log.isDebugEnabled()) { + log.debug("Removed because : " + e); + } + } + } + } + + public TopiaSecurityFilterList(Collection entities, int actions, String ... fields) { + //TODO: Gestion des autorisations sur les champs (cf TopiaEntityAuthorization) + throw new UnsupportedOperationException(); + } + +} Index: topia-security/src/java/org/codelutin/topia/security/util/TopiaSecurityUtil.java diff -u /dev/null topia-security/src/java/org/codelutin/topia/security/util/TopiaSecurityUtil.java:1.1 --- /dev/null Mon Sep 25 13:24:45 2006 +++ topia-security/src/java/org/codelutin/topia/security/util/TopiaSecurityUtil.java Mon Sep 25 13:24:40 2006 @@ -0,0 +1,242 @@ +/* *##% +* 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/25 13:24:40 $ +* par : $Author: ruchaud $ +*/ + +package org.codelutin.topia.security.util; + +import java.security.AccessControlException; +import java.security.AccessController; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.StringTokenizer; + +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.security.entities.authorization.TopiaEntityAuthorization; +import org.codelutin.topia.security.entities.authorization.TopiaEntityAuthorizationImpl; +import org.codelutin.topia.security.jaas.TopiaLoginModule; +import org.codelutin.topia.security.jaas.TopiaPermission; + +import sun.misc.BASE64Encoder; + +/** + * Classe utilitaire + * + * @author ruchaud + * + */ +public class TopiaSecurityUtil { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(TopiaSecurityUtil.class); + + 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(); + + public static final String TOPIA_SECURITY_PERSISTENCE_CLASSES = "org.codelutin.topia.security.entities.user.TopiaUserImpl,org.codelutin.topia.security.entities.authorization.TopiaEntityAuthorizationImpl,org.codelutin.topia.security.entities.user.TopiaGroupImpl,org.codelutin.topia.security.entities.authorization.TopiaLinkAuthorizationImpl,org.codelutin.topia.security.entities.authorization.TopiaAssociationAuthorizationImpl,org.codelutin.topia.security.entities.authorization.TopiaAuthorizationImpl"; + + /** + * 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) { + return digestSHAHex(msg); + } + + /** + * 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 digestSHABase64(String msg) { + if (msg == null) { + return null; + } + try { + MessageDigest digest = MessageDigest.getInstance("SHA"); + byte[] bytes = msg.getBytes(); + bytes = digest.digest(bytes); + BASE64Encoder encoder = new sun.misc.BASE64Encoder(); + String msgHashed = encoder.encode(bytes); + return msgHashed; + } catch (NoSuchAlgorithmException nsee) { + return msg; + } + } + + /** + * Fait le checksum SHA de la chaine de caractere le resultat est retourne + * sous forme de chaine Hexadecimal. + */ + static public String digestSHAHex(String ch){ + if(ch == null){ + return null; + } + try{ + MessageDigest md = MessageDigest.getInstance("SHA"); + md.update(ch.getBytes()); + byte[] digest = md.digest(); + + StringBuffer result = new StringBuffer(); + for (int i=0; i < digest.length; i++) { + String hex = Integer.toHexString(0xFF & digest[i]); + if (hex.length() == 1) { + result.append("0" + hex); + } else { + result.append(hex); + } + } + + return result.toString(); + }catch(NoSuchAlgorithmException eee){ + log.warn("Impossible de trouve l'algo SHA", eee); + return ch; + } + } + + /** + * Transforme actions en un entier. + * @param actions - + * combinaison de mots cles "load" "update" "create" et "delete" + * separes par des virgules. Ex : "load,update" + * @return 0 si aucune permission. Une combinaison des permissions + */ + public static int actionsString2Int(String actions) { + int result = 0x0; + StringTokenizer tokens = new StringTokenizer(actions, ","); + while (tokens.hasMoreTokens()) { + String action = tokens.nextToken().trim(); + if (LOAD_TEXT.equalsIgnoreCase(action)) { + result |= LOAD; + } else if (CREATE_TEXT.equalsIgnoreCase(action)) { + result |= CREATE; + } else if (UPDATE_TEXT.equalsIgnoreCase(action)) { + result |= UPDATE; + } else if (DELETE_TEXT.equalsIgnoreCase(action)) { + result |= DELETE; + } else { + throw new IllegalArgumentException("action not supported: " + + action); + } + } + return result; + } + + /** + * Transforme actions en une chaîne de caractères + * @param actions les actions sous forme d'un entier + * @return La chaine des actions passé en paramètre + */ + public static String actionsInt2String(int actions) { + StringBuffer result = new StringBuffer(); + if ((actions & LOAD) == LOAD) { + result.append(LOAD_TEXT); + result.append(","); + } + if ((actions & CREATE) == CREATE) { + result.append(CREATE_TEXT); + result.append(","); + } + if ((actions & UPDATE) == UPDATE) { + result.append(UPDATE_TEXT); + result.append(","); + } + if ((actions & DELETE) == DELETE) { + result.append(DELETE_TEXT); + result.append(","); + } + + if (result.length() > 0) { + return result.substring(0, result.length() - 1); + } else { + return ""; + } + } + + /** + * 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, int 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, int 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, actions, subj.getPrincipals()); + 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); + } + } + +} //TopiaSecurityUtil