Package org.apache.jackrabbit.core.security

Examples of org.apache.jackrabbit.core.security.AccessManager


        since there is no specific privilege for reordering child nodes,
        test if the the node to be reordered can be removed and added,
        i.e. treating reorder similar to a move.
        TODO: properly deal with sns in which case the index would change upon reorder.
        */
        AccessManager acMgr = sessionContext.getAccessManager();
        PathBuilder pb = new PathBuilder(getPrimaryPath());
        pb.addLast(srcName.getName(), srcName.getIndex());
        Path childPath = pb.getPath();
        if (!acMgr.isGranted(childPath, Permission.ADD_NODE | Permission.REMOVE_NODE)) {
            String msg = "Not allowed to reorder child node " + sessionContext.getJCRPath(childPath) + ".";
            log.debug(msg);
            throw new AccessDeniedException(msg);
        }

View Full Code Here


            throw new ItemExistsException(
                    "Same name siblings not allowed: " + existing);
        }

        // check permissions
        AccessManager acMgr = sessionContext.getAccessManager();
        if (!(acMgr.isGranted(getPrimaryPath(), Permission.REMOVE_NODE) &&
                acMgr.isGranted(parent.getPrimaryPath(), qName, Permission.ADD_NODE | Permission.NODE_TYPE_MNGMT))) {
            String msg = "Not allowed to rename node " + safeGetJCRPath() + " to " + newName;
            log.debug(msg);
            throw new AccessDeniedException(msg);
        }
View Full Code Here

    }

    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);
        }
    }
View Full Code Here

    }

    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.");
            }
        }
    }
View Full Code Here

        if (index == 0) {
            index = 1;
        }

        // check permissions
        AccessManager acMgr = getAccessManager();
        if (!(acMgr.isGranted(srcPath, Permission.REMOVE_NODE) &&
                acMgr.isGranted(destPath, Permission.ADD_NODE | Permission.NODE_TYPE_MNGMT))) {
            String msg = "Not allowed to move node " + srcAbsPath + " to " + destAbsPath;
            log.debug(msg);
            throw new AccessDeniedException(msg);
        }
