Java tutorial
/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This 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 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.extension.internal.validator; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.lang3.EnumUtils; import org.xwiki.component.namespace.Namespace; import org.xwiki.component.namespace.NamespaceUtils; import org.xwiki.extension.Extension; import org.xwiki.extension.InstallException; import org.xwiki.extension.InstalledExtension; import org.xwiki.extension.UninstallException; import org.xwiki.extension.handler.ExtensionValidator; import org.xwiki.job.Request; import org.xwiki.model.EntityType; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.EntityReference; import org.xwiki.model.reference.EntityReferenceResolver; import org.xwiki.security.authorization.AccessDeniedException; import org.xwiki.security.authorization.AuthorizationManager; import org.xwiki.security.authorization.Right; /** * Base class helper to implement {@link ExtensionValidator}. * * @version $Id: c7bb36cc88bc971fe8d926a63a0f083312a4540a $ * @since 9.0RC1 */ public abstract class AbstractExtensionValidator implements ExtensionValidator { /** * The name of the property containing the reference of the current user. */ public static final String PROPERTY_USERREFERENCE = "user.reference"; /** * The name of the property containing the reference of the current author. */ public static final String PROPERTY_CALLERREFERENCE = "caller.reference"; /** * The name of the property indicating of rights should be checked. */ public static final String PROPERTY_CHECKRIGHTS = "checkrights"; @Inject protected AuthorizationManager authorization; @Inject @Named("relative") protected EntityReferenceResolver<String> resolver; protected Right entityRight = Right.PROGRAM; /** * @param property the property containing a user reference * @param request the request of the job currently being executed * @return the reference of the user found in the request */ public static DocumentReference getRequestUserReference(String property, Request request) { Object obj = request.getProperty(property); if (obj instanceof DocumentReference) { return (DocumentReference) obj; } return null; } protected void checkAccess(EntityReference reference, Right right, Request request) throws AccessDeniedException { // Context author checkAccess(PROPERTY_CALLERREFERENCE, reference, right, request); // Context user checkAccess(PROPERTY_USERREFERENCE, reference, right, request); } private void checkAccess(String propertyCallerreference, EntityReference reference, Right right, Request request) throws AccessDeniedException { if (request.getProperty(propertyCallerreference) != null) { this.authorization.checkAccess(right, getRequestUserReference(propertyCallerreference, request), reference); } } @Override public void checkInstall(Extension extension, String namespace, Request request) throws InstallException { if (request.getProperty(PROPERTY_CHECKRIGHTS) == Boolean.TRUE) { checkInstallInternal(extension, namespace, request); } } protected void checkAccess(Extension extension, String namespaceString, Request request) throws AccessDeniedException { checkAccess(this.entityRight, namespaceString, request); } protected void checkAccess(Right entityRight, String namespaceString, Request request) throws AccessDeniedException { Namespace namespace = NamespaceUtils.toNamespace(namespaceString); // Root namespace if (namespace == null) { checkRootRight(entityRight, request); return; } if (namespace.getType() != null) { // User if (namespace.getType().equals("user")) { EntityReference reference = this.resolver.resolve(namespace.getValue(), EntityType.DOCUMENT); checkUserRight(reference, request); return; } // Entity EntityType entityType = EnumUtils.getEnum(EntityType.class, namespace.getType().toUpperCase()); if (entityType != null) { EntityReference reference = this.resolver.resolve(namespace.getValue(), entityType); checkAccess(reference, entityRight, request); return; } } // Unknown namespace checkNamespaceRight(namespace, Right.PROGRAM, request); } protected void checkInstallInternal(Extension extension, String namespace, Request request) throws InstallException { try { checkAccess(extension, namespace, request); } catch (AccessDeniedException e) { throw new InstallException(String.format("Install of extension [%s] is not allowed", extension.getId()), e); } } private void checkRootRight(Right entityRight, Request request) throws AccessDeniedException { // Need programming right for root namespace checkAccess(null, entityRight, request); } private void checkUserRight(EntityReference reference, Request request) throws AccessDeniedException { // Context author checkUserAccess(PROPERTY_CALLERREFERENCE, reference, request); // Context user checkUserAccess(PROPERTY_USERREFERENCE, reference, request); } private void checkUserAccess(String property, EntityReference reference, Request request) throws AccessDeniedException { if (request.getProperty(property) != null) { // Allow a user to install an extension in its own namespace DocumentReference currentAuthorReference = getRequestUserReference(property, request); if (!currentAuthorReference.equals(reference)) { // Need programming right to register an extension in another user namespace checkAccess(null, Right.PROGRAM, request); } } } private void checkNamespaceRight(Namespace namespace, Right program, Request request) throws AccessDeniedException { // Check programming right by default checkAccess(null, Right.PROGRAM, request); } @Override public void checkUninstall(InstalledExtension extension, String namespace, Request request) throws UninstallException { if (request.getProperty(PROPERTY_CHECKRIGHTS) == Boolean.TRUE) { checkUninstallInternal(extension, namespace, request); } } protected void checkUninstallInternal(InstalledExtension extension, String namespace, Request request) throws UninstallException { try { checkAccess(extension, namespace, request); } catch (AccessDeniedException e) { throw new UninstallException( String.format("Uninstall of extension [%s] is not allowed", extension.getId()), e); } } }