Package org.apache.sling.jcr.jackrabbit.server.impl.security

Source Code of org.apache.sling.jcr.jackrabbit.server.impl.security.PluggableDefaultAccessManager

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.sling.jcr.jackrabbit.server.impl.security;

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.security.auth.Subject;

import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.id.ItemId;
import org.apache.jackrabbit.core.security.AMContext;
import org.apache.jackrabbit.core.security.DefaultAccessManager;
import org.apache.jackrabbit.core.security.authorization.AccessControlProvider;
import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.sling.jcr.jackrabbit.server.impl.AccessManagerFactoryTracker;
import org.apache.sling.jcr.jackrabbit.server.impl.Activator;
import org.apache.sling.jcr.jackrabbit.server.security.accessmanager.AccessManagerPlugin;
import org.apache.sling.jcr.jackrabbit.server.security.accessmanager.AccessManagerPluginFactory;
import org.apache.sling.jcr.jackrabbit.server.security.accessmanager.WorkspaceAccessManagerPlugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Allows to plugin a custom <code>AccessManager</code> as an OSGi bundle:
* <ol>
*   <li>Set this class as <code>AccessManager</code> in your <code>repository.xml</code></li>
*   <li>Implement <code>o.a.s.j.j.s.s.a.AccessManagerPluginFactory</code></li>
* </ol>
*
* <p>If <code>PluggableDefaultAccessManager</code> is specified in <code>repository.xml</code>, and no
* implementation of <code>AccessManagerPluginFactory</code> exists, all calls will fall back
* to <code>DefaultAccessManager</code>.</p>
*
* <p>See also <a href="https://issues.apache.org/jira/browse/SLING-880">SLING-880</a></p>
* @see AccessManagerPluginFactory
*/
public class PluggableDefaultAccessManager extends DefaultAccessManager {

    private AccessManagerPlugin accessManagerPlugin;
    private NamePathResolver namePathResolver;
    private static final Logger log = LoggerFactory.getLogger(PluggableDefaultAccessManager.class);
    protected AccessManagerPluginFactory accessManagerFactory;
    protected AccessManagerFactoryTracker accessManagerFactoryTracker;
    private Session session;
    private Subject subject;
    // only warn once, then only warn on debug level.
    private static int pluginWarning = 0;

    /**
     * the hierarchy manager used to resolve path from itemId
     */
    private HierarchyManager hierMgr;

    public PluggableDefaultAccessManager() {
    }

    protected AccessManagerPluginFactory getAccessManagerFactory() {
        return accessManagerFactoryTracker.getFactory(this);
    }

    public void init(AMContext context) throws AccessDeniedException, Exception {
        this.init(context, null, null);
    }

    public void init(AMContext context, AccessControlProvider acProvider, WorkspaceAccessManager wspAccessMgr) throws AccessDeniedException, Exception {
        accessManagerFactoryTracker = Activator.getAccessManagerFactoryTracker();
        accessManagerFactory = getAccessManagerFactory();
        if (accessManagerFactory != null) {
            this.accessManagerPlugin = accessManagerFactory.getAccessManager();
        }
        this.sanityCheck();
        super.init(context, acProvider, wspAccessMgr);
        this.namePathResolver = context.getNamePathResolver();
        if (this.accessManagerPlugin != null) {
            this.accessManagerPlugin.init(context.getSubject(), context.getSession());
        }
        this.session = context.getSession();
        this.subject = context.getSubject();

        hierMgr = context.getHierarchyManager();
    }

    public void close() throws Exception {
        this.accessManagerFactoryTracker.unregister(this);
        super.close();
        if (this.accessManagerPlugin != null) {
            this.accessManagerPlugin.close();
        }
    }

    public void endSession() {
        if (this.session != null && this.session.isLive()) {
            this.session.logout();
        }
    }

    public void checkPermission(ItemId id, int permissions) throws AccessDeniedException, ItemNotFoundException, RepositoryException {
        this.sanityCheck();
        super.checkPermission(id, permissions);
    }

    public boolean isGranted(ItemId id, int permissions) throws ItemNotFoundException, RepositoryException {
        return super.isGranted(id, permissions);
    }

    public boolean isGranted(Path absPath, int permissions) throws RepositoryException {
        if (this.sanityCheck()) {
            return this.accessManagerPlugin.isGranted(namePathResolver.getJCRPath(absPath), permissions);
        }
        return super.isGranted(absPath, permissions);
    }

    public boolean isGranted(Path parentPath, Name childName, int permissions) throws RepositoryException {
        return super.isGranted(parentPath, childName, permissions);
    }

    public boolean canRead(Path itemPath, ItemId itemId) throws RepositoryException {
        if (this.sanityCheck()) {
          String resolvedPath = null;
          if (itemPath != null) {
            resolvedPath = namePathResolver.getJCRPath(itemPath);
          } else if (itemId != null) {
            Path path = hierMgr.getPath(itemId);
            resolvedPath = namePathResolver.getJCRPath(path);
          }
            return this.accessManagerPlugin.canRead(resolvedPath);
        }
        return super.canRead(itemPath, itemId);
    }

    public boolean canAccess(String workspaceName) throws RepositoryException {
        WorkspaceAccessManagerPlugin plugin = null;
        if (this.sanityCheck()) {
            plugin = this.accessManagerPlugin.getWorkspaceAccessManager();
        }
        if (plugin != null) {
            return plugin.canAccess(workspaceName);
        }
        return super.canAccess(workspaceName);
    }

    private boolean sanityCheck() throws RepositoryException {
        if (this.accessManagerPlugin == null) {
            AccessManagerPluginFactory factory = this.accessManagerFactoryTracker.getFactory(this);
            if (factory == null) {
                if ( pluginWarning  == 0 ) {
                    pluginWarning++;
                    log.warn("No pluggable AccessManager available, falling back to DefaultAccessManager");
                } else {
                    log.debug("No pluggable AccessManager available, falling back to DefaultAccessManager");
                }
                return false;

            }
            this.accessManagerPlugin = factory.getAccessManager();
            try {
                this.accessManagerPlugin.init(this.subject, this.session);
            } catch (Exception e) {
                throw new RepositoryException(e);
            }
        }
        return true;
    }
}
TOP

Related Classes of org.apache.sling.jcr.jackrabbit.server.impl.security.PluggableDefaultAccessManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.