public boolean hasCapability()

in oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionImpl.java [679:766]


    public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
        requireNonNull(methodName, "parameter 'methodName' must not be null");
        requireNonNull(target, "parameter 'target' must not be null");
        checkAlive();

        AccessManager accessMgr = sessionContext.getAccessManager();
        if (target instanceof ItemImpl) {
            ItemDelegate dlg = ((ItemImpl<?>) target).dlg;
            if (dlg.isProtected()) {
                return false;
            }

            boolean isNode = ((ItemImpl<?>) target).isNode();
            NodeImpl parent = (NodeImpl) ((isNode) ? target : ((ItemImpl<?>) target).getParent());
            if (!parent.internalIsCheckedOut()) {
                return false;
            }
            boolean hasLocking = sessionContext.getRepository().getDescriptorValue(Repository.OPTION_LOCKING_SUPPORTED)
                    .getBoolean();
            if (hasLocking && parent.isLocked()) {
                return false;
            }

            long permission = Permissions.NO_PERMISSION;
            if (isNode) {
                Tree tree = ((NodeDelegate) dlg).getTree();
                if ("addNode".equals(methodName)) {
                    String relPath = getFirstArgument(arguments);
                    if (relPath != null) {
                        // add-node needs to be checked on the (path of) the
                        // new node that has/will be added
                        String path = PathUtils.concat(tree.getPath(), sessionContext.getOakPathOrThrow(relPath));
                        return accessMgr.hasPermissions(path, Session.ACTION_ADD_NODE) && !isMountedReadOnly(path);
                    } else {
                        // invalid arguments -> cannot verify
                        log.warn("Cannot verify capability to '{}' due to missing or invalid arguments, required a valid relative path.", methodName);
                        return false;
                    }
                } else if ("setPrimaryType".equals(methodName) || "addMixin".equals(methodName)
                        || "removeMixin".equals(methodName)) {
                    permission = Permissions.NODE_TYPE_MANAGEMENT;
                } else if ("orderBefore".equals(methodName)) {
                    if (tree.isRoot()) {
                        return false;
                    } else {
                        permission = Permissions.MODIFY_CHILD_NODE_COLLECTION;
                        tree = tree.getParent();
                    }
                } else if ("setProperty".equals(methodName)) {
                    permission = Permissions.ADD_PROPERTY;
                } else if ("remove".equals(methodName)) {
                    permission = Permissions.REMOVE_NODE;
                }
                return accessMgr.hasPermissions(tree, null, permission) && !isMountedReadOnly(tree.getPath());
            } else {
                if ("setValue".equals(methodName)) {
                    permission = Permissions.MODIFY_PROPERTY;
                } else if ("remove".equals(methodName)) {
                    permission = Permissions.REMOVE_PROPERTY;
                }
                NodeDelegate parentDelegate = dlg.getParent();
                if (parentDelegate != null) {
                    return accessMgr.hasPermissions(parentDelegate.getTree(),
                            ((PropertyDelegate) dlg).getPropertyState(), permission)
                            && !isMountedReadOnly(parentDelegate.getPath());
                } else {
                    return accessMgr.hasPermissions(dlg.getPath(),
                            (permission == Permissions.MODIFY_PROPERTY) ? Session.ACTION_SET_PROPERTY
                                    : Session.ACTION_REMOVE)
                            && !isMountedReadOnly(dlg.getPath());
                }
            }
        } else if (target instanceof AccessControlManager && isPolicyWriteMethod(methodName)) {
            if (!hasArguments(arguments)) {
                log.warn("Cannot verify capability to '{}' due to missing arguments.", methodName);
                return false;
            }
            String path = getFirstArgument(arguments);
            if (path == null) {
                return getAccessControlManager().hasPrivileges(null, AccessControlUtils.privilegesFromNames(this, PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL));
            } else {
                String oakPath = getOakPathOrThrow(path);
                return !isMountedReadOnly(oakPath) && accessMgr.hasPermissions(oakPath, JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL);
            }
        }
        // TODO: add more best-effort checks
        return true;
    }