Package org.apache.jackrabbit.core

Source Code of org.apache.jackrabbit.core.ProtectedItemModifier

/*
* 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.jackrabbit.core;

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemExistsException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Value;

import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.nodetype.NodeDefinitionImpl;
import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
import org.apache.jackrabbit.core.retention.RetentionManagerImpl;
import org.apache.jackrabbit.core.security.AccessManager;
import org.apache.jackrabbit.core.security.authorization.Permission;
import org.apache.jackrabbit.core.security.authorization.acl.ACLEditor;
import org.apache.jackrabbit.core.security.user.UserManagerImpl;
import org.apache.jackrabbit.core.state.ChildNodeEntry;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.value.InternalValue;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;

/**
* <code>SecurityItemModifier</code>: An abstract helper class to allow classes
* of the security API residing outside of the core package to modify and remove
* protected items for security. The protected item definitions are required in
* order not to have security relevant content being changed through common
* item operations but forcing the usage of the security API. The latter asserts
* that implementation specific constraints are not violated.
*/
public abstract class ProtectedItemModifier {

    private static final int DEFAULT_PERM_CHECK = -1;
    private final int permission;

    protected ProtectedItemModifier() {
        this(DEFAULT_PERM_CHECK);
    }

    protected ProtectedItemModifier(int permission) {
        Class cl = getClass();
        if (!(UserManagerImpl.class.isAssignableFrom(cl) ||
              RetentionManagerImpl.class.isAssignableFrom(cl) ||
              ACLEditor.class.isAssignableFrom(cl) ||
              org.apache.jackrabbit.core.security.authorization.principalbased.ACLEditor.class.isAssignableFrom(cl))) {
            throw new IllegalArgumentException("Only UserManagerImpl, RetentionManagerImpl and ACLEditor may extend from the ProtectedItemModifier");
        }
        this.permission = permission;
    }

    protected NodeImpl addNode(NodeImpl parentImpl, Name name, Name ntName) throws RepositoryException {
        checkPermission(parentImpl, name, getPermission(true, false));
        // validation: make sure Node is not locked or checked-in.
        parentImpl.checkSetProperty();

        NodeTypeImpl nodeType = parentImpl.session.getNodeTypeManager().getNodeType(ntName);
        NodeDefinitionImpl def = parentImpl.getApplicableChildNodeDefinition(name, ntName);

        // check for name collisions
        // TODO: improve. copied from NodeImpl
        NodeState thisState = (NodeState) parentImpl.getItemState();
        ChildNodeEntry cne = thisState.getChildNodeEntry(name, 1);
        if (cne != null) {
            // there's already a child node entry with that name;
            // check same-name sibling setting of new node
            if (!def.allowsSameNameSiblings()) {
                throw new ItemExistsException();
            }
            // check same-name sibling setting of existing node
            NodeId newId = cne.getId();
            NodeImpl n = (NodeImpl) parentImpl.session.getItemManager().getItem(newId);
            if (!n.getDefinition().allowsSameNameSiblings()) {
                throw new ItemExistsException();
            }
        }

        return parentImpl.createChildNode(name, def, nodeType, null);
    }

    protected Property setProperty(NodeImpl parentImpl, Name name, Value value) throws RepositoryException {
        return setProperty(parentImpl, name, value, false);
    }

    protected Property setProperty(NodeImpl parentImpl, Name name, Value value, boolean ignorePermissions) throws RepositoryException {
        if (!ignorePermissions) {
            checkPermission(parentImpl, name, getPermission(false, false));
        }
        // validation: make sure Node is not locked or checked-in.
        parentImpl.checkSetProperty();
        InternalValue intVs = InternalValue.create(value, parentImpl.session);
        return parentImpl.internalSetProperty(name, intVs);
    }

    protected Property setProperty(NodeImpl parentImpl, Name name, Value[] values) throws RepositoryException {
        checkPermission(parentImpl, name, getPermission(false, false));
        // validation: make sure Node is not locked or checked-in.
        parentImpl.checkSetProperty();
        InternalValue[] intVs = new InternalValue[values.length];
        for (int i = 0; i < values.length; i++) {
            intVs[i] = InternalValue.create(values[i], parentImpl.session);
        }
        return parentImpl.internalSetProperty(name, intVs);
    }

    protected void removeItem(ItemImpl itemImpl) throws RepositoryException {
        NodeImpl n;
        if (itemImpl.isNode()) {
            n = (NodeImpl) itemImpl;
        } else {
            n = (NodeImpl) itemImpl.getParent();
        }
        checkPermission(itemImpl, getPermission(itemImpl.isNode(), true));
        // validation: make sure Node is not locked or checked-in.
        n.checkSetProperty();
        itemImpl.internalRemove(true);
    }

    protected void markModified(NodeImpl parentImpl) throws RepositoryException {
        parentImpl.getOrCreateTransientItemState();
    }

    private void checkPermission(ItemImpl item, int perm) throws RepositoryException {
        if (perm > Permission.NONE) {
            SessionImpl sImpl = (SessionImpl) item.getSession();
            AccessManager acMgr = sImpl.getAccessManager();

            Path path = item.getPrimaryPath();
            acMgr.checkPermission(path, perm);
        }
    }

    private void checkPermission(NodeImpl node, Name childName, int perm) throws RepositoryException {
        if (perm > Permission.NONE) {
            SessionImpl sImpl = (SessionImpl) node.getSession();
            AccessManager acMgr = sImpl.getAccessManager();

            boolean isGranted = acMgr.isGranted(node.getPrimaryPath(), childName, perm);
            if (!isGranted) {
                throw new AccessDeniedException("Permission denied.");
            }
        }
    }

    private int getPermission(boolean isNode, boolean isRemove) {
        if (permission < Permission.NONE) {
            if (isNode) {
                return (isRemove) ? Permission.REMOVE_NODE : Permission.ADD_NODE;
            } else {
                return (isRemove) ? Permission.REMOVE_PROPERTY : Permission.SET_PROPERTY;
            }
        } else {
            return permission;
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.core.ProtectedItemModifier

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.