Index: topia-security/src/java/org/codelutin/topia/security/TopiaSecurityServiceImpl.java diff -u topia-security/src/java/org/codelutin/topia/security/TopiaSecurityServiceImpl.java:1.5 topia-security/src/java/org/codelutin/topia/security/TopiaSecurityServiceImpl.java:1.6 --- topia-security/src/java/org/codelutin/topia/security/TopiaSecurityServiceImpl.java:1.5 Fri Oct 27 08:03:39 2006 +++ topia-security/src/java/org/codelutin/topia/security/TopiaSecurityServiceImpl.java Fri Oct 27 17:00:24 2006 @@ -20,6 +20,7 @@ package org.codelutin.topia.security; +import static org.codelutin.topia.security.util.TopiaSecurityUtil.LOAD; import static org.codelutin.topia.security.util.TopiaSecurityUtil.TOPIA_SECURITY_PERSISTENCE_CLASSES; import java.security.AccessController; @@ -36,10 +37,12 @@ import javax.security.auth.login.Configuration; import org.apache.commons.collections.map.ReferenceMap; +import org.apache.commons.lang.ArrayUtils; 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.TopiaServiceDAOHelper; import org.codelutin.topia.event.TopiaTransactionEvent; import org.codelutin.topia.event.TopiaTransactionVetoable; @@ -60,6 +63,7 @@ import org.codelutin.topia.security.jaas.TopiaPermission; import org.codelutin.topia.security.jaas.TopiaPolicy; import org.codelutin.topia.security.listener.EntityVetoable; +import org.codelutin.topia.security.listener.NoSecurityLoad; import org.codelutin.topia.security.listener.PropertyReadListener; import org.codelutin.topia.security.listener.PropertyVetoable; import org.codelutin.topia.security.listener.PropertyWriteListener; @@ -344,19 +348,52 @@ * @throws TopiaException */ //FIXME : Voir si on peut mettre en relation un objet vers plusieurs objets - protected List getAllPossibleExpression(String topiaId) throws TopiaException { - List allBy = getSecurityContext().find("select distinct link.by from " + - TopiaExpressionLink.class.getName() + " link where link.replace=?", - topiaId); - - if(allBy == null) { - allBy = new ArrayList(); + protected List getRealExpressions(String topiaId) { + try { + List allBy = getSecurityContext().find("select distinct link.by from " + + TopiaExpressionLink.class.getName() + " link where link.replace=?", + topiaId); + + if(allBy == null) { + allBy = new ArrayList(); + } + + allBy.add(topiaId); + return allBy; + } catch (TopiaException te) { + throw new SecurityException("Replace expression for link failed", te); } - - allBy.add(topiaId); - return allBy; } + /** + * Permet de determiner seulement les actions pour lesquelles on doit vérifier + * les actions. + * @param topiaId identifiant de l'entité ToPIA + * @param actions actions à vérifier + * @return actions réellement à vérifer + */ + protected int getRealActions(String topiaId, int actions) { + try { + Class className = TopiaId.getClassName(topiaId); + Class[] interfaces = className.getInterfaces(); + + if(ArrayUtils.contains(interfaces, NoSecurityLoad.class)) { + actions = actions - LOAD; + } + + /* TODO: + if(ArrayUtils.contains(interfaces, NoEntityVetoableRead.class)) { + actions = actions - UPDATE; + } + ... + */ + } catch (TopiaNotFoundException te) { + if(log.isDebugEnabled()) { + log.debug("Real actions failed", te); + } + } + return actions; + } /* (non-Javadoc) * @see org.codelutin.topia.security.TopiaSecurityService#checkPermission(java.lang.Class, int) */ @@ -375,34 +412,33 @@ * @see org.codelutin.topia.security.TopiaSecurityService#checkPermission(java.lang.String, int) */ public void checkPermission(String topiaId, int actions) throws SecurityException { - List expressions; - Subject subject = Subject.getSubject(AccessController.getContext()); - if (subject != null) { - try { - expressions = getAllPossibleExpression(topiaId); - } catch (TopiaException te) { - throw new SecurityException("Replace expression for link failed", te); - } - - boolean authorized = false; - for (String expression : expressions) { - TopiaEntityAuthorization authorization = new TopiaEntityAuthorizationImpl( - expression, actions, subject.getPrincipals()); - try { - AccessController.checkPermission(new TopiaPermission(authorization)); - authorized = true; - break; - } catch (SecurityException se) { - authorized = false; + int realActions = getRealActions(topiaId, actions); + /* Il reste des actions à vérifier */ + if(realActions != 0) { + Subject subject = Subject.getSubject(AccessController.getContext()); + if (subject != null) { + List expressions = getRealExpressions(topiaId); + + boolean authorized = false; + for (String expression : expressions) { + TopiaEntityAuthorization authorization = new TopiaEntityAuthorizationImpl( + expression, realActions, subject.getPrincipals()); + try { + AccessController.checkPermission(new TopiaPermission(authorization)); + authorized = true; + break; + } catch (SecurityException se) { + authorized = false; + } + } + + if(!authorized) { + throw new SecurityException("Access denied to object \"" + topiaId + "\" for \"" + subject + "\""); + } + } else { + if(log.isWarnEnabled()) { + log.warn("Use doAs() and login first"); } - } - - if(!authorized) { - throw new SecurityException("Access denied to object \"" + topiaId + "\" for \"" + subject + "\""); - } - } else { - if(log.isWarnEnabled()) { - log.warn("Use doAs() and login first"); } } }