diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java index ae97d097ee..0bba6cd9d5 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java @@ -174,13 +174,10 @@ public class CompositeAuthorizationConfiguration extends CompositeConfiguration< case 1: return configurations.get(0).getPermissionProvider(root, workspaceName, principals); default: List aggrPermissionProviders = new ArrayList<>(configurations.size()); - CompositePermissionProvider composite = null; for (AuthorizationConfiguration conf : configurations) { PermissionProvider pProvider = conf.getPermissionProvider(root, workspaceName, principals); if (pProvider instanceof AggregatedPermissionProvider) { aggrPermissionProviders.add((AggregatedPermissionProvider) pProvider); - } else if (pProvider instanceof CompositePermissionProvider) { - composite = (CompositePermissionProvider) pProvider; } else { log.debug("Ignoring permission provider of '{}': Not an AggregatedPermissionProvider", conf.getClass().getName()); } @@ -188,11 +185,7 @@ public class CompositeAuthorizationConfiguration extends CompositeConfiguration< PermissionProvider pp; switch (aggrPermissionProviders.size()) { case 0 : - if (composite != null) { - pp = composite; - } else { - pp = EmptyPermissionProvider.getInstance(); - } + pp = EmptyPermissionProvider.getInstance(); break; case 1 : pp = aggrPermissionProviders.get(0); diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java index 9cf8f27b69..273c72523b 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java @@ -20,6 +20,7 @@ import static org.apache.jackrabbit.oak.security.authorization.composite.Composi import java.util.List; import java.util.Set; +import java.util.function.Function; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -29,6 +30,7 @@ import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.plugins.tree.RootFactory; import org.apache.jackrabbit.oak.plugins.tree.TreeLocation; +import org.apache.jackrabbit.oak.plugins.tree.TreeType; import org.apache.jackrabbit.oak.plugins.tree.TreeTypeProvider; import org.apache.jackrabbit.oak.plugins.tree.impl.ImmutableTree; import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType; @@ -49,7 +51,7 @@ import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider; * {@link org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider} * interface. */ -class CompositePermissionProvider implements PermissionProvider { +class CompositePermissionProvider implements AggregatedPermissionProvider { private final Root root; private final AggregatedPermissionProvider[] pps; @@ -162,14 +164,7 @@ class CompositePermissionProvider implements PermissionProvider { @Nonnull @Override public TreePermission getTreePermission(@Nonnull Tree tree, @Nonnull TreePermission parentPermission) { - ImmutableTree immutableTree = (ImmutableTree) PermissionUtil.getImmutableTree(tree, immutableRoot); - if (tree.isRoot()) { - return CompositeTreePermission.create(immutableTree, typeProvider, pps, compositionType); - } else if (parentPermission instanceof CompositeTreePermission) { - return CompositeTreePermission.create(immutableTree, ((CompositeTreePermission) parentPermission)); - } else { - return parentPermission.getChildPermission(immutableTree.getName(), immutableTree.getNodeState()); - } + return getTreePermission(tree, TreeType.DEFAULT, parentPermission); } @Override @@ -206,37 +201,7 @@ class CompositePermissionProvider implements PermissionProvider { boolean isAcContent = ctx.definesLocation(location); long permissions = Permissions.getPermissions(jcrActions, location, isAcContent); - - PropertyState property = location.getProperty(); - Tree tree = (property == null) ? location.getTree() : location.getParent().getTree(); - - if (tree != null) { - return isGranted(tree, property, permissions); - } else { - boolean isGranted = false; - long coveredPermissions = Permissions.NO_PERMISSION; - - for (AggregatedPermissionProvider aggregatedPermissionProvider : pps) { - long supportedPermissions = aggregatedPermissionProvider.supportedPermissions(location, permissions); - if (doEvaluate(supportedPermissions)) { - if (compositionType == AND) { - isGranted = aggregatedPermissionProvider.isGranted(location, supportedPermissions); - if (!isGranted) { - return false; - } - coveredPermissions |= supportedPermissions; - } else { - for (long p : Permissions.aggregates(permissions)) { - if (aggregatedPermissionProvider.isGranted(location, p)) { - coveredPermissions |= p; - isGranted = true; - } - } - } - } - } - return isGranted && coveredPermissions == permissions; - } + return isGranted(location, permissions); } //------------------------------------------------------------< private >--- @@ -293,4 +258,90 @@ class CompositePermissionProvider implements PermissionProvider { return isGranted && coveredPermissions == repositoryPermissions; } } + + //---------------------------------------< AggregatedPermissionProvider >--- + + @Nonnull + @Override + public PrivilegeBits supportedPrivileges(@Nullable Tree tree, @Nullable PrivilegeBits privilegeBits) { + PrivilegeBits result = PrivilegeBits.getInstance(); + for (AggregatedPermissionProvider aggregatedPermissionProvider : pps) { + PrivilegeBits supported = aggregatedPermissionProvider.supportedPrivileges(tree, privilegeBits); + result.add(supported); + } + return result; + } + + @Override + public long supportedPermissions(@Nullable Tree tree, @Nullable PropertyState property, long permissions) { + return supportedPermissions((aggregatedPermissionProvider) -> aggregatedPermissionProvider + .supportedPermissions(tree, property, permissions)); + } + + @Override + public long supportedPermissions(TreeLocation location, long permissions) { + return supportedPermissions((aggregatedPermissionProvider) -> aggregatedPermissionProvider + .supportedPermissions(location, permissions)); + } + + @Override + public long supportedPermissions(TreePermission treePermission, PropertyState property, long permissions) { + return supportedPermissions((aggregatedPermissionProvider) -> aggregatedPermissionProvider + .supportedPermissions(treePermission, property, permissions)); + } + + private long supportedPermissions(Function supported) { + long coveredPermissions = Permissions.NO_PERMISSION; + for (AggregatedPermissionProvider aggregatedPermissionProvider : pps) { + long supportedPermissions = supported.apply(aggregatedPermissionProvider); + coveredPermissions |= supportedPermissions; + } + return coveredPermissions; + } + + @Override + public boolean isGranted(@Nonnull TreeLocation location, long permissions) { + PropertyState property = location.getProperty(); + Tree tree = (property == null) ? location.getTree() : location.getParent().getTree(); + + if (tree != null) { + return isGranted(tree, property, permissions); + } else { + boolean isGranted = false; + long coveredPermissions = Permissions.NO_PERMISSION; + + for (AggregatedPermissionProvider aggregatedPermissionProvider : pps) { + long supportedPermissions = aggregatedPermissionProvider.supportedPermissions(location, permissions); + if (doEvaluate(supportedPermissions)) { + if (compositionType == AND) { + isGranted = aggregatedPermissionProvider.isGranted(location, supportedPermissions); + if (!isGranted) { + return false; + } + coveredPermissions |= supportedPermissions; + } else { + for (long p : Permissions.aggregates(permissions)) { + if (aggregatedPermissionProvider.isGranted(location, p)) { + coveredPermissions |= p; + isGranted = true; + } + } + } + } + } + return isGranted && coveredPermissions == permissions; + } + } + + @Override + public TreePermission getTreePermission(Tree tree, TreeType type, TreePermission parentPermission) { + ImmutableTree immutableTree = (ImmutableTree) PermissionUtil.getImmutableTree(tree, immutableRoot); + if (tree.isRoot()) { + return CompositeTreePermission.create(immutableTree, type, typeProvider, pps, compositionType); + } else if (parentPermission instanceof CompositeTreePermission) { + return CompositeTreePermission.create(immutableTree, ((CompositeTreePermission) parentPermission)); + } else { + return parentPermission.getChildPermission(immutableTree.getName(), immutableTree.getNodeState()); + } + } } diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java index bbaf835bdb..43cbc5aaa3 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java @@ -64,22 +64,23 @@ final class CompositeTreePermission implements TreePermission { this.compositionType = compositionType; } - static TreePermission create(@Nonnull ImmutableTree rootTree, @Nonnull TreeTypeProvider typeProvider, - @Nonnull AggregatedPermissionProvider[] providers, @Nonnull CompositionType compositionType) { + static TreePermission create(@Nonnull ImmutableTree rootTree, @Nonnull TreeType type, + @Nonnull TreeTypeProvider typeProvider, @Nonnull AggregatedPermissionProvider[] providers, + @Nonnull CompositionType compositionType) { switch (providers.length) { case 0 : return TreePermission.EMPTY; - case 1 : return providers[0].getTreePermission(rootTree, TreeType.DEFAULT, TreePermission.EMPTY); + case 1 : return providers[0].getTreePermission(rootTree, type, TreePermission.EMPTY); default : int cnt = 0; TreePermission[] treePermissions = new TreePermission[providers.length]; for (int i = 0; i < providers.length; i++) { - TreePermission tp = providers[i].getTreePermission(rootTree, TreeType.DEFAULT, TreePermission.EMPTY); + TreePermission tp = providers[i].getTreePermission(rootTree, type, TreePermission.EMPTY); if (!isValid(tp)) { cnt++; } treePermissions[i] = tp; } - return new CompositeTreePermission(rootTree, TreeType.DEFAULT, typeProvider, providers, treePermissions, + return new CompositeTreePermission(rootTree, type, typeProvider, providers, treePermissions, cnt, compositionType); } }