Author: bpoussin Date: 2012-01-31 17:31:51 +0100 (Tue, 31 Jan 2012) New Revision: 1395 Url: http://nuiton.org/repositories/revision/wikitty/1395 Log: rename authorization to authorisation (US->GB) Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthentication.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthenticationLDAP.java trunk/wikitty-api/src/main/resources/wikitty-config-sample-client.properties trunk/wikitty-api/src/main/resources/wikitty-config-sample-inmemory.properties trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties trunk/wikitty-api/src/main/resources/wikitty-config-sample-standalone.properties Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyConfigOption.java 2012-01-31 16:31:51 UTC (rev 1395) @@ -131,7 +131,7 @@ n_("WikittyService to use (list must be in right order. " + "ex: org.nuiton.wikitty.WikittyServiceStorage,org.nuiton.wikitty.WikittyServiceNotifier," + "org.nuiton.wikitty.WikittyServiceCached,org.nuiton.wikitty.WikittyServiceAuthentication," - + "org.nuiton.wikitty.WikittyServiceAuthorization)"), + + "org.nuiton.wikitty.WikittyServiceAuthorisation)"), WikittyServiceInMemory.class.getName(), String.class, false, false), WIKITTY_WIKITTYSERVICEINMEMORY_PERSISTENCE( Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/WikittyService.java 2012-01-31 16:31:51 UTC (rev 1395) @@ -55,7 +55,7 @@ * <dd>add a cache for wikitties</dd> * <dt>{@link WikittyServiceAuthentication}</dt> * <dd>add user authentication support</dd> - * <dt>{@link WikittyServiceAuthorization}</dt> + * <dt>{@link WikittyServiceAuthorisation}</dt> * <dd>add right management</dd> * <dt>{@link WikittyServiceNotifier}</dt> * <dd>add notifications between client of the same wikitty service</dd> Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyExtensionMigrationRename.java 2012-01-31 16:31:51 UTC (rev 1395) @@ -53,7 +53,7 @@ /** * Recursively add extension with requires ones (orderer). - * WikittyService used in this method must not have WikittyServiceAuthorization + * WikittyService used in this method must not have WikittyServiceAuthorisation * in stack because we pass null as secuirtyToken to method. (TODO poussin * 2010 verify this assertion, when we use Migration, we don't need * Security) Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceAuthorisation.java 2012-01-31 16:31:51 UTC (rev 1395) @@ -0,0 +1,810 @@ +/* + * #%L + * Wikitty :: api + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.wikitty.services; + +import static org.nuiton.i18n.I18n._; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import org.apache.commons.lang.StringUtils; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.ApplicationConfig; +import org.nuiton.util.TimeLog; +import org.nuiton.wikitty.WikittyConfigOption; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyAuthorisation; +import org.nuiton.wikitty.entities.WikittyAuthorisationHelper; +import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.entities.WikittyGroup; +import org.nuiton.wikitty.entities.WikittyGroupHelper; +import org.nuiton.wikitty.entities.WikittyMetaExtensionUtil; +import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.entities.WikittyTokenHelper; +import org.nuiton.wikitty.entities.WikittyTreeNode; +import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; + +/** + * Cette classe gere les autorisations d'acces en utilisant les + * WikittyAuthorization, il faut donc que la personne soit loggue et donc + * qu'il y ait un WikittyServiceAuthentication dans la pile des services, le + * plus souvent avant le WikittyServiceAuthorisation pour que la methode de + * login ne but pas sur les autorisations. + * + * + * FIXME add security policy level two on wikittyAuthorisation to prevent writing + * + * @author poussin + * @version $Revision: 1311 $ + * + * Last update: $Date: 2012-01-09 20:03:18 +0100 (Mon, 09 Jan 2012) $ + * by : $Author: bpoussin $ + */ +public class WikittyServiceAuthorisation extends WikittyServiceDelegator { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + final static private Log log = LogFactory.getLog(WikittyServiceAuthorisation.class); + /** use to trace time of security code, timelog must not include delegator + * time in this class */ + final static private TimeLog timeLog = new TimeLog(WikittyServiceAuthorisation.class); + + /** cache de l'id du groupe AppAdmin */ + transient protected String appAdminGroupId = null; + + /** + * + * @param config + * @param ws + * @param auth si non null alors un mecanisme d'authentification externe est + * utilise + */ + public WikittyServiceAuthorisation(ApplicationConfig config, WikittyService ws) { + super(ws); + if (config != null) { + long timeToLogInfo = config.getOptionAsInt(WikittyConfigOption. + WIKITTY_SERVICE_TIME_TO_LOG_INFO.getKey()); + long timeToLogWarn = config.getOptionAsInt(WikittyConfigOption. + WIKITTY_SERVICE_TIME_TO_LOG_WARN.getKey()); + timeLog.setTimeToLogInfo(timeToLogInfo); + timeLog.setTimeToLogWarn(timeToLogWarn); + } + } + + @Override + public void addWikittyServiceListener(WikittyListener listener, ServiceListenerType type) { + getDelegate().addWikittyServiceListener(listener, type); + } + + @Override + public void removeWikittyServiceListener(WikittyListener listener, ServiceListenerType type) { + getDelegate().addWikittyServiceListener(listener, type); + } + + @Override + public WikittyEvent clear(String securityToken) { + String userId = getUserId(securityToken); + if (isAppAdmin(securityToken, userId)) { + // seul les AppAdmin on le droit a cette method + WikittyEvent result = getDelegate().clear(securityToken); + return result; + } else { + throw new SecurityException(_("user %s can't clear data", userId)); + } + } + + @Override + public WikittyEvent replay( + String securityToken, List<WikittyEvent> events, boolean force) { + long start = TimeLog.getTime(); + + String userId = getUserId(securityToken); + for (WikittyEvent e : events) { + if (e.getType().contains( + WikittyEvent.WikittyEventType.CLEAR_WIKITTY) + || e.getType().contains( + WikittyEvent.WikittyEventType.CLEAR_EXTENSION)) { + if (isAppAdmin(securityToken, userId)) { + // seul les AppAdmin on le droit a cette method + // les AppAdmin on meme le droit de tout faire, donc on + // peut sortir de la boucle + break; + } else { + throw new SecurityException(_("user %s can't clear data", userId)); + } + } + if (e.getType().contains(WikittyEvent.WikittyEventType.PUT_WIKITTY)) { + checkStore(securityToken, e.getWikitties().values()); + } + if (e.getType().contains(WikittyEvent.WikittyEventType.REMOVE_WIKITTY)) { + checkDelete(securityToken, e.getRemoveDate().keySet()); + } + if (e.getType().contains(WikittyEvent.WikittyEventType.PUT_EXTENSION)) { + checkStoreExtension(securityToken, e.getExtensions().values()); + } + if (e.getType().contains(WikittyEvent.WikittyEventType.REMOVE_EXTENSION)) { + checkDeleteExtension(securityToken, e.getDeletedExtensions()); + } + } + + timeLog.log(start, "replay"); + WikittyEvent result = getDelegate().replay(securityToken, events, force); + return result; + } + + + /** + * if app-admin group exists, return true if given userId is app-admin + * if app-admin group doesn't exists, return true if user is anonymous + */ + protected boolean userIsAnonymousOrAppAdmin(String securityToken, String userId) { + boolean userIsAnonymousOrAppAdmin = false; + + if (getAppAdminGroup(securityToken) == null) { + if (securityToken == null) { + // user is anonymous + userIsAnonymousOrAppAdmin = true; + } + } else { + if (isAppAdmin(securityToken, userId)) { + // user is appAdmin + userIsAnonymousOrAppAdmin = true; + } + } + + return userIsAnonymousOrAppAdmin; + } + + @Override + public WikittyEvent store(String securityToken, + Collection<Wikitty> wikitties, boolean force) { + long start = TimeLog.getTime(); + checkStore(securityToken, wikitties); + timeLog.log(start, "store"); + WikittyEvent result = getDelegate().store(securityToken, wikitties, force); + return result; + } + + /** + * Indique si on a bien le droit d'enregistrer tout les wikitties de la + * collection. Des que pour un wikitty on a pas les droits, une exception + * est levee. + * + * @param securityToken + * @param wikitties + * @return + */ + protected void checkStore(String securityToken, Collection<Wikitty> wikitties) { + String userId = getUserId(securityToken); + for (Wikitty wikitty : wikitties) { + if (wikitty == null) { + continue; + } + // usual case, a user want to store a wikitty + Wikitty oldVersion = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, wikitty.getId()); + + Collection<String> newExtensions = new ArrayList<String>( + wikitty.getExtensionNames()); + if (oldVersion != null) { + // we already checked the rights for those extension + // re-do the check has too much cost, avoid it + newExtensions.removeAll(oldVersion.getExtensionNames()); + } + + // check that **reader** right on Security for all extension + for (String extensionName: newExtensions) { + + Wikitty extensionRights = restoreExtensionAuthorisation( + securityToken, extensionName); + boolean canCreate = extensionRights == null || + canRead(securityToken, userId, null, extensionRights); + if ( ! canCreate ) { + throw new SecurityException(_( + "user %s can't create instance of extension %s", + userId, extensionRights)); + } + } + + if (oldVersion != null) { // it's an update + + for (String fqFieldDirtyName : wikitty.getDirty()) { + + String concernedExtensionName = WikittyUtil + .getExtensionNameFromFQFieldName(fqFieldDirtyName); + + if (log.isTraceEnabled()) { + log.trace(String.format( + "will update field %s from extension %s", + fqFieldDirtyName, concernedExtensionName)); + } + + boolean fieldRequireAdminRights = // true if field is a field of WikittyAuthorisation + // concerned extension is "WikittyAuthorisation" + WikittyAuthorisation.EXT_WIKITTYAUTHORISATION.equals( + concernedExtensionName) + // or concerned extension is something like "AnyExtension:WikittyAuthorisation" + || WikittyAuthorisation.EXT_WIKITTYAUTHORISATION.equals( + WikittyUtil.getMetaExtensionNameFromFQMetaExtensionName( + concernedExtensionName)); + + boolean canChange; // will be true if user can modify the value of this field + // according to his level of rights + if (fieldRequireAdminRights) { + canChange = canAdmin(securityToken, + userId, concernedExtensionName, wikitty); + } else { + canChange = canWrite(securityToken, + userId, concernedExtensionName, wikitty); + } + + // TODO poussin 20101208 quel est l'interet de faire cette copie ? + // surtout quelle ne fonctionne pas car le oldVersion n'a pas + // forcement toutes les extensions du nouveau wikitty + // Code supprime et remplace +// if (canChange) { +// Object newValue = wikitty.getFqField(fqFieldDirtyName); +// oldVersion.setFqField(fqFieldDirtyName, newValue); +// } else { +// throw new SecurityException(_("user %s can't write field %s on wikitty %s", +// userId, fqFieldDirtyName, wikitty)); +// } + if (!canChange) { + throw new SecurityException(_("user %s can't write field %s on wikitty %s", + userId, fqFieldDirtyName, wikitty)); + } + } + } + } + } + + @Override + public List<Wikitty> restore(String securityToken, List<String> ids) { + String userId = getUserId(securityToken); + List<Wikitty> wikitties = getDelegate().restore(securityToken, ids); + + long start = TimeLog.getTime(); + for (Wikitty wikitty : wikitties) { + if (wikitty != null) { + refuseUnauthorizedRead(securityToken, userId, wikitty); + } + } + timeLog.log(start, "restore"); + return wikitties; + } + + /** throw an exception if read is not allowed */ + protected void refuseUnauthorizedRead( String securityToken, + String userId, + Wikitty wikitty) { + if (wikitty != null) { + for (String extensionName : wikitty.getExtensionNames()) { + if ( ! canRead(securityToken, userId, extensionName, wikitty)) { + throw new SecurityException(_( + "user %s can't read extension %s on wikitty %s," + + " it may be due to a global policy on the wikitty", + userId, extensionName, wikitty)); + } + } + } + } + + protected boolean canRead(String securityToken, String userId, + String extensionName, Wikitty wikitty) { + + boolean canRead = false; + + // first, check per-extension rights + if (wikitty.hasMetaExtension(WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, + extensionName)) { + // there is a policy on the extension + canRead = isReader(securityToken, userId, wikitty, extensionName) + || canWrite(securityToken, userId, extensionName, wikitty); + } + + if ( ! canRead && + wikitty.hasExtension(WikittyAuthorisation.EXT_WIKITTYAUTHORISATION) ) { + // there is no policy for this extension + // but there is a policy for all extension of wikitty + canRead = isReader(securityToken, userId, wikitty, null) + || canWrite(securityToken, userId, extensionName, wikitty); + } else { + // no security policy, everything is allowed + canRead = true; + } + + return canRead; + } + + protected boolean canWrite(String securityToken, String userId, + String extensionName, Wikitty wikitty) { + boolean canWrite = false; + + // first, check per-extension rights + if (wikitty.hasMetaExtension(WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, + extensionName)) { + // there is a policy on the extension of fqFieldDirtyName + canWrite = isWriter(securityToken, userId, wikitty, extensionName) + || canAdmin(securityToken, userId, extensionName, wikitty); + } + + if ( ! canWrite && + wikitty.hasExtension(WikittyAuthorisation.EXT_WIKITTYAUTHORISATION) ) { + // there is no policy for this extension + // but there is a policy for all extension of wikitty + canWrite = isWriter(securityToken, userId, wikitty, null) + || canAdmin(securityToken, userId, extensionName, wikitty); + } else { + // no security policy, everything is allowed + canWrite = true; + } + + return canWrite; + } + + protected boolean canAdmin(String securityToken, String userId, + String extensionName, Wikitty wikitty) { + + boolean canAdmin = false; + + // first, check per-extension rights + if (wikitty.hasMetaExtension(WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, + extensionName)) { + // there is a policy on the extension of fqFieldDirtyName + canAdmin = isAdmin(securityToken, userId, wikitty, extensionName) + || isOwner(securityToken, userId, wikitty, extensionName); + } + if ( ! canAdmin && + wikitty.hasExtension(WikittyAuthorisation.EXT_WIKITTYAUTHORISATION) ) { + // there is no policy for this extension + // but there is a policy for all extension of wikitty + canAdmin = isAdmin(securityToken, userId, wikitty, null) + || isOwner(securityToken, userId, wikitty, null); + } + if ( ! canAdmin ) { + // still not admin, check appAdmin + canAdmin = isAppAdmin(securityToken, userId); + } + + return canAdmin; + } + + @Override + public WikittyEvent delete(String securityToken, Collection<String> ids) { + long start = TimeLog.getTime(); + checkDelete(securityToken, ids); + timeLog.log(start, "delete"); + WikittyEvent result = getDelegate().delete(securityToken, ids); + return result; + } + + /** + * Check if we can delete all id passed in argument + * @param securityToken + * @param ids + */ + public void checkDelete(String securityToken, Collection<String> ids) { + String userId = getUserId(securityToken); + List<String> idsAsList = new ArrayList<String>(ids); + List<Wikitty> wikitties = getDelegate().restore(securityToken, idsAsList); + for (Wikitty wikitty : wikitties) { + if (wikitty != null) { + for (String extensionName : wikitty.getExtensionNames()) { + if ( ! canWrite(securityToken, userId, extensionName, wikitty)) { + throw new SecurityException(_( + "user %s doesn't have rights on extension %s on wikitty %s", + userId, extensionName, wikitty)); + } + } + } + } + } + + @Override + public boolean canWrite(String securityToken, Wikitty wikitty) { + boolean result = true; + String userId = getUserId(securityToken); + for (String extName : wikitty.getExtensionNames()) { + result = result && isWriter(securityToken, userId, wikitty, extName); + if (!result) { + break; + } + } + return result; + } + + @Override + public boolean canDelete(String securityToken, String wikittyId) { + boolean result = true; + Wikitty wikitty = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, wikittyId); + if (wikitty != null) { + String userId = getUserId(securityToken); + for (String extName : wikitty.getExtensionNames()) { + result = result && isWriter(securityToken, userId, wikitty, extName); + if (!result) { + break; + } + } + } + return result; + } + + @Override + public boolean canRead(String securityToken, String wikittyId) { + boolean result = true; + String userId = getUserId(securityToken); + Wikitty wikitty = WikittyServiceEnhanced.restore(getDelegate(), securityToken, wikittyId); + if (wikitty == null) { + result = false; + } else { + for (String extName : wikitty.getExtensionNames()) { + result = result && isReader(securityToken, userId, wikitty, extName); + if (!result) { + break; + } + } + } + return result; + } + + /* *** storing and restoring extensions ***/ + + protected void checkStoreExtension(String securityToken, + Collection<WikittyExtension> exts) { + String userId = getUserId(securityToken); + if ( ! isAppAdmin(securityToken, userId)) { + for (WikittyExtension extension : exts) { + Wikitty extensionAuthorisation = restoreExtensionAuthorisation(securityToken, extension.getName()); + if (extensionAuthorisation != null) { + // canWrite is true if this user can modify the field for this extension + boolean canWrite = canWrite(securityToken, userId, null, extensionAuthorisation); + if ( ! canWrite) { + throw new SecurityException(_("user %s don't have write right for extension %s", userId, extension)); + } + } + } + } + } + + protected void checkDeleteExtension (String securityToken, Collection<String> extNames) { + // FIXME 20101115 poussin check security for extension deletion + } + + @Override + public WikittyEvent storeExtension(String securityToken, + Collection<WikittyExtension> exts) { + long start = TimeLog.getTime(); + checkStoreExtension(securityToken, exts); + timeLog.log(start, "storeExtension"); + return getDelegate().storeExtension(securityToken, exts); + } + + @Override + public WikittyEvent deleteExtension( + String securityToken, Collection<String> extNames) { + long start = TimeLog.getTime(); + checkDeleteExtension(securityToken, extNames); + timeLog.log(start, "deleteExtension"); + return getDelegate().deleteExtension(securityToken, extNames); + } + + private void checkRestoreTreeNode(String securityToken, String userId, WikittyTreeNode treeNode) { + Wikitty treeNodeWikitty = WikittyUtil.getWikitty(getDelegate(), securityToken, treeNode); + refuseUnauthorizedRead(securityToken, userId, treeNodeWikitty); + } + + @Override + public WikittyEvent deleteTree(String securityToken, String treeNodeId) { + Wikitty treeNodeWikitty = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, treeNodeId); + + long start = TimeLog.getTime(); + Collection<Wikitty> wikitties = Collections.singletonList(treeNodeWikitty); + // TODO poussin 20101222 perhaps we must check deletion authorization + // for all children ? + checkStore(securityToken, wikitties); + timeLog.log(start, "deleteTree"); + return getDelegate().deleteTree(securityToken, treeNodeId); + } + + @Override + public Wikitty restoreVersion(String securityToken, String wikittyId, String version) { + Wikitty wikitty = getDelegate().restoreVersion(securityToken, wikittyId, version); + long start = TimeLog.getTime(); + String userId = getUserId(securityToken); + refuseUnauthorizedRead(securityToken, userId, wikitty); + timeLog.log(start, "restoreVersion"); + return wikitty; + } + + @Override + public void syncSearchEngine(String securityToken) { + long start = TimeLog.getTime(); + String userId = getUserId(securityToken); + if (isAppAdmin(securityToken, userId)) { + timeLog.log(start, "syncSearchEngine"); + // seul les AppAdmin on le droit a cette method + getDelegate().syncSearchEngine(securityToken); + } else { + throw new SecurityException(_("user %s can't sync search engine", + getUserId(securityToken))); + } + } + + // + // Method helper to check right + // + + /** tell who own a token (who got this token after login). + * @param securityToken the token whose owner will be returned + * @return a wikitty Id (wikitty has extension WikittyUser) + */ + protected String getUserId(String securityToken) { + String result = null; + // recuperation de l'utilisateur associe au securityToken + // le securityToken est aussi l'id de l'objet + if (securityToken != null) { + Wikitty securityTokenWikitty = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, securityToken); + if (securityTokenWikitty == null) { + throw new SecurityException("bad (obsolete ?) token"); + } else { + result = WikittyTokenHelper.getUser(securityTokenWikitty); + } + } + return result; + } + + /** + * + * @param securityToken + * @param userId + * @param wikitty + * @param extensionName may be null + * @return + */ + protected boolean isReader(String securityToken, String userId, Wikitty wikitty, String extensionName) { + boolean result; + String metaFieldName = WikittyUtil.getMetaFieldName( + WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, extensionName, + WikittyAuthorisation.FIELD_WIKITTYAUTHORISATION_READER); + result = isMember(securityToken, userId, wikitty, metaFieldName, true); + return result; + } + + /** + * + * @param securityToken + * @param userId + * @param wikitty + * @param extensionName may be null + * @return + */ + protected boolean isWriter(String securityToken, String userId, Wikitty wikitty, String extensionName) { + boolean result; + String metaFieldName = WikittyUtil.getMetaFieldName( + WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, extensionName, + WikittyAuthorisation.FIELD_WIKITTYAUTHORISATION_WRITER); + log.trace("meta field name " + metaFieldName); + result = isMember(securityToken, userId, wikitty, metaFieldName); + return result; + } + + /** + * + * @param securityToken + * @param userId + * @param wikitty + * @param extensionName may be null + * @return + */ + protected boolean isAdmin(String securityToken, String userId, Wikitty wikitty, String extensionName) { + boolean result; + String metaFieldName = WikittyUtil.getMetaFieldName( + WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, extensionName, + WikittyAuthorisation.FIELD_WIKITTYAUTHORISATION_ADMIN); + result = isMember(securityToken, userId, wikitty, metaFieldName); + return result; + } + + /** true if given user is owner + * + * @param securityToken + * @param userId + * @param wikitty + * @param extensionName may be null + * @return + */ + protected boolean isOwner(String securityToken, String userId, Wikitty wikitty, String extensionName) { + + String metaFieldName = WikittyUtil.getMetaFieldName( + WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, extensionName, + WikittyAuthorisation.FIELD_WIKITTYAUTHORISATION_OWNER); + + String actualExtensionName = WikittyUtil.getExtensionNameFromFQFieldName(metaFieldName); + String fieldName = WikittyUtil.getFieldNameFromFQFieldName(metaFieldName); + + String owner = wikitty.getFieldAsString(actualExtensionName, fieldName); + + boolean isOwner; + if (owner == null) { + isOwner = false; + } else { + isOwner = owner.equals(userId); + } + return isOwner; + } + + /** {@link #isMember(String, String, Wikitty, String, boolean)} with default value */ + protected boolean isMember(String securityToken, String userId, Wikitty extensionRights, String fqFieldName) { + // by default, user is considered not member if he is not in the group, so passing "false" + return isMember(securityToken, userId, extensionRights, fqFieldName, false); + } + + /** check if a user is listed in a level of rights + * + * @param securityToken + * @param userId the userId to look for + * @param extensionRights a wikitty with WikittyAuthorisation as extension <strong>OR</strong> meta-extension + * @param fqFieldName the field to look into, it should be one of the field of extension WikittyAuthorisation + * it has to be a FQN and may contain an extension-name if using meta-extension + * @param considerEmptyGroupAsMembership if true, an empty field value will be considered as + * "every-one is in the group". Most of the time, it will be false but true should be + * passed for "reader" level because user has right to read if he belongs to "reader" OR + * if reader is empty + * @return true if userId appear in the single/list of group/user of given field + */ + protected boolean isMember(String securityToken, String userId, + Wikitty extensionRights, String fqFieldName, boolean considerEmptyGroupAsMembership) { + + String extensionName = WikittyUtil.getExtensionNameFromFQFieldName(fqFieldName); + String fieldName = WikittyUtil.getFieldNameFromFQFieldName(fqFieldName); + + Set<String> groupOrUser = extensionRights.getFieldAsSet(extensionName, + fieldName, + String.class); + + boolean isMember; + if (groupOrUser == null || groupOrUser.isEmpty()) { + isMember = considerEmptyGroupAsMembership; + } else { + isMember = isMember(securityToken, userId, groupOrUser); + } + + if ( ! isMember) { + // user don't have right on current object, check parent right + String parentId = WikittyAuthorisationHelper.getParent(extensionRights); + if (parentId != null) { + Wikitty parent = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, parentId); + if (parent != null) { + isMember = isMember(securityToken, userId, parent, fqFieldName); + } + } + } + return isMember; + } + + /** check if a given user belong to the group of app-admins. */ + protected boolean isAppAdmin(String securityToken, String userId) { + // si le group n'existe pas alors tout le monde est admin + boolean result = true; + Wikitty group = getAppAdminGroup(securityToken); + if (group != null) { + Set<String> ids = WikittyGroupHelper.getMembers(group); + result = isMember(securityToken, userId, ids); + } + return result; + } + + /** get the wikitty with extension WikittyGroup that contains all app-admin. */ + protected Wikitty getAppAdminGroup(String securityToken) { + // on a deja fait la recherche precedement, on essaie de reutilise + // le meme id + Wikitty group = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, appAdminGroupId); + if (group == null) { + // 1er fois, on le recherche + WikittyQuery criteria = new WikittyQueryMaker() + .eq(WikittyGroup.FQ_FIELD_WIKITTYGROUP_NAME, + WikittySecurityHelper.WIKITTY_APPADMIN_GROUP_NAME).end(); + String groupId = getDelegate().findByQuery( + securityToken, Collections.singletonList(criteria)).get(0); + appAdminGroupId = groupId; + group = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, appAdminGroupId); + } + + return group; + } + + /** + * Verifie recursivement si un utilisateur est dans un groupe qui peut etre + * constitue d'autre groupe ou d'utilisateur + * + * @param userId l'utilisateur recherche + * @param groupOrUser la liste des id d'utilisateurs ou d'autres groupes + * @return vrai si userId est retrouve, false sinon + */ + protected boolean isMember( + String securityToken, String userId, Set<String> groupOrUser) { + if (groupOrUser != null) { + for (String id : groupOrUser) { + if (StringUtils.equals(id, userId)) { + // on a l'id du user, on l'autorise + return true; + } else { + // sinon, on charge l'objet car ca pourrait etre un groupe + // dans lequel il faut cherche le user + Wikitty groupWikitty = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, id); + if (groupWikitty != null && + WikittyGroupHelper.hasExtension(groupWikitty)) { + Set<String> members = + WikittyGroupHelper.getMembers(groupWikitty); + return isMember(securityToken, userId, members); + } + } + } + } + return false; // not found in groupOrUser + } + + /** + * restore the wikitty authorisation attached to given extension. + * + * @return a wikitty with WikittyAuthorisation extension, or null if given + * extension has no security policy attached + */ + protected Wikitty restoreExtensionAuthorisation(String securityToken, + WikittyExtension extension) { + return restoreExtensionAuthorisation(securityToken, extension.getName()); + } + + /** + * restore the wikitty authorisation attached to given extension. + * + * @return a wikitty with WikittyAuthorisation extension, or null if given + * extension has no security policy attached + */ + protected Wikitty restoreExtensionAuthorisation(String securityToken, + String extensionName) { + String wikittyAuthorisationId = WikittyMetaExtensionUtil.generateId( + WikittyAuthorisation.EXT_WIKITTYAUTHORISATION, extensionName); + Wikitty wikittyAuthorisation = WikittyServiceEnhanced.restore( + getDelegate(), securityToken, wikittyAuthorisationId); + if (wikittyAuthorisation == null) { + log.debug(extensionName + " has no authorization attached"); + } + return wikittyAuthorisation; + } + +} Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.java 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurity.java 2012-01-31 16:31:51 UTC (rev 1395) @@ -67,7 +67,7 @@ * * Last update: $Date$ * by : $Author$ - * @deprecated since 3.4 use WikittyServiceAuthentication and WikittyServiceAuthorization + * @deprecated since 3.4 use WikittyServiceAuthentication and WikittyServiceAuthorisation */ @Deprecated public class WikittyServiceSecurity extends WikittyServiceDelegator { Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthentication.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthentication.java 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthentication.java 2012-01-31 16:31:51 UTC (rev 1395) @@ -10,7 +10,7 @@ * * Last update: $Date$ * by : $Author$ - * @deprecated since 3.4 use WikittyServiceAuthentication and WikittyServiceAuthorization + * @deprecated since 3.4 use WikittyServiceAuthentication and WikittyServiceAuthorisation */ @Deprecated public interface WikittyServiceSecurityExternalAuthentication { Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthenticationLDAP.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthenticationLDAP.java 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceSecurityExternalAuthenticationLDAP.java 2012-01-31 16:31:51 UTC (rev 1395) @@ -19,7 +19,7 @@ * * Last update: $Date$ * by : $Author$ - * @deprecated since 3.4 use WikittyServiceAuthenticationLDAP and WikittyServiceAuthorization + * @deprecated since 3.4 use WikittyServiceAuthenticationLDAP and WikittyServiceAuthorisation */ @Deprecated public class WikittyServiceSecurityExternalAuthenticationLDAP Modified: trunk/wikitty-api/src/main/resources/wikitty-config-sample-client.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-client.properties 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-client.properties 2012-01-31 16:31:51 UTC (rev 1395) @@ -25,7 +25,7 @@ wikitty.WikittyService.components=org.nuiton.wikitty.services.WikittyServiceHessianClient,\ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ -org.nuiton.wikitty.services.WikittyServiceAuthorization +org.nuiton.wikitty.services.WikittyServiceAuthorisation wikitty.WikittyServiceNotifier.components=org.nuiton.wikitty.services.XMPPNotifierTransporter wikitty.WikittyServiceCached.components=org.nuiton.wikitty.services.WikittyCacheJCS wikitty.service.cache.allwaysRestoreCopies=false Modified: trunk/wikitty-api/src/main/resources/wikitty-config-sample-inmemory.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-inmemory.properties 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-inmemory.properties 2012-01-31 16:31:51 UTC (rev 1395) @@ -36,7 +36,7 @@ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ org.nuiton.wikitty.services.WikittyServiceAuthentication,\ -org.nuiton.wikitty.services.WikittyServiceAuthorization +org.nuiton.wikitty.services.WikittyServiceAuthorisation wikitty.WikittyServiceStorage.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ org.nuiton.wikitty.jdbc.WikittyStorageJDBC,\ org.nuiton.wikitty.storage.solr.WikittySearchEngineSolr Modified: trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-server-slave.properties 2012-01-31 16:31:51 UTC (rev 1395) @@ -38,7 +38,7 @@ org.nuiton.wikitty.services.WikittyServiceSlave,\ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ -org.nuiton.wikitty.services.WikittyServiceAuthorization,\ +org.nuiton.wikitty.services.WikittyServiceAuthorisation,\ org.nuiton.wikitty.services.WikittyServiceHessianServer wikitty.WikittyServiceStorage.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ org.nuiton.wikitty.jdbc.WikittyStorageJDBC,\ Modified: trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-server.properties 2012-01-31 16:31:51 UTC (rev 1395) @@ -38,7 +38,7 @@ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ org.nuiton.wikitty.services.WikittyServiceAuthentication,\ -org.nuiton.wikitty.services.WikittyServiceAuthorization,\ +org.nuiton.wikitty.services.WikittyServiceAuthorisation,\ org.nuiton.wikitty.services.WikittyServiceHessianServer wikitty.WikittyServiceStorage.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ org.nuiton.wikitty.jdbc.WikittyStorageJDBC,\ Modified: trunk/wikitty-api/src/main/resources/wikitty-config-sample-standalone.properties =================================================================== --- trunk/wikitty-api/src/main/resources/wikitty-config-sample-standalone.properties 2012-01-30 18:21:23 UTC (rev 1394) +++ trunk/wikitty-api/src/main/resources/wikitty-config-sample-standalone.properties 2012-01-31 16:31:51 UTC (rev 1395) @@ -38,7 +38,7 @@ org.nuiton.wikitty.services.WikittyServiceNotifier,\ org.nuiton.wikitty.services.WikittyServiceCached,\ org.nuiton.wikitty.services.WikittyServiceAuthentication,\ -org.nuiton.wikitty.services.WikittyServiceAuthorization +org.nuiton.wikitty.services.WikittyServiceAuthorisation wikitty.WikittyServiceStorage.components=org.nuiton.wikitty.jdbc.WikittyExtensionStorageJDBC,\ org.nuiton.wikitty.jdbc.WikittyStorageJDBC,\ org.nuiton.wikitty.storage.solr.WikittySearchEngineSolr