View Full Code Here

         * note that the protected flag is checked in Node.addNode/Node.remove
         * (for adding/removing child entries of a node), in
         * Node.addMixin/removeMixin/setPrimaryType (for type changes on nodes)
         * and in Property.setValue (for properties to be modified).
         */
        AccessManager accessMgr = session.getAccessManager();
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        // walk through list of dirty transient items and validate each
        while (dirtyIter.hasNext()) {
            ItemState itemState = (ItemState) dirtyIter.next();
            ItemDefinition def;
            if (itemState.isNode()) {
                def = ntMgr.getNodeDefinition(((NodeState) itemState).getDefinitionId());
            } else {
                def = ntMgr.getPropertyDefinition(((PropertyState) itemState).getDefinitionId());
            }
            /* check permissions for non-protected items. protected items are
               only added through API methods which need to assert that
               permissions are not violated.
             */
            if (!def.isProtected()) {
                /* detect the effective set of modification:
                   - new added node -> add_node perm on the child
                   - new property added -> set_property permission
                   - property modified -> set_property permission
                   - modified nodes can be ignored for changes only included
                     child-item addition or removal or changes of protected
                     properties such as mixin-types which are covered separately
                   note: removed items are checked later on.
                */
                Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId());
                boolean isGranted = true;
                if (itemState.isNode()) {
                    if (itemState.getStatus() == ItemState.STATUS_NEW) {
                        isGranted = accessMgr.isGranted(path, Permission.ADD_NODE);
                    } // else: modified node (see comment above)
                } else {
                    // modified or new property: set_property permission
                    isGranted = accessMgr.isGranted(path, Permission.SET_PROPERTY);
                }

                if (!isGranted) {
                    String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to add or modify item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
            }

            if (itemState.isNode()) {
                // the transient item is a node
                NodeState nodeState = (NodeState) itemState;
                ItemId id = nodeState.getNodeId();
                NodeDefinition nodeDef = (NodeDefinition) def;
                // primary type
                NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName());
                // effective node type (primary type incl. mixins)
                EffectiveNodeType ent = getEffectiveNodeType(nodeState);
                /**
                 * if the transient node was added (i.e. if it is 'new') or if
                 * its primary type has changed, check its node type against the
                 * required node type in its definition
                 */
                if (nodeState.getStatus() == ItemState.STATUS_NEW
                        || !nodeState.getNodeTypeName().equals(
                            ((NodeState) nodeState.getOverlayedState()).getNodeTypeName())) {
                    NodeType[] nta = nodeDef.getRequiredPrimaryTypes();
                    for (int i = 0; i < nta.length; i++) {
                        NodeTypeImpl ntReq = (NodeTypeImpl) nta[i];
                        if (!(pnt.getQName().equals(ntReq.getQName())
                                || pnt.isDerivedFrom(ntReq.getQName()))) {
                            /**
                             * the transient node's primary node type does not
                             * satisfy the 'required primary types' constraint
                             */
                            String msg = itemMgr.safeGetJCRPath(id)
                                    + " must be of node type " + ntReq.getName();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }
                    }
                }

                // mandatory child properties
                PropDef[] pda = ent.getMandatoryPropDefs();
                for (int i = 0; i < pda.length; i++) {
                    PropDef pd = pda[i];
                    if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)
                            || pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                        /**
                         * todo FIXME workaround for mix:versionable:
                         * the mandatory properties are initialized at a
                         * later stage and might not exist yet
                         */
                        continue;
                    }
                    if (!nodeState.hasPropertyName(pd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory property " + pd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
                // mandatory child nodes
                NodeDef[] cnda = ent.getMandatoryNodeDefs();
                for (int i = 0; i < cnda.length; i++) {
                    NodeDef cnd = cnda[i];
                    if (!nodeState.hasChildNodeEntry(cnd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory child node " + cnd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
            } else {
                // the transient item is a property
                PropertyState propState = (PropertyState) itemState;
                ItemId propId = propState.getPropertyId();
                PropertyDefinitionImpl propDef = (PropertyDefinitionImpl) def;

                /**
                 * check value constraints
                 * (no need to check value constraints of protected properties
                 * as those are set by the implementation only, i.e. they
                 * cannot be set by the user through the api)
                 */
                if (!def.isProtected()) {
                    String[] constraints = propDef.getValueConstraints();
                    if (constraints != null) {
                        InternalValue[] values = propState.getValues();
                        try {
                            EffectiveNodeType.checkSetPropertyValueConstraints(
                                    propDef.unwrap(), values);
                        } catch (RepositoryException e) {
                            // repack exception for providing more verbose error message
                            String msg = itemMgr.safeGetJCRPath(propId) + ": " + e.getMessage();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }

                        /**
                         * need to manually check REFERENCE value constraints
                         * as this requires a session (target node needs to
                         * be checked)
                         */
                        if (constraints.length > 0
                                && propDef.getRequiredType() == PropertyType.REFERENCE) {
                            for (int i = 0; i < values.length; i++) {
                                boolean satisfied = false;
                                String constraintViolationMsg = null;
                                try {
                                    UUID targetUUID = values[i].getUUID();
                                    Node targetNode = session.getNodeByUUID(targetUUID);
                                    /**
                                     * constraints are OR-ed, i.e. at least one
                                     * has to be satisfied
                                     */
                                    for (int j = 0; j < constraints.length; j++) {
                                        /**
                                         * a REFERENCE value constraint specifies
                                         * the name of the required node type of
                                         * the target node
                                         */
                                        String ntName = constraints[j];
                                        if (targetNode.isNodeType(ntName)) {
                                            satisfied = true;
                                            break;
                                        }
                                    }
                                    if (!satisfied) {
                                        NodeType[] mixinNodeTypes = targetNode.getMixinNodeTypes();
                                        String[] targetMixins = new String[mixinNodeTypes.length];
                                        for (int j = 0; j < mixinNodeTypes.length; j++) {
                                            targetMixins[j] = mixinNodeTypes[j].getName();
                                        }
                                        String targetMixinsString = Text.implode(targetMixins, ", ");
                                        String constraintsString = Text.implode(constraints, ", ");
                                        constraintViolationMsg = itemMgr.safeGetJCRPath(propId)
                                                + ": is constraint to ["
                                                + constraintsString
                                                + "] but references [primaryType="
                                                + targetNode.getPrimaryNodeType().getName()
                                                + ", mixins="
                                                + targetMixinsString + "]";
                                    }
                                } catch (RepositoryException re) {
                                    String msg = itemMgr.safeGetJCRPath(propId)
                                            + ": failed to check REFERENCE value constraint";
                                    log.debug(msg);
                                    throw new ConstraintViolationException(msg, re);
                                }
                                if (!satisfied) {
                                    log.debug(constraintViolationMsg);
                                    throw new ConstraintViolationException(constraintViolationMsg);
                                }
                            }
                        }
                    }
                }

                /**
                 * no need to check the protected flag as this is checked
                 * in PropertyImpl.setValue(Value)
                 */
            }
        }

        // walk through list of removed transient items and check REMOVE permission
        while (removedIter.hasNext()) {
            ItemState itemState = (ItemState) removedIter.next();
            ItemDefinition def;
            if (itemState.isNode()) {
                def = ntMgr.getNodeDefinition(((NodeState) itemState).getDefinitionId());
            } else {
                def = ntMgr.getPropertyDefinition(((PropertyState) itemState).getDefinitionId());
            }
            if (!def.isProtected()) {
                Path path = stateMgr.getAtticAwareHierarchyMgr().getPath(itemState.getId());
                // check REMOVE permission
                int permission = (itemState.isNode()) ? Permission.REMOVE_NODE : Permission.REMOVE_PROPERTY;
                if (!accessMgr.isGranted(path, permission)) {
                    String msg = itemMgr.safeGetJCRPath(path)
                            + ": not allowed to remove item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
View Full Code Here

        if (index == 0) {
            index = 1;
        }

        // check permissions
        AccessManager acMgr = getAccessManager();
        if (!(acMgr.isGranted(srcPath, Permission.REMOVE_NODE) &&
                acMgr.isGranted(destPath, Permission.ADD_NODE | Permission.NODE_TYPE_MNGMT))) {
            String msg = "Not allowed to move node " + srcAbsPath + " to " + destAbsPath;
            log.debug(msg);
            throw new AccessDeniedException(msg);
        }
View Full Code Here

         * note that the protected flag is checked in Node.addNode/Node.remove
         * (for adding/removing child entries of a node), in
         * Node.addMixin/removeMixin/setPrimaryType (for type changes on nodes)
         * and in Property.setValue (for properties to be modified).
         */
        AccessManager accessMgr = session.getAccessManager();
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        // walk through list of dirty transient items and validate each
        while (dirtyIter.hasNext()) {
            ItemState itemState = dirtyIter.next();
            ItemDefinition def;
            if (itemState.isNode()) {
                def = ntMgr.getNodeDefinition(((NodeState) itemState).getDefinitionId());
            } else {
                def = ntMgr.getPropertyDefinition(((PropertyState) itemState).getDefinitionId());
            }
            /* check permissions for non-protected items. protected items are
               only added through API methods which need to assert that
               permissions are not violated.
             */
            if (!def.isProtected()) {
                /* detect the effective set of modification:
                   - new added node -> add_node perm on the child
                   - new property added -> set_property permission
                   - property modified -> set_property permission
                   - modified nodes can be ignored for changes only included
                     child-item addition or removal or changes of protected
                     properties such as mixin-types which are covered separately
                   note: removed items are checked later on.
                */
                Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId());
                boolean isGranted = true;
                if (itemState.isNode()) {
                    if (itemState.getStatus() == ItemState.STATUS_NEW) {
                        isGranted = accessMgr.isGranted(path, Permission.ADD_NODE);
                    } // else: modified node (see comment above)
                } else {
                    // modified or new property: set_property permission
                    isGranted = accessMgr.isGranted(path, Permission.SET_PROPERTY);
                }

                if (!isGranted) {
                    String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to add or modify item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
            }

            if (itemState.isNode()) {
                // the transient item is a node
                NodeState nodeState = (NodeState) itemState;
                ItemId id = nodeState.getNodeId();
                NodeDefinition nodeDef = (NodeDefinition) def;
                // primary type
                NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName());
                // effective node type (primary type incl. mixins)
                EffectiveNodeType ent = getEffectiveNodeType(nodeState);
                /**
                 * if the transient node was added (i.e. if it is 'new') or if
                 * its primary type has changed, check its node type against the
                 * required node type in its definition
                 */
                if (nodeState.getStatus() == ItemState.STATUS_NEW
                        || !nodeState.getNodeTypeName().equals(
                            ((NodeState) nodeState.getOverlayedState()).getNodeTypeName())) {
                    NodeType[] nta = nodeDef.getRequiredPrimaryTypes();
                    for (int i = 0; i < nta.length; i++) {
                        NodeTypeImpl ntReq = (NodeTypeImpl) nta[i];
                        if (!(pnt.getQName().equals(ntReq.getQName())
                                || pnt.isDerivedFrom(ntReq.getQName()))) {
                            /**
                             * the transient node's primary node type does not
                             * satisfy the 'required primary types' constraint
                             */
                            String msg = itemMgr.safeGetJCRPath(id)
                                    + " must be of node type " + ntReq.getName();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }
                    }
                }

                // mandatory child properties
                PropDef[] pda = ent.getMandatoryPropDefs();
                for (int i = 0; i < pda.length; i++) {
                    PropDef pd = pda[i];
                    if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)
                            || pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                        /**
                         * todo FIXME workaround for mix:versionable:
                         * the mandatory properties are initialized at a
                         * later stage and might not exist yet
                         */
                        continue;
                    }
                    if (!nodeState.hasPropertyName(pd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory property " + pd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
                // mandatory child nodes
                NodeDef[] cnda = ent.getMandatoryNodeDefs();
                for (int i = 0; i < cnda.length; i++) {
                    NodeDef cnd = cnda[i];
                    if (!nodeState.hasChildNodeEntry(cnd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory child node " + cnd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
            } else {
                // the transient item is a property
                PropertyState propState = (PropertyState) itemState;
                ItemId propId = propState.getPropertyId();
                PropertyDefinitionImpl propDef = (PropertyDefinitionImpl) def;

                /**
                 * check value constraints
                 * (no need to check value constraints of protected properties
                 * as those are set by the implementation only, i.e. they
                 * cannot be set by the user through the api)
                 */
                if (!def.isProtected()) {
                    String[] constraints = propDef.getValueConstraints();
                    if (constraints != null) {
                        InternalValue[] values = propState.getValues();
                        try {
                            EffectiveNodeType.checkSetPropertyValueConstraints(
                                    propDef.unwrap(), values);
                        } catch (RepositoryException e) {
                            // repack exception for providing more verbose error message
                            String msg = itemMgr.safeGetJCRPath(propId) + ": " + e.getMessage();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }

                        /**
                         * need to manually check REFERENCE value constraints
                         * as this requires a session (target node needs to
                         * be checked)
                         */
                        if (constraints.length > 0
                                && (propDef.getRequiredType() == PropertyType.REFERENCE
                                    || propDef.getRequiredType() == PropertyType.WEAKREFERENCE)) {
                            for (int i = 0; i < values.length; i++) {
                                boolean satisfied = false;
                                String constraintViolationMsg = null;
                                try {
                                    UUID targetUUID = values[i].getUUID();
                                    if (propDef.getRequiredType() == PropertyType.WEAKREFERENCE
                                        && !itemMgr.itemExists(new NodeId(targetUUID))) {
                                        // target of weakref doesn;t exist, skip
                                        continue;
                                    }
                                    Node targetNode = session.getNodeByUUID(targetUUID);
                                    /**
                                     * constraints are OR-ed, i.e. at least one
                                     * has to be satisfied
                                     */
                                    for (int j = 0; j < constraints.length; j++) {
                                        /**
                                         * a [WEAK]REFERENCE value constraint specifies
                                         * the name of the required node type of
                                         * the target node
                                         */
                                        String ntName = constraints[j];
                                        if (targetNode.isNodeType(ntName)) {
                                            satisfied = true;
                                            break;
                                        }
                                    }
                                    if (!satisfied) {
                                        NodeType[] mixinNodeTypes = targetNode.getMixinNodeTypes();
                                        String[] targetMixins = new String[mixinNodeTypes.length];
                                        for (int j = 0; j < mixinNodeTypes.length; j++) {
                                            targetMixins[j] = mixinNodeTypes[j].getName();
                                        }
                                        String targetMixinsString = Text.implode(targetMixins, ", ");
                                        String constraintsString = Text.implode(constraints, ", ");
                                        constraintViolationMsg = itemMgr.safeGetJCRPath(propId)
                                                + ": is constraint to ["
                                                + constraintsString
                                                + "] but references [primaryType="
                                                + targetNode.getPrimaryNodeType().getName()
                                                + ", mixins="
                                                + targetMixinsString + "]";
                                    }
                                } catch (RepositoryException re) {
                                    String msg = itemMgr.safeGetJCRPath(propId)
                                            + ": failed to check "
                                            + ((propDef.getRequiredType() == PropertyType.REFERENCE) ? "REFERENCE" : "WEAKREFERENCE")
                                            + " value constraint";
                                    log.debug(msg);
                                    throw new ConstraintViolationException(msg, re);
                                }
                                if (!satisfied) {
                                    log.debug(constraintViolationMsg);
                                    throw new ConstraintViolationException(constraintViolationMsg);
                                }
                            }
                        }
                    }
                }

                /**
                 * no need to check the protected flag as this is checked
                 * in PropertyImpl.setValue(Value)
                 */
            }
        }

        // walk through list of removed transient items and check REMOVE permission
        while (removedIter.hasNext()) {
            ItemState itemState = removedIter.next();
            ItemDefinition def;
            if (itemState.isNode()) {
                def = ntMgr.getNodeDefinition(((NodeState) itemState).getDefinitionId());
            } else {
                def = ntMgr.getPropertyDefinition(((PropertyState) itemState).getDefinitionId());
            }
            if (!def.isProtected()) {
                Path path = stateMgr.getAtticAwareHierarchyMgr().getPath(itemState.getId());
                // check REMOVE permission
                int permission = (itemState.isNode()) ? Permission.REMOVE_NODE : Permission.REMOVE_PROPERTY;
                if (!accessMgr.isGranted(path, permission)) {
                    String msg = itemMgr.safeGetJCRPath(path)
                            + ": not allowed to remove item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
View Full Code Here

     * and in Property.setValue (for properties to be modified).
     */
    private void validateTransientItems(Iterable<ItemState> dirty, Iterable<ItemState> removed)
            throws AccessDeniedException, ConstraintViolationException,
            RepositoryException {
        AccessManager accessMgr = session.getAccessManager();
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        // walk through list of dirty transient items and validate each
        for (ItemState itemState : dirty) {
            ItemDefinition def;
            if (itemState.isNode()) {
                def = itemMgr.getDefinition((NodeState) itemState);
            } else {
                def = itemMgr.getDefinition((PropertyState) itemState);
            }
            /* check permissions for non-protected items. protected items are
               only added through API methods which need to assert that
               permissions are not violated.
             */
            if (!def.isProtected()) {
                /* detect the effective set of modification:
                   - new added node -> add_node perm on the child
                   - new property added -> set_property permission
                   - property modified -> set_property permission
                   - modified nodes can be ignored for changes only included
                     child-item addition or removal or changes of protected
                     properties such as mixin-types which are covered separately
                   note: removed items are checked later on.
                   note: reordering of child nodes has been covered upfront as
                         this information isn't available here.
                */
                Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId());
                boolean isGranted = true;
                if (itemState.isNode()) {
                    if (itemState.getStatus() == ItemState.STATUS_NEW) {
                        isGranted = accessMgr.isGranted(path, Permission.ADD_NODE);
                    } // else: modified node (see comment above)
                } else {
                    // modified or new property: set_property permission
                    isGranted = accessMgr.isGranted(path, Permission.SET_PROPERTY);
                }

                if (!isGranted) {
                    String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to add or modify item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
            }

            if (itemState.isNode()) {
                // the transient item is a node
                NodeState nodeState = (NodeState) itemState;
                ItemId id = nodeState.getNodeId();
                NodeDefinition nodeDef = (NodeDefinition) def;
                // primary type
                NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName());
                // effective node type (primary type incl. mixins)
                EffectiveNodeType ent = getEffectiveNodeType(nodeState);
                /**
                 * if the transient node was added (i.e. if it is 'new') or if
                 * its primary type has changed, check its node type against the
                 * required node type in its definition
                 */
                if (nodeState.getStatus() == ItemState.STATUS_NEW
                        || !nodeState.getNodeTypeName().equals(
                            ((NodeState) nodeState.getOverlayedState()).getNodeTypeName())) {
                    for (NodeType ntReq : nodeDef.getRequiredPrimaryTypes()) {
                        Name ntName = ((NodeTypeImpl) ntReq).getQName();
                        if (!(pnt.getQName().equals(ntName)
                                || pnt.isDerivedFrom(ntName))) {
                            /**
                             * the transient node's primary node type does not
                             * satisfy the 'required primary types' constraint
                             */
                            String msg = itemMgr.safeGetJCRPath(id)
                                    + " must be of node type " + ntReq.getName();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }
                    }
                }

                // mandatory child properties
                for (QPropertyDefinition pd : ent.getMandatoryPropDefs()) {
                    if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)
                            || pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                        /**
                         * todo FIXME workaround for mix:versionable:
                         * the mandatory properties are initialized at a
                         * later stage and might not exist yet
                         */
                        continue;
                    }
                    String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory property " + pd.getName()
                                + " does not exist";
                    if (!nodeState.hasPropertyName(pd.getName())) {
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    } else {
                        /*
                        there exists a property with the mandatory-name.
                        make sure the property really has the expected mandatory
                        property definition (and not another non-mandatory def,
                        such as e.g. multivalued residual instead of single-value
                        mandatory, named def).
                        */
                        PropertyId pi = new PropertyId(nodeState.getNodeId(), pd.getName());
                        ItemData childData = itemMgr.getItemData(pi, null, false);
                        if (!childData.getDefinition().isMandatory()) {
                            throw new ConstraintViolationException(msg);
                        }
                    }
                }
                // mandatory child nodes
                for (QItemDefinition cnd : ent.getMandatoryNodeDefs()) {
                    String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory child node " + cnd.getName()
                                + " does not exist";
                    if (!nodeState.hasChildNodeEntry(cnd.getName())) {                     
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    } else {
                        /*
                        there exists a child node with the mandatory-name.
                        make sure the node really has the expected mandatory
                        node definition.
                        */
                        boolean hasMandatoryChild = false;
                        for (ChildNodeEntry cne : nodeState.getChildNodeEntries(cnd.getName())) {
                            ItemData childData = itemMgr.getItemData(cne.getId(), null, false);
                            if (childData.getDefinition().isMandatory()) {
                                hasMandatoryChild = true;
                                break;
                            }
                        }
                        if (!hasMandatoryChild) {
                            throw new ConstraintViolationException(msg);
                        }
                    }
                }
            } else {
                // the transient item is a property
                PropertyState propState = (PropertyState) itemState;
                ItemId propId = propState.getPropertyId();
                org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl propDef = (org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl) def;

                /**
                 * check value constraints
                 * (no need to check value constraints of protected properties
                 * as those are set by the implementation only, i.e. they
                 * cannot be set by the user through the api)
                 */
                if (!def.isProtected()) {
                    String[] constraints = propDef.getValueConstraints();
                    if (constraints != null) {
                        InternalValue[] values = propState.getValues();
                        try {
                            EffectiveNodeType.checkSetPropertyValueConstraints(
                                    propDef.unwrap(), values);
                        } catch (RepositoryException e) {
                            // repack exception for providing more verbose error message
                            String msg = itemMgr.safeGetJCRPath(propId) + ": " + e.getMessage();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }

                        /**
                         * need to manually check REFERENCE value constraints
                         * as this requires a session (target node needs to
                         * be checked)
                         */
                        if (constraints.length > 0
                                && (propDef.getRequiredType() == PropertyType.REFERENCE
                                    || propDef.getRequiredType() == PropertyType.WEAKREFERENCE)) {
                            for (InternalValue internalV : values) {
                                boolean satisfied = false;
                                String constraintViolationMsg = null;
                                try {
                                    NodeId targetId = internalV.getNodeId();
                                    if (propDef.getRequiredType() == PropertyType.WEAKREFERENCE
                                        && !itemMgr.itemExists(targetId)) {
                                        // target of weakref doesn;t exist, skip
                                        continue;
                                    }
                                    Node targetNode = session.getNodeById(targetId);
                                    /**
                                     * constraints are OR-ed, i.e. at least one
                                     * has to be satisfied
                                     */
                                    for (String constrNtName : constraints) {
                                        /**
                                         * a [WEAK]REFERENCE value constraint specifies
                                         * the name of the required node type of
                                         * the target node
                                         */
                                        if (targetNode.isNodeType(constrNtName)) {
                                            satisfied = true;
                                            break;
                                        }
                                    }
                                    if (!satisfied) {
                                        NodeType[] mixinNodeTypes = targetNode.getMixinNodeTypes();
                                        String[] targetMixins = new String[mixinNodeTypes.length];
                                        for (int j = 0; j < mixinNodeTypes.length; j++) {
                                            targetMixins[j] = mixinNodeTypes[j].getName();
                                        }
                                        String targetMixinsString = Text.implode(targetMixins, ", ");
                                        String constraintsString = Text.implode(constraints, ", ");
                                        constraintViolationMsg = itemMgr.safeGetJCRPath(propId)
                                                + ": is constraint to ["
                                                + constraintsString
                                                + "] but references [primaryType="
                                                + targetNode.getPrimaryNodeType().getName()
                                                + ", mixins="
                                                + targetMixinsString + "]";
                                    }
                                } catch (RepositoryException re) {
                                    String msg = itemMgr.safeGetJCRPath(propId)
                                            + ": failed to check "
                                            + ((propDef.getRequiredType() == PropertyType.REFERENCE) ? "REFERENCE" : "WEAKREFERENCE")
                                            + " value constraint";
                                    log.debug(msg);
                                    throw new ConstraintViolationException(msg, re);
                                }
                                if (!satisfied) {
                                    log.debug(constraintViolationMsg);
                                    throw new ConstraintViolationException(constraintViolationMsg);
                                }
                            }
                        }
                    }
                }

                /**
                 * no need to check the protected flag as this is checked
                 * in PropertyImpl.setValue(Value)
                 */
            }
        }

        // walk through list of removed transient items and check REMOVE permission
        for (ItemState itemState : removed) {
            QItemDefinition def;
            if (itemState.isNode()) {
                def = itemMgr.getDefinition((NodeState) itemState).unwrap();
            } else {
                def = itemMgr.getDefinition((PropertyState) itemState).unwrap();
            }
            if (!def.isProtected()) {
                Path path = stateMgr.getAtticAwareHierarchyMgr().getPath(itemState.getId());
                // check REMOVE permission
                int permission = (itemState.isNode()) ? Permission.REMOVE_NODE : Permission.REMOVE_PROPERTY;
                if (!accessMgr.isGranted(path, permission)) {
                    String msg = itemMgr.safeGetJCRPath(path)
                            + ": not allowed to remove item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
View Full Code Here

         * note that the protected flag is checked in Node.addNode/Node.remove
         * (for adding/removing child entries of a node), in
         * Node.addMixin/removeMixin/setPrimaryType (for type changes on nodes)
         * and in Property.setValue (for properties to be modified).
         */
        AccessManager accessMgr = session.getAccessManager();
        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
        // walk through list of dirty transient items and validate each
        while (dirtyIter.hasNext()) {
            ItemState itemState = (ItemState) dirtyIter.next();
            ItemDefinition def;
            if (itemState.isNode()) {
                def = itemMgr.getDefinition((NodeState) itemState);
            } else {
                def = itemMgr.getDefinition((PropertyState) itemState);
            }
            /* check permissions for non-protected items. protected items are
               only added through API methods which need to assert that
               permissions are not violated.
             */
            if (!def.isProtected()) {
                /* detect the effective set of modification:
                   - new added node -> add_node perm on the child
                   - new property added -> set_property permission
                   - property modified -> set_property permission
                   - modified nodes can be ignored for changes only included
                     child-item addition or removal or changes of protected
                     properties such as mixin-types which are covered separately
                   note: removed items are checked later on.
                */
                Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId());
                boolean isGranted = true;
                if (itemState.isNode()) {
                    if (itemState.getStatus() == ItemState.STATUS_NEW) {
                        isGranted = accessMgr.isGranted(path, Permission.ADD_NODE);
                    } // else: modified node (see comment above)
                } else {
                    // modified or new property: set_property permission
                    isGranted = accessMgr.isGranted(path, Permission.SET_PROPERTY);
                }

                if (!isGranted) {
                    String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to add or modify item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
            }

            if (itemState.isNode()) {
                // the transient item is a node
                NodeState nodeState = (NodeState) itemState;
                ItemId id = nodeState.getNodeId();
                NodeDefinition nodeDef = (NodeDefinition) def;
                // primary type
                NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName());
                // effective node type (primary type incl. mixins)
                EffectiveNodeType ent = getEffectiveNodeType(nodeState);
                /**
                 * if the transient node was added (i.e. if it is 'new') or if
                 * its primary type has changed, check its node type against the
                 * required node type in its definition
                 */
                if (nodeState.getStatus() == ItemState.STATUS_NEW
                        || !nodeState.getNodeTypeName().equals(
                            ((NodeState) nodeState.getOverlayedState()).getNodeTypeName())) {
                    NodeType[] nta = nodeDef.getRequiredPrimaryTypes();
                    for (int i = 0; i < nta.length; i++) {
                        NodeTypeImpl ntReq = (NodeTypeImpl) nta[i];
                        if (!(pnt.getQName().equals(ntReq.getQName())
                                || pnt.isDerivedFrom(ntReq.getQName()))) {
                            /**
                             * the transient node's primary node type does not
                             * satisfy the 'required primary types' constraint
                             */
                            String msg = itemMgr.safeGetJCRPath(id)
                                    + " must be of node type " + ntReq.getName();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }
                    }
                }

                // mandatory child properties
                PropDef[] pda = ent.getMandatoryPropDefs();
                for (int i = 0; i < pda.length; i++) {
                    PropDef pd = pda[i];
                    if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)
                            || pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                        /**
                         * todo FIXME workaround for mix:versionable:
                         * the mandatory properties are initialized at a
                         * later stage and might not exist yet
                         */
                        continue;
                    }
                    if (!nodeState.hasPropertyName(pd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory property " + pd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
                // mandatory child nodes
                NodeDef[] cnda = ent.getMandatoryNodeDefs();
                for (int i = 0; i < cnda.length; i++) {
                    NodeDef cnd = cnda[i];
                    if (!nodeState.hasChildNodeEntry(cnd.getName())) {
                        String msg = itemMgr.safeGetJCRPath(id)
                                + ": mandatory child node " + cnd.getName()
                                + " does not exist";
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
            } else {
                // the transient item is a property
                PropertyState propState = (PropertyState) itemState;
                ItemId propId = propState.getPropertyId();
                PropertyDefinitionImpl propDef = (PropertyDefinitionImpl) def;

                /**
                 * check value constraints
                 * (no need to check value constraints of protected properties
                 * as those are set by the implementation only, i.e. they
                 * cannot be set by the user through the api)
                 */
                if (!def.isProtected()) {
                    String[] constraints = propDef.getValueConstraints();
                    if (constraints != null) {
                        InternalValue[] values = propState.getValues();
                        try {
                            EffectiveNodeType.checkSetPropertyValueConstraints(
                                    propDef.unwrap(), values);
                        } catch (RepositoryException e) {
                            // repack exception for providing more verbose error message
                            String msg = itemMgr.safeGetJCRPath(propId) + ": " + e.getMessage();
                            log.debug(msg);
                            throw new ConstraintViolationException(msg);
                        }

                        /**
                         * need to manually check REFERENCE value constraints
                         * as this requires a session (target node needs to
                         * be checked)
                         */
                        if (constraints.length > 0
                                && propDef.getRequiredType() == PropertyType.REFERENCE) {
                            for (int i = 0; i < values.length; i++) {
                                boolean satisfied = false;
                                String constraintViolationMsg = null;
                                try {
                                    UUID targetUUID = values[i].getUUID();
                                    Node targetNode = session.getNodeByUUID(targetUUID);
                                    /**
                                     * constraints are OR-ed, i.e. at least one
                                     * has to be satisfied
                                     */
                                    for (int j = 0; j < constraints.length; j++) {
                                        /**
                                         * a REFERENCE value constraint specifies
                                         * the name of the required node type of
                                         * the target node
                                         */
                                        String ntName = constraints[j];
                                        if (targetNode.isNodeType(ntName)) {
                                            satisfied = true;
                                            break;
                                        }
                                    }
                                    if (!satisfied) {
                                        NodeType[] mixinNodeTypes = targetNode.getMixinNodeTypes();
                                        String[] targetMixins = new String[mixinNodeTypes.length];
                                        for (int j = 0; j < mixinNodeTypes.length; j++) {
                                            targetMixins[j] = mixinNodeTypes[j].getName();
                                        }
                                        String targetMixinsString = Text.implode(targetMixins, ", ");
                                        String constraintsString = Text.implode(constraints, ", ");
                                        constraintViolationMsg = itemMgr.safeGetJCRPath(propId)
                                                + ": is constraint to ["
                                                + constraintsString
                                                + "] but references [primaryType="
                                                + targetNode.getPrimaryNodeType().getName()
                                                + ", mixins="
                                                + targetMixinsString + "]";
                                    }
                                } catch (RepositoryException re) {
                                    String msg = itemMgr.safeGetJCRPath(propId)
                                            + ": failed to check REFERENCE value constraint";
                                    log.debug(msg);
                                    throw new ConstraintViolationException(msg, re);
                                }
                                if (!satisfied) {
                                    log.debug(constraintViolationMsg);
                                    throw new ConstraintViolationException(constraintViolationMsg);
                                }
                            }
                        }
                    }
                }

                /**
                 * no need to check the protected flag as this is checked
                 * in PropertyImpl.setValue(Value)
                 */
            }
        }

        // walk through list of removed transient items and check REMOVE permission
        while (removedIter.hasNext()) {
            ItemState itemState = (ItemState) removedIter.next();
            ItemDefinition def;
            try {
                 if (itemState.isNode()) {
                     def = itemMgr.getDefinition((NodeState) itemState);
                 } else {
                     def = itemMgr.getDefinition((PropertyState) itemState);
                 }
             } catch (ConstraintViolationException e) {
                 // since identifier of assigned definition is not stored anymore
                 // with item state (see JCR-2170), correct definition cannot be
                 // determined for items which have been removed due to removal
                 // of a mixin (see also JCR-2130 & JCR-2408)
                 continue;
             }
            if (!def.isProtected()) {
                Path path = stateMgr.getAtticAwareHierarchyMgr().getPath(itemState.getId());
                // check REMOVE permission
                int permission = (itemState.isNode()) ? Permission.REMOVE_NODE : Permission.REMOVE_PROPERTY;
                if (!accessMgr.isGranted(path, permission)) {
                    String msg = itemMgr.safeGetJCRPath(path)
                            + ": not allowed to remove item";
                    log.debug(msg);
                    throw new AccessDeniedException(msg);
                }
View Full Code Here

TOP

Related Classes of org.apache.jackrabbit.core.security.AccessManager

Copyright © 2018 www.massapicom. 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.