Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (revision 1792701) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (revision ) @@ -44,6 +44,7 @@ import org.apache.jackrabbit.oak.plugins.version.ReadOnlyVersionManager; import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; import org.apache.jackrabbit.oak.spi.security.Context; +import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants; import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants; import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions; import org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission; @@ -165,6 +166,8 @@ } if (parentPermission instanceof VersionTreePermission) { return ((VersionTreePermission) parentPermission).createChildPermission(tree); + } else if (parentPermission instanceof RepoPolicyTreePermission) { + return ((RepoPolicyTreePermission)parentPermission).getChildPermission(); } switch (type) { case HIDDEN: @@ -190,6 +193,12 @@ return new VersionTreePermission(tree, buildVersionDelegatee(versionableTree)); } } + case ACCESS_CONTROL: + if (AccessControlConstants.REP_REPO_POLICY.equals(tree.getName())) { + return new RepoPolicyTreePermission(this); + } else { + return new TreePermissionImpl(tree, type, parentPermission); + } case INTERNAL: return EMPTY; default: @@ -432,6 +441,8 @@ return TreeType.DEFAULT; } else if (parentPermission instanceof VersionTreePermission) { return TreeType.VERSION; + } else if (parentPermission instanceof RepoPolicyTreePermission) { + return TreeType.ACCESS_CONTROL; } else { throw new IllegalArgumentException("Illegal TreePermission implementation."); } Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/RepoPolicyTreePermission.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/RepoPolicyTreePermission.java (revision ) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/RepoPolicyTreePermission.java (revision ) @@ -0,0 +1,98 @@ +/* + * 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.oak.security.authorization.permission; + +import javax.annotation.Nonnull; + +import org.apache.jackrabbit.oak.api.PropertyState; +import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions; +import org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission; +import org.apache.jackrabbit.oak.spi.state.NodeState; + +/** + * {@code TreePermission} implementation for the access control policy coverying + * repository level permissions. In this implementation these permissions are + * managed in the policy tree defined at /rep:repoPolicy, which is considered + * protected access control content. + * + * This implementation relies on the precondition that the subtree defined by the + * /rep:repoPolicy node only consists of trees of type access control. Consequently, + * read access to trees and properties is granted if and only if {@link Permissions#READ_ACCESS_CONTROL} + * is granted at the repo-level. + * + * For the same reason any other permissions are evaluated by checking the + * {@link org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission}, + * which apply for all items defined by this special subtree. + */ +final class RepoPolicyTreePermission implements TreePermission { + + private CompiledPermissionImpl compiledPermission; + private ReadStatus readStatus; + + RepoPolicyTreePermission(CompiledPermissionImpl compiledPermission) { + this.compiledPermission = compiledPermission; + } + + TreePermission getChildPermission() { + return this; + } + + //-----------------------------------------------------< TreePermission >--- + @Nonnull + @Override + public TreePermission getChildPermission(@Nonnull String childName, @Nonnull NodeState childState) { + return getChildPermission(); + } + + @Override + public boolean canRead() { + return getReadStatus().allowsThis(); + } + + @Override + public boolean canRead(@Nonnull PropertyState property) { + return getReadStatus().allowsThis(); + } + + @Override + public boolean canReadAll() { + return getReadStatus().allowsAll(); + } + + @Override + public boolean canReadProperties() { + return getReadStatus().allowsProperties(); + } + + @Override + public boolean isGranted(long permissions) { + return compiledPermission.getRepositoryPermission().isGranted(permissions); + } + + @Override + public boolean isGranted(long permissions, @Nonnull PropertyState property) { + return compiledPermission.getRepositoryPermission().isGranted(permissions); + } + + private ReadStatus getReadStatus() { + if (readStatus == null) { + boolean canRead = compiledPermission.getRepositoryPermission().isGranted(Permissions.READ_ACCESS_CONTROL); + readStatus = (canRead) ? ReadStatus.ALLOW_ALL : ReadStatus.DENY_ALL; + } + return readStatus; + } +}