You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2018/04/23 13:36:34 UTC
svn commit: r1829885 - in /jackrabbit/oak/trunk/oak-exercise: ./
src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/
src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/
...
Author: angela
Date: Mon Apr 23 13:36:34 2018
New Revision: 1829885
URL: http://svn.apache.org/viewvc?rev=1829885&view=rev
Log:
OAK-5122 : Exercise for Custom Authorization Models
Added:
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Editor.java (with props)
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Reader.java (with props)
Modified:
jackrabbit/oak/trunk/oak-exercise/pom.xml
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/PredefinedPermissionProvider.java
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAccessControlManager.java
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAuthorizationConfiguration.java
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesPermissionProvider.java
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesTreePermission.java
jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/Utils.java
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L3_UnderstandAggregationTest.java
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L5_CustomPermissionEvaluationTest.java
Modified: jackrabbit/oak/trunk/oak-exercise/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/pom.xml?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-exercise/pom.xml Mon Apr 23 13:36:34 2018
@@ -111,6 +111,11 @@
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-authorization-cug</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-api</artifactId>
<version>${jackrabbit.version}</version>
</dependency>
Added: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Editor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Editor.java?rev=1829885&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Editor.java (added)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Editor.java Mon Apr 23 13:36:34 2018
@@ -0,0 +1,26 @@
+/*
+ * 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.exercise.security.authorization.models.predefined;
+
+import javax.annotation.Nonnull;
+
+public class Editor extends Reader {
+
+ public Editor(@Nonnull String name) {
+ super(name);
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Editor.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/PredefinedPermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/PredefinedPermissionProvider.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/PredefinedPermissionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/PredefinedPermissionProvider.java Mon Apr 23 13:36:34 2018
@@ -21,12 +21,16 @@ import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+/**
+ * EXERCISE: complete PermissionProvider implementation
+ */
class PredefinedPermissionProvider implements PermissionProvider {
private final Set<Principal> principals;
@@ -37,46 +41,46 @@ class PredefinedPermissionProvider imple
@Override
public void refresh() {
- // TODO
+ // EXERCISE: complete PermissionProvider implementation
}
@Nonnull
@Override
public Set<String> getPrivileges(@Nullable Tree tree) {
- // TODO
- return null;
+ // EXERCISE: complete PermissionProvider implementation
+ return ImmutableSet.of();
}
@Override
public boolean hasPrivileges(@Nullable Tree tree, @Nonnull String... privilegeNames) {
- // TODO
+ // EXERCISE: complete PermissionProvider implementation
return false;
}
@Nonnull
@Override
public RepositoryPermission getRepositoryPermission() {
- // TODO
- return null;
+ // EXERCISE: complete PermissionProvider implementation
+ return RepositoryPermission.EMPTY;
}
@Nonnull
@Override
public TreePermission getTreePermission(@Nonnull Tree tree, @Nonnull TreePermission parentPermission) {
- // TODO
- return null;
+ // EXERCISE: complete PermissionProvider implementation
+ return TreePermission.EMPTY;
}
@Override
public boolean isGranted(@Nonnull Tree tree, @Nullable PropertyState property, long permissions) {
- // TODO
+ // EXERCISE: complete PermissionProvider implementation
return false;
}
@Override
public boolean isGranted(@Nonnull String oakPath, @Nonnull String jcrActions) {
- // TODO
+ // EXERCISE: complete PermissionProvider implementation
return false;
}
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Reader.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Reader.java?rev=1829885&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Reader.java (added)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Reader.java Mon Apr 23 13:36:34 2018
@@ -0,0 +1,38 @@
+/*
+ * 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.exercise.security.authorization.models.predefined;
+
+import java.security.Principal;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Reader implements Principal {
+
+ private final String name;
+
+ public Reader(@Nonnull String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/predefined/Reader.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAccessControlManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAccessControlManager.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAccessControlManager.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAccessControlManager.java Mon Apr 23 13:36:34 2018
@@ -41,30 +41,30 @@ class ThreeRolesAccessControlManager imp
ThreeRolesAccessControlManager(@Nonnull Root root, @Nonnull String supportedPath, @Nonnull SecurityProvider securityProvider) {
this.supportedPath = supportedPath;
- // TODO
+ // EXERCISE
}
@Override
public Privilege[] getSupportedPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
- // TODO
+ // EXERCISE
return new Privilege[0];
}
@Override
public Privilege privilegeFromName(String privilegeName) throws AccessControlException, RepositoryException {
- // TODO
+ // EXERCISE
return null;
}
@Override
public boolean hasPrivileges(String absPath, Privilege[] privileges) throws PathNotFoundException, RepositoryException {
- // TODO
+ // EXERCISE
return false;
}
@Override
public Privilege[] getPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
- // TODO
+ // EXERCISE
return new Privilege[0];
}
@@ -73,38 +73,38 @@ class ThreeRolesAccessControlManager imp
*/
@Override
public AccessControlPolicy[] getPolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
- // TODO
+ // EXERCISE
return new AccessControlPolicy[0];
}
@Override
public AccessControlPolicy[] getEffectivePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
- // TODO
+ // EXERCISE
return new AccessControlPolicy[0];
}
@Override
public AccessControlPolicyIterator getApplicablePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
- // TODO
+ // EXERCISE
return new AccessControlPolicyIteratorAdapter(ImmutableList.of());
}
@Override
public void setPolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, LockException, VersionException, RepositoryException {
- // TODO
+ // EXERCISE
}
@Override
public void removePolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, LockException, VersionException, RepositoryException {
- // TODO
+ // EXERCISE
}
@Override
public boolean defines(@Nullable String absPath, @Nonnull AccessControlPolicy accessControlPolicy) {
if (Utils.isSupportedPath(supportedPath, absPath)) {
- // TODO
+ // EXERCISE
}
return false;
}
Modified: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAuthorizationConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAuthorizationConfiguration.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAuthorizationConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesAuthorizationConfiguration.java Mon Apr 23 13:36:34 2018
@@ -170,7 +170,7 @@ public class ThreeRolesAuthorizationConf
return ImmutableList.of(new ValidatorProvider() {
@Override
protected Validator getRootValidator(NodeState before, NodeState after, CommitInfo info) {
- // TODO: write a validator that meets the following requirements:
+ // EXERCISE: write a validator that meets the following requirements:
// 1. check that the item names defined with the node types are only used within the scope of the 2 node types
// 2. check that the policies are never nested.
@@ -186,7 +186,7 @@ public class ThreeRolesAuthorizationConf
@Nonnull
@Override
public List<ProtectedItemImporter> getProtectedItemImporters() {
- // TODO
+ // EXERCISE
return ImmutableList.of();
}
Modified: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesPermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesPermissionProvider.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesPermissionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesPermissionProvider.java Mon Apr 23 13:36:34 2018
@@ -142,7 +142,7 @@ class ThreeRolesPermissionProvider imple
@Nonnull
@Override
public TreePermission getTreePermission(@Nonnull Tree tree, @Nonnull TreeType type, @Nonnull TreePermission parentPermission) {
- // TODO : currently this implementation ignores TreeType
+ // EXERCISE : currently this implementation ignores TreeType -> complete implementation
return getTreePermission(tree, parentPermission);
}
Modified: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesTreePermission.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesTreePermission.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesTreePermission.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/ThreeRolesTreePermission.java Mon Apr 23 13:36:34 2018
@@ -44,7 +44,7 @@ class ThreeRolesTreePermission implement
if (isAcContent) {
return this;
} else {
- // TODO: respect access controlled content defined by other modules
+ // EXERCISE: respect access controlled content defined by other modules
return new ThreeRolesTreePermission(role, REP_3_ROLES_POLICY.equals(childName));
}
}
Modified: jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/Utils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/Utils.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/Utils.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/main/java/org/apache/jackrabbit/oak/exercise/security/authorization/models/simplifiedroles/Utils.java Mon Apr 23 13:36:34 2018
@@ -19,12 +19,7 @@ package org.apache.jackrabbit.oak.exerci
import javax.annotation.Nonnull;
import org.apache.jackrabbit.util.Text;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-/**
- * Utils... TODO
- */
final class Utils {
private Utils() {}
Modified: jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L3_UnderstandAggregationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L3_UnderstandAggregationTest.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L3_UnderstandAggregationTest.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L3_UnderstandAggregationTest.java Mon Apr 23 13:36:34 2018
@@ -16,6 +16,39 @@
*/
package org.apache.jackrabbit.oak.exercise.security.authorization.advanced;
+import javax.jcr.GuestCredentials;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.authorization.PrincipalSetPolicy;
+import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration;
+import org.apache.jackrabbit.oak.security.internal.SecurityProviderHelper;
+import org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.cug.impl.CugConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
/**
* <pre>
* Module: Advanced Authorization Topics
@@ -25,14 +58,310 @@ package org.apache.jackrabbit.oak.exerci
* -----------------------------------------------------------------------------
*
* Goal:
- * TODO
+ * Understand the inner working of aggregated authorization by stepping through
+ * access control management and permission evaluation.
+ * Note that this exercise uses a non-OSGi setup for training purpose relying on
+ * helpers available only for test setup.
*
* Exercises:
- * TODO
+ * Debug through each of the test methods in order to get an understand on how
+ * the composite setup works.
+ *
+ * - {@link #testTestUserReadPermissions()}
+ * - {@link #testTestUserWritePermissions()}
+ * - {@link #testGuestReadPermissions()}
+ * - {@link #testGuestWritePermissions()}
+ * - {@link #testAdminReadPermissions()}
+ * - {@link #testAdminWritePermissions()}
+ * - {@link #testEffectivePolicies()}
+ * - {@link #testApplicablePolicies()}
+ * - {@link #testGetPolicies()}
+ * - {@link #testRemovePolicy()}
+ *
+ * - Explain the {@link org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.PolicyOwner} interface.
+ *
+ * - Write more tests to explore aggregation of additional features within the
+ * authorization setup such as e.g.
+ * > Privilege discovery
+ * > Repository level privileges such as e.g. ability to register a new node type.
+ * > XML Import
+ * > Validation
+ * > Repository Initialization
+ *
+ *
+ * Advanced Exercises
+ * -----------------------------------------------------------------------------
+ *
+ * - Change the 'authorizationCompositionType' to 'OR' and discuss the expected effect
+ * on the tests. Re-run the tests to verify your expectations.
+ *
+ * - Take another look at {@link org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider}.
+ * What happens if a given {@link AuthorizationConfiguration} exposes a simple
+ * {@link org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider}
+ * that doesn't implement the aggregation-extension?
+ * To verify your findings write a test-setup that combines the default authorization model with
+ * {@link org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.PredefinedAuthorizationConfiguration}
*
* </pre>
*/
-public class L3_UnderstandAggregationTest {
+public class L3_UnderstandAggregationTest extends AbstractSecurityTest {
+
+ private PropertyState prop;
+
+ private AccessControlManager acMgr;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ prop = PropertyStates.createProperty("prop", "value");
+
+ Tree var = TreeUtil.addChild(root.getTree("/"), "var", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ var.setProperty(prop);
+
+ Tree content = TreeUtil.addChild(root.getTree("/"), "content", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ content.setProperty(prop);
+
+ Tree c1 = TreeUtil.addChild(content, "c1", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ c1.setProperty(prop);
+
+ Tree c2 = TreeUtil.addChild(content, "c2", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ c2.setProperty(prop);
+
+ acMgr = getAccessControlManager(root);
+
+ // at /content grant read-access for everyone using default model
+ AccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, content.getPath());
+ acl.addAccessControlEntry(EveryonePrincipal.getInstance(), privilegesFromNames(PrivilegeConstants.JCR_READ));
+ acMgr.setPolicy(content.getPath(), acl);
+
+ // at /content/c1 deny reading properties (default model) and establish
+ // a CUG that limits access to test user
+ AccessControlPolicyIterator it = acMgr.getApplicablePolicies(c1.getPath());
+ while (it.hasNext()) {
+ AccessControlPolicy policy = it.nextAccessControlPolicy();
+ if (policy instanceof PrincipalSetPolicy) {
+ PrincipalSetPolicy psp = (PrincipalSetPolicy) policy;
+ psp.addPrincipals(getTestUser().getPrincipal());
+ acMgr.setPolicy(c1.getPath(), psp);
+ } else if (policy instanceof JackrabbitAccessControlList) {
+ JackrabbitAccessControlList jacl = (JackrabbitAccessControlList) policy;
+ jacl.addEntry(EveryonePrincipal.getInstance(), privilegesFromNames(PrivilegeConstants.REP_ADD_PROPERTIES), true);
+ acMgr.setPolicy(c1.getPath(), jacl);
+ }
+ }
+ root.commit();
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ root.getTree("/content").remove();
+ root.getTree("/var").remove();
+ root.commit();
+ } finally {
+ super.after();
+ }
+ }
+
+ @Override
+ protected SecurityProvider initSecurityProvider() {
+ SecurityProvider sp = super.initSecurityProvider();
+ CugConfiguration cugConfiguration = new CugConfiguration();
+ cugConfiguration.setParameters(ConfigurationParameters.of("cugSupportedPaths", new String[] {"/content"}, "cugEnabled", true));
+
+ SecurityProviderHelper.updateConfig(sp, cugConfiguration, AuthorizationConfiguration.class);
+ return sp;
+ }
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ return ConfigurationParameters.of("authorizationCompositionType", CompositeAuthorizationConfiguration.CompositionType.AND.toString());
+ }
+
+ @Test
+ public void testTestUserReadPermissions() throws Exception {
+ try (ContentSession cs = createTestSession()) {
+ Root r = cs.getLatestRoot();
+
+ assertFalse(r.getTree("/").exists());
+ assertFalse(r.getTree("/var").exists());
+
+ Tree t = r.getTree("/content");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+
+ t = r.getTree("/content/c2");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+
+ t = r.getTree("/content/c1");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+ }
+ }
+
+ @Test
+ public void testTestUserWritePermissions() throws Exception {
+ try (ContentSession cs = createTestSession()) {
+ Root r = cs.getLatestRoot();
+
+ Tree t = r.getTree("/content/c1");
+ t.setProperty("addingProperty", "value");
+ root.commit();
+
+ assertFalse(getAccessControlManager(r).hasPrivileges("/content/c1", privilegesFromNames(PrivilegeConstants.JCR_ADD_CHILD_NODES)));
+ assertFalse(getAccessControlManager(r).hasPrivileges("/content/c1", privilegesFromNames(PrivilegeConstants.JCR_REMOVE_CHILD_NODES)));
+ assertFalse(getAccessControlManager(r).hasPrivileges("/content/c1", privilegesFromNames(PrivilegeConstants.REP_REMOVE_PROPERTIES)));
+ assertFalse(getAccessControlManager(r).hasPrivileges("/content/c1", privilegesFromNames(PrivilegeConstants.REP_ALTER_PROPERTIES)));
+ }
+ }
+
+ @Test
+ public void testGuestReadPermissions() throws Exception {
+ try (ContentSession cs = login(new GuestCredentials())) {
+ Root r = cs.getLatestRoot();
+
+ assertFalse(r.getTree("/").exists());
+ assertFalse(r.getTree("/var").exists());
+
+ Tree t = r.getTree("/content");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+
+ t = r.getTree("/content/c2");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+
+ assertFalse(r.getTree("/content/c1").exists());
+ }
+ }
+
+ @Test(expected = CommitFailedException.class)
+ public void testGuestWritePermissions() throws Exception {
+ try (ContentSession cs = login(new GuestCredentials())) {
+ Root r = cs.getLatestRoot();
+
+ // EXERCISE: write additional code testing permissions required for
+ // another property and child node.
+
+ Tree t = r.getTree("/content");
+ t.setProperty("prop2", "value");
+ t.addChild("anotherChild");
+
+ r.commit();
+ }
+ }
+
+ @Test
+ public void testAdminReadPermissions() {
+ assertTrue(root.getTree("/").exists());
+ assertTrue(root.getTree("/var").exists());
+
+ Tree t = root.getTree("/content");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+
+ t = root.getTree("/content/c2");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+
+ t = root.getTree("/content/c1");
+ assertTrue(t.exists());
+ assertTrue(t.hasProperty(prop.getName()));
+ }
+
+ @Test
+ public void testAdminWritePermissions() throws Exception {
+ for (String p : new String[] {"/", "/var", "/content", "/content/c1", "/content/c2"}) {
+ assertTrue(acMgr.hasPrivileges(p, privilegesFromNames(PrivilegeConstants.JCR_ALL)));
+ }
+ }
+
+ @Test
+ public void testEffectivePolicies() throws Exception {
+ // EXERCISE: inspect the effective policies to be discovered at the various paths
+ // explain the result and the differences.
+
+ // EXERCISE: compare list of effective policies to policies return upon AccessControlManager.getPolicies
+
+ AccessControlPolicy[] effective = acMgr.getEffectivePolicies("/content/c1");
+ assertEquals(3, effective.length);
+
+ effective = acMgr.getEffectivePolicies("/content/c2");
+ assertEquals(1, effective.length);
+
+ effective = acMgr.getEffectivePolicies("/var");
+ assertEquals(0, effective.length);
+
+ effective = acMgr.getEffectivePolicies(NamespaceConstants.NAMESPACES_PATH);
+ assertEquals(1, effective.length);
+
+ // EXERCISE: try to modify the policies obtained in any of the calls
+
+ // EXERCISE: try to write back the effective policies using AccessControlManager.setPolicy
+ }
+
+ @Test
+ public void testApplicablePolicies() throws Exception {
+ // EXERCISE: observe the type of applicable policies and explain differences
+ // between the 3 paths.
+ AccessControlPolicyIterator it = acMgr.getApplicablePolicies("/content/c2");
+ int cnt = 0;
+ while (it.hasNext()) {
+ AccessControlPolicy policy = it.nextAccessControlPolicy();
+ cnt++;
+ }
+ assertEquals(2, cnt);
+
+ it = acMgr.getApplicablePolicies("/var");
+ cnt = 0;
+ while (it.hasNext()) {
+ AccessControlPolicy policy = it.nextAccessControlPolicy();
+ cnt++;
+ }
+ assertEquals(1, cnt);
+
+ it = acMgr.getApplicablePolicies("/content");
+ cnt = 0;
+ while (it.hasNext()) {
+ AccessControlPolicy policy = it.nextAccessControlPolicy();
+ cnt++;
+ }
+ assertEquals(1, cnt);
+
+ // EXERCISE: expand the test by optionally modifying the applicable policies
+ // and writing them back using AccessControlManager.setPolicy
+
+ // EXERCISE: explain the effective permissions resulting from both applying
+ // empty and modified policies.
+ }
+
+ @Test
+ public void testGetSetPolicies() throws Exception {
+ AccessControlPolicy[] policies = acMgr.getPolicies("/content/c1");
+
+ assertEquals(2, policies.length);
+
+ // EXERCISE: observe how the different authorization models claim responsibility for the setPolicy call.
+ for (AccessControlPolicy policy : policies) {
+ acMgr.setPolicy("/content/c1", policy);
+ }
+
+ assertEquals(2, acMgr.getPolicies("/content/c1").length);
+ }
+
+ @Test
+ public void testRemovePolicy() throws Exception {
+ AccessControlPolicy[] policies = acMgr.getPolicies("/content/c1");
+
+ assertEquals(2, policies.length);
+ // EXERCISE: observe how the different authorization models claim responsibility for the removal.
+ for (AccessControlPolicy policy : policies) {
+ acMgr.removePolicy("/content/c1", policy);
+ }
+ assertEquals(0, acMgr.getPolicies("/content/c1").length);
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L5_CustomPermissionEvaluationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L5_CustomPermissionEvaluationTest.java?rev=1829885&r1=1829884&r2=1829885&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L5_CustomPermissionEvaluationTest.java (original)
+++ jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/advanced/L5_CustomPermissionEvaluationTest.java Mon Apr 23 13:36:34 2018
@@ -22,16 +22,22 @@ import java.util.Set;
import javax.annotation.Nonnull;
import javax.jcr.GuestCredentials;
import javax.jcr.Session;
+import javax.jcr.security.Privilege;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.Editor;
import org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.PredefinedAuthorizationConfiguration;
+import org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.Reader;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.security.authentication.AuthenticationConfigurationImpl;
@@ -46,6 +52,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.apache.jackrabbit.util.Text;
import org.junit.Test;
@@ -71,13 +78,46 @@ import static org.junit.Assert.assertTru
* Complete the implementation of {@link org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.PredefinedPermissionProvider}
* such that the tests pass.
*
+ * - {@link #testAdministrativeAccess}
+ * Complete the {@link org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.PredefinedPermissionProvider}
+ * such that at least the admin principal has full access everywhere.
*
- * Advanced Exercise
+ * Questions:
+ * - How can you identify the 'administrator' from a given set of principals?
+ * - Would it make sense to include other principals in that category? How would you identify them?
+ * - Take another look at the built-in authorization models (default and oak-authorization-cug):
+ * Can you describe what types of 'administrative' access they define? And how?
+ *
+ * - {@link #testGuestAccess()}
+ * The {@link org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.PredefinedPermissionProvider}
+ * assumes that the guest account doesn't have any permissions granted. Complete
+ * the permission provider implementation accordingly.
+ *
+ * Question:
+ * Do you need to explicitly identify the guest account? If yes, how would you do that?
+ *
+ * - {@link #testWriteAccess()}
+ * This tests asserts that 'editors' have basic read/write permissions. Complete
+ * the permission provider implementation accordingly.
+ *
+ * Questions:
+ * - The test hard-codes the 'editor' principal. Can you come up with a setup scenario
+ * where the Editor principal would be placed into the Subject upon login? What are the criteria?
+ * - Can you make sure a given test-user won't be able to map itself to the 'editor' principal?
+ *
+ * - {@link #testReadAccess()}
+ * This tests asserts that 'readers' exclusively have basic read access. Complete
+ * the permission provider implementation accordingly.
+ *
+ *
+ * Advanced Exercises
* -----------------------------------------------------------------------------
*
+ * 1. Aggregation
+ *
* Currently the {@link org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.PredefinedPermissionProvider}
* doesn't implement {@link org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider} interface
- * and can therefore not be used in a setup that combines multipe authorization models.
+ * and can therefore not be used in a setup that combines multiple authorization models.
*
* As an advanced exercise modify the {@link org.apache.jackrabbit.oak.exercise.security.authorization.models.predefined.PredefinedPermissionProvider}
* to additionally implement {@link org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider}
@@ -88,6 +128,26 @@ import static org.junit.Assert.assertTru
* - Clarify which type of 'Authorization Composition' your implementation should be used.
* - Observe the result of your combination and explain the results to effective permissions.
*
+ *
+ * 2. Limit Access
+ *
+ * Currently the predefined {@code PermissionProvider} grants/denies the same permissions
+ * on the whole content repository. As an advanced exercise discuss how you would
+ * limit the permissions to certain parts of the content repository.
+ *
+ * For example: Imagine the first hierarchy level would define a trust-boundary
+ * based on continent. So, every 'Editor' only has write access to the continent
+ * he/she has been assigned to.
+ *
+ * Questions:
+ *
+ * - Should read-access be granted across continents?
+ * - Do you need a distinction between repository-administrators and continent-administrators?
+ * - How do you identify a given continent and map it to the access pattern of a given principal set?
+ * - Can you come up with your own PrincipalConfiguration serving a custom Principal implementation that help you with that task?
+ * - Are the items used for continent-identification properly protected to prevent unintended (or malicious) meddling?
+ * - At which point would you additionally need access control management?
+ *
* </pre>
*/
public class L5_CustomPermissionEvaluationTest extends AbstractSecurityTest {
@@ -155,8 +215,14 @@ public class L5_CustomPermissionEvaluati
return Iterables.transform(trees, Tree::getPath);
}
+ private Set<Principal> getGuestPrincipals() throws Exception {
+ try (ContentSession guest = login(new GuestCredentials())) {
+ return guest.getAuthInfo().getPrincipals();
+ }
+ }
+
@Test
- public void testAdministratorHasFullAccessEverywhere() {
+ public void testAdministrativeAccess() {
for (String path : getTreePaths()) {
Tree t = root.getTree(path);
assertFalse(t.exists());
@@ -176,7 +242,7 @@ public class L5_CustomPermissionEvaluati
}
@Test
- public void testGuestHasNowherePermissions() throws Exception {
+ public void testGuestAccess() throws Exception {
try (ContentSession guest = login(new GuestCredentials())) {
Root r = guest.getLatestRoot();
for (String path : getTreePaths()) {
@@ -201,5 +267,95 @@ public class L5_CustomPermissionEvaluati
}
}
- // TODO: add more tests
+ @Test
+ public void testWriteAccess() throws Exception {
+ List<Set<Principal>> editors = ImmutableList.<Set<Principal>>of(
+ ImmutableSet.<Principal>of(new Editor("ida")),
+ ImmutableSet.<Principal>of(EveryonePrincipal.getInstance(), new Editor("amanda")),
+ ImmutableSet.<Principal>of(getTestUser().getPrincipal(),new Editor("susi")),
+ ImmutableSet.<Principal>builder().addAll(getGuestPrincipals()).add(new Editor("naima")).build()
+ );
+
+ for (Set<Principal> principals : editors) {
+ PermissionProvider pp = getPermissionProvider(principals);
+ for (Tree t : trees) {
+ assertTrue(pp.hasPrivileges(t, PrivilegeConstants.JCR_READ, PrivilegeConstants.JCR_WRITE));
+
+ assertFalse(pp.hasPrivileges(t, PrivilegeConstants.JCR_WRITE, PrivilegeConstants.JCR_NODE_TYPE_MANAGEMENT));
+ assertFalse(pp.hasPrivileges(t, PrivilegeConstants.JCR_READ_ACCESS_CONTROL, PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL, PrivilegeConstants.REP_USER_MANAGEMENT));
+ assertFalse(pp.hasPrivileges(t, PrivilegeConstants.JCR_ALL));
+
+ assertTrue(pp.isGranted(t, null, Permissions.WRITE | Permissions.READ));
+ assertTrue(pp.isGranted(t, prop, Permissions.WRITE|Permissions.READ));
+
+ assertFalse(pp.isGranted(t, null, Permissions.ALL));
+ assertFalse(pp.isGranted(t, prop, Permissions.ALL));
+
+ assertFalse(pp.isGranted(t, null, Permissions.READ_ACCESS_CONTROL|Permissions.MODIFY_ACCESS_CONTROL|Permissions.USER_MANAGEMENT));
+ assertFalse(pp.isGranted(t, prop, Permissions.READ_ACCESS_CONTROL | Permissions.MODIFY_ACCESS_CONTROL | Permissions.USER_MANAGEMENT));
+
+
+ for (String action : ACTION_NAMES) {
+ String treePath = t.getPath();
+ assertTrue(pp.isGranted(treePath, action));
+ assertTrue(pp.isGranted(PathUtils.concat(treePath, prop.getName()), action));
+ }
+
+ String deniedActions = Text.implode(new String[] {JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL, JackrabbitSession.ACTION_READ_ACCESS_CONTROL, JackrabbitSession.ACTION_USER_MANAGEMENT}, ",");
+ assertFalse(pp.isGranted(t.getPath(), deniedActions));
+ }
+ }
+ }
+
+ @Test
+ public void testReadAccess() throws Exception {
+ List<Set<Principal>> readers = ImmutableList.<Set<Principal>>of(
+ ImmutableSet.<Principal>of(new Reader("ida")),
+ ImmutableSet.<Principal>of(EveryonePrincipal.getInstance(), new Reader("fairuz")),
+ ImmutableSet.<Principal>of(getTestUser().getPrincipal(),new Editor("juni")),
+ ImmutableSet.<Principal>builder().addAll(getGuestPrincipals()).add(new Editor("ale")).build()
+ );
+
+ PrivilegeManager privilegeManager = getPrivilegeManager(root);
+ Privilege all = privilegeManager.getPrivilege(PrivilegeConstants.JCR_ALL);
+ Set<String> readPrivNames = ImmutableSet.of(PrivilegeConstants.JCR_READ, PrivilegeConstants.REP_READ_NODES, PrivilegeConstants.REP_READ_PROPERTIES);
+
+ for (Set<Principal> principals : readers) {
+ PermissionProvider pp = getPermissionProvider(principals);
+ for (Tree t : trees) {
+ assertTrue(pp.hasPrivileges(t, readPrivNames.toArray(new String[readPrivNames.size()])));
+
+ for (Privilege p : all.getAggregatePrivileges()) {
+ String pName = p.getName();
+ if (readPrivNames.contains(pName)) {
+ assertTrue(pp.hasPrivileges(t, pName));
+ } else {
+ assertFalse(pp.hasPrivileges(t, pName));
+ }
+ }
+ assertFalse(pp.hasPrivileges(t, PrivilegeConstants.JCR_ALL, PrivilegeConstants.JCR_READ));
+
+ assertTrue(pp.isGranted(t, null, Permissions.READ));
+ assertTrue(pp.isGranted(t, null, Permissions.READ_NODE));
+ assertTrue(pp.isGranted(t, prop, Permissions.READ_PROPERTY));
+
+ assertFalse(pp.isGranted(t, null, Permissions.ALL));
+ assertFalse(pp.isGranted(t, prop, Permissions.ALL));
+
+ assertFalse(pp.isGranted(t, null, Permissions.WRITE|Permissions.VERSION_MANAGEMENT|Permissions.READ_ACCESS_CONTROL));
+ assertFalse(pp.isGranted(t, prop, Permissions.SET_PROPERTY|Permissions.VERSION_MANAGEMENT|Permissions.READ_ACCESS_CONTROL));
+
+ String treePath = t.getPath();
+ assertTrue(pp.isGranted(treePath, Session.ACTION_READ));
+ assertTrue(pp.isGranted(PathUtils.concat(treePath, prop.getName()), Session.ACTION_READ));
+
+ String deniedActions = Text.implode(new String[] {Session.ACTION_ADD_NODE, Session.ACTION_SET_PROPERTY, Session.ACTION_REMOVE, JackrabbitSession.ACTION_READ_ACCESS_CONTROL}, ",");
+ assertFalse(pp.isGranted(t.getPath(), deniedActions));
+ }
+
+ assertTrue(pp.isGranted("/path/to/nonexisting/item", Session.ACTION_READ));
+ assertFalse(pp.isGranted("/path/to/nonexisting/item", Session.ACTION_SET_PROPERTY));
+ }
+ }
+
}
\ No newline at end of file