Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L3_BuiltInPrivilegesTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L3_BuiltInPrivilegesTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L3_BuiltInPrivilegesTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L3_BuiltInPrivilegesTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,189 @@
+/*
+ * 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.privilege;
+
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nullable;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+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.Root;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * <pre>
+ * Module: Privilege Management
+ *
=============================================================================
+ *
+ * Title: The Built-in Privileges
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand what built-in privileges are provided by JCR specification and
+ * the Oak repository and what type of operations and items they take
+ * effect upon.
+ *
+ * Exercises:
+ *
+ * - Privilege Overview
+ * List all privileges defined by JSR 283 and Oak and mark if they are
+ * aggregated privileges (if yes: what's the aggregation). Try to understand
+ * the meaning of the individual privileges.
+ *
+ * - {@link #testAggregation()}
+ * For all built-in aggregated privileges defined the mapping of the name
+ * to the declared aggregated privileges such that the test passes.
+ *
+ * Question: What can you say about the nature of {@link Privilege#JCR_READ}
+ * Question: Review again what JSR 283 states about {@link Privilege#JCR_ALL}
+ *
+ * - {@link #testMapItems()}
+ * This allows you to become familiar with the mapping of individual
privileges
+ * to items. Use the Oak API to change those items directly (instead of using
+ * the corresponding JCR API call.
+ * Use the JCR specification, the privilege definitions and {@link
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions}
+ *
+ * Question: Can you map the items to the corresponding JCR API calls? (see
additional exercises below)
+ * Question: Can you extract the rules when a dedicated specific privilege is
+ * being used instead of regular JCR write privileges?
+ *
+ *
+ * Additional Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - Create a new test-case similar to {@link #testMapItems()} extending from
+ * {@link org.apache.jackrabbit.test.AbstractJCRTest} and verify your
findings
+ * by executing the corresponding JCR API calls.
+ *
+ * Related Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link L4_CustomPrivilegeTest}
+ *
+ * </pre>
+ *
+ * @see javax.jcr.security.Privilege
+ * @see org.apache.jackrabbit.api.security.authorization.PrivilegeManager
+ * @see javax.jcr.security.AccessControlManager#privilegeFromName(String)
+ * @see org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants
+ */
+public class L3_BuiltInPrivilegesTest extends AbstractSecurityTest {
+
+ private ContentSession testSession;
+ private Root testRoot;
+
+ private AccessControlManager acMgr;
+ private PrivilegeBitsProvider privilegeBitsProvider;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ testSession = createTestSession();
+ testRoot = testSession.getLatestRoot();
+
+ acMgr = getAccessControlManager(root);
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ if (testSession != null) {
+ testSession.close();
+ }
+ } finally {
+ super.after();
+ }
+ }
+
+ @Test
+ public void testAggregation() throws RepositoryException {
+ PrivilegeManager privilegeManager = getPrivilegeManager(root);
+
+ // EXERCISE: for all aggregated privileges define the mapping of the
privilege name to declaredAggregates
+ Map<String, Set<Privilege>> expectedResults = ImmutableMap.of(
+ /* EXERCISE */
+ );
+
+ Iterable<Privilege> aggregated = Iterables.<Privilege>filter(
+
ImmutableList.<Privilege>copyOf(privilegeManager.getRegisteredPrivileges()),
+ new Predicate<Privilege>() {
+ @Override
+ public boolean apply(@Nullable Privilege input) {
+ return input != null && input.isAggregate();
+ }
+ });
+
+ for (Privilege aggrPrivilege : aggregated) {
+ Set<Privilege> expected =
expectedResults.get(aggrPrivilege.getName());
+ assertEquals(expected,
ImmutableSet.copyOf(aggrPrivilege.getDeclaredAggregatePrivileges()));
+ }
+ }
+
+ @Test
+ public void testMapItems() throws Exception {
+ Privilege jcrAll = acMgr.privilegeFromName(PrivilegeConstants.JCR_ALL);
+ for (Privilege privilege : jcrAll.getAggregatePrivileges()) {
+ try {
+ // EXERCISE : modify item(s) affected by the given privilege
and verify that it fails
+
+ setupAcl(privilege, acMgr);
+ testRoot.refresh();
+
+ // EXERCISE : modify the same item(s) again and verify that it
succeeds
+
+ } finally {
+ clearAcl(acMgr);
+ testRoot.refresh();
+ }
+
+ }
+ }
+
+ private void setupAcl(Privilege privilege, AccessControlManager acMgr)
throws Exception {
+ JackrabbitAccessControlList acl =
AccessControlUtils.getAccessControlList(acMgr, "/");
+ acl.addEntry(getTestUser().getPrincipal(), new Privilege[]
{privilege}, true);
+ acMgr.setPolicy("/", acl);
+ root.commit();
+ }
+
+ public void clearAcl(AccessControlManager acMgr) throws
RepositoryException, CommitFailedException {
+ AccessControlPolicy[] policies = acMgr.getPolicies("/");
+ for (AccessControlPolicy policy : policies) {
+ acMgr.removePolicy("/", policy);
+ }
+ root.commit();
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L3_BuiltInPrivilegesTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L4_CustomPrivilegeTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L4_CustomPrivilegeTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L4_CustomPrivilegeTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L4_CustomPrivilegeTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,164 @@
+/*
+ * 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.privilege;
+
+import java.security.Principal;
+import java.util.Set;
+import java.util.UUID;
+import javax.annotation.Nullable;
+import javax.jcr.security.Privilege;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+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;
+import static org.junit.Assert.fail;
+
+/**
+ * <pre>
+ * Module: Privilege Management
+ *
=============================================================================
+ *
+ * Title: Custom Privileges
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * The aim of this exercise is to make you familiar with the API to register
+ * custom privileges and provide you with the basic understanding on how those
+ * are being evaluated and enforced.
+ *
+ * Exercises:
+ *
+ * - {@link #testCustomPrivilege()}
+ * Use this test to verify the nature of the aggregated custom privilege
+ * registered in the setup.
+ *
+ * - {@link #testJcrAll()}
+ * Verify that our custom privileges properly listed in the aggregated
privileges
+ * exposed by jcr:all.
+ *
+ * Question: Having completed this test, what can you say about the nature
of jcr:all?
+ * Question: What does that mean for the internal representation of jcr:all?
+ *
+ * - {@link #testHasPrivilege()}
+ * Fix the test case such that the given set of test princials is granted the
+ * custom privileges at the test node.
+ *
+ * Question: Would it also work if you would grant jcr:all for any of the
test principals?
+ *
+ *
+ * Advanced Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * As you can see in the permission evaluation implementation custom privileges
+ * will NOT be enforced upon read/write to the repository as the nature of the
+ * custom privilege is by definition known to the application responsible for
+ * the registration and therefore must be evaluated/enforced on the application
+ * level as well.
+ *
+ * - Verify this by taking another look at the Oak internal permission
evaluation.
+ *
+ * Question: Can you identify which parts in Oak would need to be extended
and
+ * which interfaces you would need to implement and plug/replace if
+ * you wanted to enforce your custom privileges in the repository?
+ *
+ *
+ * Related Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link org.apache.jackrabbit.oak.security.privilege.L6_JcrAllTest}
+ *
+ * </pre>
+ *
+ * @see
org.apache.jackrabbit.api.security.authorization.PrivilegeManager#registerPrivilege(String,
boolean, String[])
+ */
+public class L4_CustomPrivilegeTest extends AbstractSecurityTest {
+
+ private PrivilegeManager privilegeManager;
+ private Privilege customAbstractPriv;
+ private Privilege customAggrPriv;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ privilegeManager = getPrivilegeManager(root);
+ customAbstractPriv = privilegeManager.registerPrivilege(
+ "customAbstractPriv_" + UUID.randomUUID().toString(), true,
new String[0]);
+ customAggrPriv = privilegeManager.registerPrivilege(
+ "customAbstractPriv_" + UUID.randomUUID().toString(), false,
+ new String[] {customAbstractPriv.getName(),
PrivilegeConstants.JCR_READ});
+ }
+
+ private static void assertEqualPrivileges(Set<String> expectedNames,
Privilege[] result) {
+ if (expectedNames.size() != result.length) {
+ fail();
+ }
+
+ Iterable<String> resultNames =
Iterables.transform(Sets.newHashSet(result), new Function<Privilege, String>() {
+ @Nullable
+ @Override
+ public String apply(Privilege input) {
+ return input.toString();
+ }
+ });
+
+ Iterables.removeAll(resultNames, expectedNames);
+ assertFalse(resultNames.iterator().hasNext());
+ }
+
+ @Test
+ public void testCustomPrivilege() {
+ Set<String> expected = null; //EXERCISE
+ assertEqualPrivileges(expected,
customAggrPriv.getDeclaredAggregatePrivileges());
+
+ expected = null; // EXERCISE
+ assertEqualPrivileges(expected,
customAggrPriv.getAggregatePrivileges());
+
+ Boolean expectedIsAbstract = null; // EXERCISE
+ assertEquals(expectedIsAbstract.booleanValue(),
customAggrPriv.isAbstract());
+ }
+
+ @Test
+ public void testJcrAll() {
+ // EXERCISE : verify that the custom privileges are contained in the
jcr:all aggregation
+ }
+
+ @Test
+ public void testHasPrivilege() throws Exception {
+ try {
+ // EXERCISE : fix the test case such that the test principals have
the specified privileges granted at "/"
+
+ Privilege[] testPrivileges = new Privilege[] {customAbstractPriv,
customAggrPriv};
+ Set<Principal> testPrincipals =
ImmutableSet.of(EveryonePrincipal.getInstance(), getTestUser().getPrincipal());
+ boolean hasPrivilege =
getAccessControlManager(root).hasPrivileges("/", testPrincipals,
testPrivileges);
+
+ assertTrue(hasPrivilege);
+ } finally {
+ // EXERCISE: cleanup the changes.
+ }
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L4_CustomPrivilegeTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L5_PrivilegeContentTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L5_PrivilegeContentTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L5_PrivilegeContentTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L5_PrivilegeContentTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,176 @@
+/*
+ * 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.privilege;
+
+import java.util.Set;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinition;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeUtil;
+import org.apache.jackrabbit.oak.util.TreeUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * <pre>
+ * Module: Privilege Management
+ *
=============================================================================
+ *
+ * Title: Representation of Privileges in the Repository
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand how privileges are represented in the repository content.
+ *
+ * Exercises:
+ *
+ * - {@link #testPrivilegeRoot()}
+ * This test retrieves the root node below which all registered privileges
are
+ * being stored. Make yourself familiar with the structure by looking at the
+ * node type definitions in 'builtin-nodetypes.cnd' and complete the test
case
+ * such that it passes.
+ *
+ * Question: What can you say about the structure of the privileges tree in
the repository?
+ * Question: Can you explain why it is located below /jcr:system ?
+ * Question: Go back to {@link
org.apache.jackrabbit.oak.security.privilege.L4_CustomPrivilegeTest}
+ * and take a closer look at the tree/node that stores your custom privilege.
+ *
+ * - {@link #testPrivilegeDefinition()}
+ * Each tree/node presenting a privilege in fact just stores the basic
definition
+ * of the privilege. Use this exercise to compare the difference between the
+ * definition (and it's tree) and the resulting privilege.
+ *
+ * Question: What properties stored on the privilege definition tree are not
exposed by
+ * {@link
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinition}?
+ * -> see advanced exercises.
+ *
+ *
+ * Advanced Exercises
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link #testPrivilegeBits()}
+ * For internal handling of privileges the Oak repository doesn't use the
+ * privilege names (and the expensive resolution of the aggregation) but
+ * rather makes use of internal long representation of the privileges.
+ * Use this exercise to become familiar with
+ * - {@link
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider}
+ * - {@link org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits}
+ * and how they are represented in the privilege content and how they are
+ * used to internally deal with privileges.
+ *
+ * Question: How are PrivilegeBits created from privilege name(s)
+ * Question: How are they stored with the privilege definition?
+ * Question: Can you also retrieve the PropertyState on the privilege trees
that
+ * effectively stores the long presentation as used in the
PrivilegeBits?
+ *
+ * - {@link #testNext()}
+ * This exercises aims to help you understand how the implementation keeps
+ * track of the internal long representation of privileges and how those
+ * long representations are being calculated for newly registered privileges.
+ * Resolve the TODOs in the test-case and explain the behavior.
+ *
+ * Question: Can you identify where 'rep:next' is being updated?
+ * Question: Try to set the value of rep:next manually and explain what
happens.
+ *
+ *
+ * Related Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link org.apache.jackrabbit.oak.security.privilege.L6_JcrAllTest}
+ * - {@link
org.apache.jackrabbit.oak.security.authorization.permission.L4_PrivilegesAndPermissionsTest}
+ * - {@link
org.apache.jackrabbit.oak.security.authorization.permission.L7_PermissionContentTest}
+ *
+ * </pre>
+ */
+public class L5_PrivilegeContentTest extends AbstractSecurityTest {
+
+
+ @Test
+ public void testPrivilegeRoot() {
+ Tree privilegesRoot = root.getTree(PrivilegeConstants.PRIVILEGES_PATH);
+
+ String name = null; // TODO
+ assertEquals(name, privilegesRoot.getName());
+
+ String primaryType = null; // TODO
+ assertEquals(primaryType, TreeUtil.getPrimaryTypeName(privilegesRoot));
+
+ // TODO: look at the node type definition in the file
'builtin-nodetypes.cnd'
+ // Question: can you predict how the tree defined the 'privilegesRoot'
tree looks like?
+ }
+
+ @Test
+ public void testPrivilegeDefinition() throws RepositoryException {
+ Tree repWriteTree =
PrivilegeUtil.getPrivilegesTree(root).getChild(PrivilegeConstants.REP_WRITE);
+
+ PrivilegeDefinition def = PrivilegeUtil.readDefinition(repWriteTree);
+
+ String expectedName = null; // TODO
+ assertEquals(expectedName, def.getName());
+
+ boolean isAbstract = false; // TODO
+ assertEquals(isAbstract, def.isAbstract());
+
+ Set<String> expectedAggregates = null; // TODO
+ assertEquals(expectedAggregates, def.getDeclaredAggregateNames());
+
+ // TODO: compare the internal privilege definition (and it's tree
representation) with the privilege itself.
+ Privilege repWritePrivilege =
getPrivilegeManager(root).getPrivilege(PrivilegeConstants.REP_WRITE);
+ }
+
+ @Test
+ public void testPrivilegeBits() {
+ Tree jcrReadTree =
PrivilegeUtil.getPrivilegesTree(root).getChild(PrivilegeConstants.JCR_READ);
+ Tree repWriteTree =
PrivilegeUtil.getPrivilegesTree(root).getChild(PrivilegeConstants.REP_WRITE);
+
+ PrivilegeBitsProvider provider = new PrivilegeBitsProvider(root);
+ PrivilegeBits privilegeBits =
provider.getBits(PrivilegeConstants.REP_WRITE, PrivilegeBits.JCR_READ);
+
+ PrivilegeBits readBits = PrivilegeBits.getInstance(jcrReadTree);
+ PrivilegeBits writeBits = PrivilegeBits.getInstance(jcrReadTree);
+
+ // TODO: play with 'PrivilegeBits' methods to compare 'privilegeBits'
with 'readBits' and 'writeBits'
+ // TODO: retrieve the property that stores the long representation of
each privilege above
+ }
+
+ @Test
+ public void testNext() throws RepositoryException, CommitFailedException {
+ PropertyState next =
PrivilegeUtil.getPrivilegesTree(root).getProperty(PrivilegeConstants.REP_NEXT);
+
+ PrivilegeManager privilegeManager = getPrivilegeManager(root);
+ Privilege newPrivilege =
privilegeManager.registerPrivilege("myPrivilege", true, null);
+ root.commit();
+
+ // TODO: compare the 'next' property state with rep:bits property of
the newly created privilege.
+
+ PropertyState nextAgain =
PrivilegeUtil.getPrivilegesTree(root).getProperty(PrivilegeConstants.REP_NEXT);
+
+ // TODO: look at the new value of rep:next and explain it. Q: where
did it get modified?
+
+ // TODO: try to modify rep:next manually and explain what happens.
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L5_PrivilegeContentTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L6_JcrAllTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L6_JcrAllTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L6_JcrAllTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L6_JcrAllTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,82 @@
+/*
+ * 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.privilege;
+
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeUtil;
+import org.junit.Test;
+
+/**
+ * <pre>
+ * Module: Privilege Management
+ *
=============================================================================
+ *
+ * Title: The Privilege 'jcr:all'
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand the meaning of the jcr:all privilege and how it is maintained
+ * in the Oak repository.
+ *
+ * Exercises:
+ *
+ * - Overview
+ * Read again what JSR 283 states about {@link Privilege#JCR_ALL) and review
+ * again the result of {@link L4_CustomPrivilegeTest#testJcrAll()}
+ *
+ * - {@link #testManualModification()}
+ * This test case tries to modify the tree storing the jcr:all privilege
+ * definition. Walk through the test and explain what happens.
+ * Fix the test case such that it passes.
+ *
+ * Question: Can you identify the relevant class in the Oak code base?
+ * Question: Can you explain what it does and why?
+ *
+ *
+ * Advanced Exercise
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link #testJcrAllInPermissionStore()}
+ * Due to the dynamic nature of jcr:all the long-representation of this
privilege
+ * may change over time.
+ * This exercise aim to show you how granting|denying jcr:all is reflected
+ * in the permission store.
+ *
+ *
+ * </pre>
+ */
+public class L6_JcrAllTest extends AbstractSecurityTest {
+
+ @Test
+ public void testManualModification() throws Exception {
+ // TODO: fix the test case such that it passes.
+
+ Tree jcrAllTree =
PrivilegeUtil.getPrivilegesTree(root).getChild(PrivilegeConstants.JCR_ALL);
+
+ jcrAllTree.removeProperty(PrivilegeConstants.REP_AGGREGATES);
+ root.commit();
+ }
+
+ @Test
+ public void testJcrAllInPermissionStore() {
+ // TODO
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L6_JcrAllTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L7_PrivilegeDiscoveryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L7_PrivilegeDiscoveryTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L7_PrivilegeDiscoveryTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L7_PrivilegeDiscoveryTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,74 @@
+/*
+ * 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.privilege;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * <pre>
+ * Module: Privilege Management | Authorization
+ *
=============================================================================
+ *
+ * Title: Privilege Discovery
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * The aim of this exercise is to make you familiar on how to discover
privileges
+ * granted for a given {@link javax.jcr.Session} or a given set of {@link
java.security.Principal}s.
+ * After having completed this exercise you should be able to explain the
difference
+ * compare to permission discovery as well as the benefit/drawback of using
+ * this API.
+ *
+ * Exercises:
+ *
+ * - {@link #testHasPrivileges()}
+ * TODO
+ *
+ * - {@link #testGetPrivileges()}
+ * TODO
+ *
+ * - {@link #testCanAddNode()}
+ * TODO
+ *
+ *
+ * Related Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link
org.apache.jackrabbit.oak.security.authorization.permission.L2_PermissionDiscoveryTest}
+ * - {@link
org.apache.jackrabbit.oak.security.authorization.permission.L4_PrivilegesAndPermissionsTest}
+ *
+ * </pre>
+ *
+ * @see TODO
+ */
+public class L7_PrivilegeDiscoveryTest extends AbstractJCRTest {
+
+ public void testHasPrivileges() {
+ // TODO
+ }
+
+ public void testGetPrivileges() {
+ // TODO
+ }
+
+ public void testCanAddNode() {
+ // TODO
+ }
+ // TODO; diff wrt session.haspermission
+ // TODO: Acmgr.hasPrivilege || getPrivileges
+
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/privilege/L7_PrivilegeDiscoveryTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L10_RemovalAndMembershipTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L10_RemovalAndMembershipTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L10_RemovalAndMembershipTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L10_RemovalAndMembershipTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,177 @@
+/*
+ * 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.user;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.security.ExerciseUtility;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * <pre>
+ * Module: User Management
+ *
=============================================================================
+ *
+ * Title: Authorizable Removal and Group Membership
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand how the removal of a given authorizable affects it's group
membership.
+ *
+ * Exercises:
+ *
+ * - {@link #testMemberAfterRecreation()}
+ * Run the test and explain why after removal and re-creation the new user is
+ * automatically member of the test group.
+ *
+ * - {@link #testNotMemberAfterRecreation()}
+ * This is the same test as above but now the re-created test-user must not
+ * be member of 'administrators'. How do you need to do in order to make the
+ * test case pass?
+ *
+ *
+ * Additional Exercise:
+ *
-----------------------------------------------------------------------------
+ *
+ * The following exercises can easily be performed in a Sling based repository
+ * installation (e.g. Granite|CQ) with the same setup as in this test class:
+ *
+ * 1. Test Setup
+ *
+ * - Login as 'admin'
+ * - Create a test-user and make it member of the 'administrators' group.
+ * - Create a second user 'uadmin:uadmin' and make sure it is granted all
privileges
+ * at the node of the test-user (Variant: make it member of
'user-administrators'.
+ * - Verify that your changes have been persisted.
+ *
+ * 2. Automatic Membership Cleanup
+ *
+ * - Configure your system such that membership cleanup is performed upon
+ * removal of the test user.
+ * Explain what you need to do (Hint: authorizable actions).
+ *
+ * 3. Test Execution with 'uadmin'
+ *
+ * - Logout
+ * - Login with the 'uadmin' user which can remove the test-user
+ * - Remove the test-user and persist the changes
+ * - Login as 'admin' again and test if the user has been removed; if yes,
recreate
+ * it and verify and if members-list at 'administrators' has been adjust
(test-user removed).
+ *
+ * - Explain the result both for the main and variant.
+ * > the removal failed: explain why?
+ * > the member-cleanup didn't succeed: explain why?
+ *
+ * 4. Test Execution with 'admin'
+ *
+ * - Perform the same test as 'admin' and compare the result with 3.
+ * - Explain whats the difference and why it works.
+ *
+ *
+ * Advanced Exercise:
+ *
-----------------------------------------------------------------------------
+ *
+ * - Discuss the possibilities Oak which could help to address the drawback
you identified
+ * with the {@link
org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction}
+ * approach.
+ *
+ *
+ * Related Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link L9_RemoveAuthorizableTest ()}
+ *
+ * </pre>
+ *
+ * @see Group#addMember(org.apache.jackrabbit.api.security.user.Authorizable)
+ * @see
Group#removeMember(org.apache.jackrabbit.api.security.user.Authorizable)
+ * @see Group#isMember(org.apache.jackrabbit.api.security.user.Authorizable)
+ * @see org.apache.jackrabbit.api.security.user.Authorizable#memberOf()
+ * @see
org.apache.jackrabbit.oak.spi.security.user.action.ClearMembershipAction
+ */
+public class L10_RemovalAndMembershipTest extends AbstractSecurityTest {
+
+ private User user;
+ private Group administrators;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ user = getTestUser();
+
+ administrators = getUserManager(root).createGroup("administrators");
+ administrators.addMember(user);
+
+ root.commit();
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ if (administrators != null) {
+ administrators.remove();
+ root.commit();
+ }
+ } finally {
+ super.after();
+ }
+ }
+
+ @Test
+ public void testMemberAfterRecreation() throws RepositoryException,
CommitFailedException {
+ // remove the user
+ String id = user.getID();
+ user.remove();
+ root.commit();
+
+ // create a new user with the same ID
+ User u = getUserManager(root).createUser(id, ExerciseUtility.TEST_PW);
+ root.commit();
+
+ // EXERCISE: explain why this user cannot be added as member?
+ assertFalse(administrators.addMember(u));
+
+ // EXERCISE: explain why is this user is still member of the test
group?
+ assertTrue(administrators.isDeclaredMember(u));
+ }
+
+ @Test
+ public void testNotMemberAfterRecreation() throws RepositoryException,
CommitFailedException {
+
+ // EXERCISE : adjust the test-case such that upon re-creation the user
is not member of administrators.
+ // HINT : do it right here
+
+ // remove the user
+ String id = user.getID();
+ user.remove();
+ root.commit();
+
+ // create a new user with the same ID
+ User u = getUserManager(root).createUser(id, ExerciseUtility.TEST_PW);
+ root.commit();
+
+ assertFalse(administrators.isDeclaredMember(u));
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L10_RemovalAndMembershipTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L11_PasswordTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L11_PasswordTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L11_PasswordTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L11_PasswordTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,209 @@
+/*
+ * 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.user;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.security.ExerciseUtility;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+import static org.apache.jackrabbit.oak.security.ExerciseUtility.TEST_PW;
+
+/**
+ * <pre>
+ * Module: User Management
+ *
=============================================================================
+ *
+ * Title: Password Test
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Become familiar with password related parts of the user management API and
+ * get to know some implementation details.
+ *
+ * Exercises:
+ *
+ * - {@link #testGetCredentials()}
+ * Understand that the password is not exposed as plain-word property from
+ * the user. Look at the return-value of the {@link
org.apache.jackrabbit.api.security.user.User#getCredentials()}
+ * call and what it looks like. Fix the test-case accordingly.
+ *
+ * Question: Can you use the exposed Credentials to login to the repository?
+ *
+ * - {@link #testPasswordInContent()}
+ * Creates a new user with a valid password. Inspect how the password is
being
+ * store in the repository (Note: implementation detail!) and fill in the
+ * right property name to get the test-case pass.
+ * Explain why the password property doesn't contain the password string.
+ *
+ * - {@link #testCreateUserAndLogin()}
+ * Same as {@link #testPasswordInContent()} but additional aims to login as
+ * the new user.
+ * Fix the test by creating the correct {@link javax.jcr.Credentials}.
+ *
+ * - {@link #testCreateUserWithoutPassword()}
+ * This test creates a new user with a 'null' password. Inspect the user node
+ * created by this method and add the correct assertion wrt password.
+ *
+ * - {@link #testCreateUserWithoutPasswordAndLogin()}
+ * Same as {@link #testCreateUserWithoutPassword()}. This time fix the test
+ * case to properly reflect the expected behavior upon login for that new
user.
+ *
+ * - {@link #testChangePassword()}
+ * Change the password of an existing user. Use both variants and get
familiar
+ * with the implementation specific constraints.
+ *
+ *
+ * Additional Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * In a OSGI-based Oak installation (Sling|Granite|CQ) you can easily perform
the
+ * following additional test.
+ * Note: You can also do that in Java by building a new Jcr/Oak repository with
+ * the corresponding configuration parameters set.
+ *
+ * - Go to the system console and change the default configuration parameters
+ * in the 'Apache Jackrabbit Oak UserConfiguration' and play with the
following
+ * configuration parameters:
+ * - {@link
org.apache.jackrabbit.oak.spi.security.user.UserConstants#PARAM_PASSWORD_HASH_ALGORITHM}
+ * - {@link
org.apache.jackrabbit.oak.spi.security.user.UserConstants#PARAM_PASSWORD_HASH_ITERATIONS}
+ * - {@link
org.apache.jackrabbit.oak.spi.security.user.UserConstants#PARAM_PASSWORD_SALT_SIZE}
+ * Change the password of a test user and observe the changes.
+ *
+ * - Go to the system console and look for the 'Apache Jackrabbit Oak
AuthorizableActionProvider'.
+ * Enable the password validation action and then change the password of
+ * an existing test user.
+ *
+ *
+ * Advanced Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - Write a custom password validation action and plug it into your
repository.
+ * See Oak documentation for some hints.
+ *
+ *
+ * Related Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - {@link L12_PasswordExpiryTest ()}
+ * - {@link
org.apache.jackrabbit.oak.security.user.action.L2_AuthorizableActionTest ()}
+ *
+ * </pre>
+ *
+ * @see User#changePassword(String, String)
+ * @see User#changePassword(String)
+ * @see
org.apache.jackrabbit.oak.spi.security.user.action.PasswordValidationAction
+ * @see org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtil
+ */
+public class L11_PasswordTest extends AbstractJCRTest {
+
+ private UserManager userManager;
+
+ private String testId;
+ private User testUser;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ userManager = ((JackrabbitSession) superuser).getUserManager();
+ testId = ExerciseUtility.getTestId("testUser");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ if (testUser != null) {
+ testUser.remove();
+ }
+ superuser.save();
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ public void testGetCredentials() throws RepositoryException {
+ testUser = userManager.createUser(testId, TEST_PW);
+ Credentials creds = testUser.getCredentials();
+
+ // EXERCISE fix the expectation
+ Credentials expected = null;
+ assertEquals(expected, creds);
+
+ // EXERCISE : complete and explain the expected behavior
+ getHelper().getRepository().login(creds).logout();
+ }
+
+ public void testPasswordInContent() throws RepositoryException {
+ testUser = userManager.createUser(testId, TEST_PW);
+ superuser.save();
+
+ Node userNode = superuser.getNode(testUser.getPath());
+ String pwPropertyName = null; // EXERCISE: fill in
+
+ Property pwProperty = userNode.getProperty(pwPropertyName);
+
+ // EXERCISE: explain why the password property doesn't contain the
'pw' string
+ assertFalse(TEST_PW.equals(pwProperty.getString()));
+ }
+
+ public void testCreateUserAndLogin() throws RepositoryException {
+ testUser = userManager.createUser(testId, TEST_PW);
+ superuser.save();
+
+ Credentials creds = null; // EXERCISE build the credentials
+ getHelper().getRepository().login(creds).logout();
+ }
+
+ public void testCreateUserWithoutPassword() throws RepositoryException {
+ testUser = userManager.createUser(testId, null);
+ superuser.save();
+
+ // EXERCISE: look at the user node. does it have a password property
set?
+ // EXERCISE: add the correct assertion
+ Node userNode = superuser.getNode(testUser.getPath());
+ }
+
+ public void testCreateUserWithoutPasswordAndLogin() throws
RepositoryException {
+ testUser = userManager.createUser(testId, null);
+ superuser.save();
+
+ // EXERCISE: build the credentials and fix the test-case such that it
no longer fails
+ Credentials creds = null;
+ getHelper().getRepository().login(creds).logout();
+ }
+
+ public void testChangePassword() throws RepositoryException {
+ testUser = userManager.createUser(testId, null);
+ superuser.save();
+
+ String newPassword = null; // EXERCISE : define valid value(s)
+ testUser.changePassword(newPassword);
+
+ String oldPassword = null; // EXERCISE : fill in the correct value
+ newPassword = null; // EXERCISE : fill in a valid value; Q: can
you use null?
+ testUser.changePassword(newPassword, oldPassword);
+
+ superuser.save();
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L11_PasswordTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L12_PasswordExpiryTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L12_PasswordExpiryTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L12_PasswordExpiryTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L12_PasswordExpiryTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,50 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+
+/**
+ * <pre>
+ * Module: User Management
+ *
=============================================================================
+ *
+ * Title: Password Expiration
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand the password expiration feature how it can be enabled in the
+ * repository.
+ *
+ * Exercises:
+ *
+ * - {@link #TODO}
+ *
+ *
+ * Additional Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * TODO
+ *
+ * </pre>
+ *
+ * @see TODO
+ */
+public class L12_PasswordExpiryTest extends AbstractSecurityTest {
+
+
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L12_PasswordExpiryTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L13_SystemUserTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L13_SystemUserTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L13_SystemUserTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L13_SystemUserTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,213 @@
+/*
+ * 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.user;
+
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.security.ExerciseUtility;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.oak.util.TreeUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * <pre>
+ * Module: User Management
+ *
=============================================================================
+ *
+ * Title: System Users
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand the difference between system users and regular users and why we
+ * decided to introduce a dedicated API for system users in Jackrabbit API
2.10.
+ *
+ * Exercises:
+ *
+ * - Overview
+ * Walk through the system user creation in the setup and also take a closer
+ * look at the node type definition in the builtin_nodetypes.cnd
+ *
+ * Question: What can you say about the {@code rep:SystemUser} node type
definition?
+ * Question: Can you explain how this is reflected in the default user
management implementation?
+ * Question: How is a system user different from a regular user? Can you
list all differences?
+ *
+ * - {@link #testSystemUser()}
+ * This test retrieves the system user created in the setup. Complete the
+ * test to become familiar with the handing of system users in the user
+ * management API.
+ *
+ * - {@link #testSystemUserNode()}
+ * This test illustrates some of the implementation details on how system
users
+ * are being represented in the repository. Complete the test to get it pass.
+ *
+ * Question: Can you explain what the 'memberOf' method will return if there
+ * exists an everyone authorizable group?
+ *
+ * - {@link #testSystemUserPrincipal()}
+ * Look at the principal associated with the system user created in the
setup.
+ * Verify your expectations wrt principal name and type of principal and the
+ * group membership and fix the test accordingly.
+ *
+ * Question: Can you elaborate about the impact of the test results when it
comes to
+ * permission evaluation for system users?
+ * Use {@link
org.apache.jackrabbit.oak.security.authorization.permission.L3_PrecedenceRulesTest}
+ * to verify your expectations or to get some more insight.
+ *
+ * - {@link #testSetPassword()}
+ * This test attempts to set a password to the system user created in the
+ * setup. Fix the test and the assertion and explain the behavior.
+ *
+ * Question: How is setting passwords different for system users compared to
regular users?
+ * Question: Look at the node type definition again. What can you state wrt
rep:password in the effective node type?
+ * Question: Walk through the test again. Can you identify the exact
location(s) for special handling?
+ *
+ * - {@link #testGetCredentials()}
+ * Look at the credentials object exposed by the system user and compare it
+ * with the result as return in {@link L11_PasswordTest#testGetCredentials()}
+ *
+ * </pre>
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/JCR-3802">JCR-3802</a>
+ */
+public class L13_SystemUserTest extends AbstractSecurityTest {
+
+ private User systemUser;
+ private Group testGroup;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ systemUser =
getUserManager(root).createSystemUser(ExerciseUtility.getTestId("testSystemUser"),
null);
+ testGroup = ExerciseUtility.createTestGroup(getUserManager(root));
+ testGroup.addMember(systemUser);
+ root.commit();
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ if (systemUser != null) {
+ systemUser.remove();
+ }
+ if (testGroup != null) {
+ testGroup.remove();
+ }
+ root.commit();
+ } finally {
+ super.after();
+ }
+ }
+
+ @Test
+ public void testSystemUser() throws RepositoryException {
+ UserManager userMgr = getUserManager(root);
+ Authorizable authorizable =
userMgr.getAuthorizable(systemUser.getID());
+
+ Boolean isGroup = null; // EXERCISE
+ assertEquals(isGroup.booleanValue(), authorizable.isGroup());
+
+ Boolean isAdmin = null; // EXERCISE
+ assertEquals(isAdmin.booleanValue(), systemUser.isAdmin());
+
+ // EXERCISE: retrieve the authorizable by class: what is the correct
authorizble-class to use?
+ Class cls = null;
+ Authorizable sUser = userMgr.getAuthorizable(systemUser.getID(), cls);
+
+ Iterator<Group> memberOf = sUser.memberOf();
+ Set<Group> expectedGroups = null; // EXERCISE
+ while (memberOf.hasNext()) {
+ assertTrue(expectedGroups.remove(memberOf.next()));
+ }
+ assertTrue(expectedGroups.isEmpty());
+ }
+
+ @Test
+ public void testSystemUserNode() throws RepositoryException {
+ Tree systemUserTree = root.getTree(systemUser.getPath());
+ assertTrue(systemUserTree.exists());
+
+ String expectedPrimaryTypeName = null; // EXERCISE
+ assertEquals(expectedPrimaryTypeName,
TreeUtil.getPrimaryTypeName(systemUserTree));
+
+ String expectedId = null; // EXERCISE
+ assertEquals(expectedId, TreeUtil.getString(systemUserTree,
UserConstants.REP_AUTHORIZABLE_ID));
+
+ String expectedPw = null; // EXERCISE
+ assertEquals(expectedPw, TreeUtil.getString(systemUserTree,
UserConstants.REP_PASSWORD));
+ }
+
+ @Test
+ public void testSystemUserPrincipal() throws RepositoryException {
+ Authorizable authorizable =
getUserManager(root).getAuthorizable(systemUser.getID());
+
+ // EXERCISE: what is the nature of the principal of the system user?
Assert your expectedation.
+ Principal principal = authorizable.getPrincipal();
+
+ PrincipalManager principalManager = getPrincipalManager(root);
+ PrincipalIterator pIter =
principalManager.getGroupMembership(principal);
+ int expectedSize = -1; // EXERCISE
+ assertEquals(expectedSize, pIter.getSize());
+
+ List<Principal> expectedGroupPrincipals = null; // EXERCISE
+ while (pIter.hasNext()) {
+ Principal group = pIter.nextPrincipal();
+ assertTrue(expectedGroupPrincipals.remove(group));
+ }
+ assertTrue(expectedGroupPrincipals.isEmpty());
+ }
+
+ @Test
+ public void testSetPassword() throws RepositoryException,
CommitFailedException {
+ systemUser.changePassword(ExerciseUtility.TEST_PW);
+
+ Tree systemUserTree = root.getTree(systemUser.getPath());
+ String expectedPw = null; // EXERCISE
+ assertEquals(expectedPw, TreeUtil.getString(systemUserTree,
UserConstants.REP_PASSWORD));
+
+ systemUserTree.setProperty(UserConstants.REP_PASSWORD, "anotherPw");
+ root.commit();
+ }
+
+ @Test
+ public void testGetCredentials() throws RepositoryException {
+ // EXERCISE look at the Credentials object returned from the system
user and compare it with the result from PasswordTest#getCredentials()
+
+ Credentials creds = systemUser.getCredentials();
+
+ // EXERCISE fix the expectation
+ Credentials expected = null;
+ assertEquals(expected, creds);
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L13_SystemUserTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L14_AuthorizableNodeNameTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L14_AuthorizableNodeNameTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L14_AuthorizableNodeNameTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L14_AuthorizableNodeNameTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,136 @@
+/*
+ * 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.user;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.test.api.util.Text;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * <pre>
+ * Module: User Management
+ *
=============================================================================
+ *
+ * Title: Authorizable Node Name
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Become familiar with the {@link
org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName}
+ * interface and how it is used in the default implementation. After having
+ * completed this test you should also be able to write and configure a custom
+ * implemenation understanding the impact it will have on the default user
+ * management.
+ *
+ * Exercises:
+ *
+ * - {@link #testAuthorizableNodeName()}
+ * Test the fallback behaviour as implemented in Oak if no
+ * {@link org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName}
+ * interface is configured.
+ *
+ * - {@link #testRandomAuthorizableNodeName()}
+ * Same as above but with an {@link
org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName}
+ * configured.
+ *
+ *
+ * Advanced Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * - Create a custom implementation of the {@link
org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName}
+ * interface.
+ *
+ * - Make your implementation a OSGi service as described in the documentation
+ * and deploy it in your Sling (Granite|CQ) repository.
+ * Verify that creating a new user or group actually makes use of your
+ * implementation.
+ *
+ * </pre>
+ *
+ * @see org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName
+ * @see org.apache.jackrabbit.oak.security.user.RandomAuthorizableNodeName
+ */
+public class L14_AuthorizableNodeNameTest extends AbstractSecurityTest {
+
+ private UserManager userManager;
+ private User testUser;
+
+ private AuthorizableNodeName nameGenerator = new
RandomAuthorizableNodeName();
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ userManager = getUserManager(root);
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ if (testUser != null) {
+ testUser.remove();
+ }
+ root.commit();
+ } finally {
+ super.after();
+ }
+ }
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ // EXERCISE: un-comment for 'testRandomAuthorizableNodeName'
+// ConfigurationParameters userConfig =
ConfigurationParameters.of(UserConstants.PARAM_AUTHORIZABLE_NODE_NAME,
nameGenerator);
+// return ConfigurationParameters.of(UserConfiguration.NAME,
userConfig);
+ return ConfigurationParameters.EMPTY;
+ }
+
+ @Test
+ public void testAuthorizableNodeName() throws RepositoryException {
+ testUser = userManager.createUser("test/:User", null);
+
+ String nodeName = Text.getName(testUser.getPath());
+ String expectedNodeName = null; // EXERCISE : fill in the expected
value
+
+ assertEquals(expectedNodeName, nodeName);
+ }
+
+ @Test
+ public void testRandomAuthorizableNodeName() throws RepositoryException {
+ // EXERCISE: uncomment the setup in 'getSecurityConfigParameters'
before running this test.
+
+ // verify that the configuration is correct:
+ AuthorizableNodeName configured =
getUserConfiguration().getParameters().getConfigValue(UserConstants.PARAM_AUTHORIZABLE_NODE_NAME,
AuthorizableNodeName.DEFAULT);
+ assertNotSame(AuthorizableNodeName.DEFAULT, configured);
+ assertTrue(configured instanceof RandomAuthorizableNodeName);
+
+ testUser = userManager.createUser("test/:User", null);
+
+ String nodeName = Text.getName(testUser.getPath());
+
+ // EXERCISE: write the correct assertion wrt the generated node name.
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L14_AuthorizableNodeNameTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L15_RepositoryWithoutAnonymousTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L15_RepositoryWithoutAnonymousTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L15_RepositoryWithoutAnonymousTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L15_RepositoryWithoutAnonymousTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,76 @@
+/*
+ * 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.user;
+
+import javax.jcr.GuestCredentials;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ * <pre>
+ * Module: User Management (Authentication)
+ *
=============================================================================
+ *
+ * Title: Repository without Anonymous
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand how the repository can be setup without having an anonymous user
+ * and how this affects the guest login.
+ *
+ * Exercises:
+ *
+ * - {@link #testAnonymousLogin()}
+ * Use the test to setup a new Oak repository that doesn't allow any
anonymous access
+ *
+ * </pre>
+ *
+ * @see org.apache.jackrabbit.oak.security.user.UserInitializer
+ * @see
org.apache.jackrabbit.oak.spi.security.user.UserConstants#PARAM_ANONYMOUS_ID
+ */
+public class L15_RepositoryWithoutAnonymousTest extends AbstractSecurityTest {
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ // EXERCISE : use the built-in oak configuration settings to prevent
anonymous access altogether
+ ConfigurationParameters userConfig = ConfigurationParameters.EMPTY;
+
+ return ConfigurationParameters.of(UserConfiguration.NAME, userConfig);
+ }
+
+ @Test
+ public void testAnonymousLogin() throws Exception {
+ ContentSession oakSession = null;
+ try {
+ oakSession = login(new GuestCredentials());
+ fail("Anonymous login must fail.");
+ } catch (javax.security.auth.login.LoginException e) {
+ // success
+ } finally {
+ if (oakSession != null) {
+ oakSession.close();
+ }
+ }
+ }
+
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L15_RepositoryWithoutAnonymousTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L16_RepositoryWithoutUserManagement.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L16_RepositoryWithoutUserManagement.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L16_RepositoryWithoutUserManagement.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L16_RepositoryWithoutUserManagement.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,142 @@
+/*
+ * 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.user;
+
+import javax.jcr.Credentials;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.RepositoryException;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.AuthInfo;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+
+/**
+ * <pre>
+ * Module: User Management & Authentication
+ *
=============================================================================
+ *
+ * Title: Repository without User Management
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * This advanced exercise aims to help you understand that user management
+ * is in fact an optional part of the Oak repository implementation.
+ * While existing application may rely on the user management to be present
+ * by default it isn't too hard to come up with a setup that omits this
+ * module altogether (e.g. if user/group information is being held outside
+ * of the repository content).
+ *
+ * - Define an repository setup that doesn't require a user management
implementation.
+ *
+ * Question: Which parts need to be modified?
+ * Question: What are the consequences for Jcr/Jackrabbit API consumers?
+ *
+ * This exercise mainly consists of defined a
+ * - SecurityProvider implementation
+ * - JAAS configuration
+ * that provides the desired repository setup without user management.
+ *
+ * It comes with the following test cases:
+ *
+ * - {@link #testUserManagementDescriptor()}
+ * Verifies that the repository descriptiors don't list {@link
org.apache.jackrabbit.api.JackrabbitRepository#OPTION_USER_MANAGEMENT_SUPPORTED}
+ * This test passes if your setup is correct.
+ *
+ * - {@link #testNoUserManagementSupported()}
+ * This test verifies that no {@link
org.apache.jackrabbit.oak.spi.security.user.UserConfiguration}
+ * can be obtained from the specified SecurityProvider.
+ *
+ * - {@link #testLogin()}
+ * Finally, a test should prove that a user with the some Credentials (valid
+ * for your custom setup) can actually login to the repository and is
associated
+ * with a valid {@link org.apache.jackrabbit.oak.api.AuthInfo}.
+ *
+ *
+ * Additional Exercises:
+ *
-----------------------------------------------------------------------------
+ *
+ * You may want to write additional test-cases that verify that the
+ * {@link org.apache.jackrabbit.api.security.principal.PrincipalManager} allows
+ * you to retrieve valid principals, which can be used to setup access control
+ * content for your repository (which for simplicity might use the built-in
+ * authorization functionality).
+ *
+ * </pre>
+ *
+ * @see org.apache.jackrabbit.oak.spi.security.SecurityProvider
+ * @see org.apache.jackrabbit.oak.spi.security.user.UserConfiguration
+ */
+public class L16_RepositoryWithoutUserManagement extends AbstractSecurityTest {
+
+ @Override
+ protected SecurityProvider getSecurityProvider() {
+ // EXERCISE: define a security provider that doesn't support user
management
+ // EXERCISE: and therefore doesn't expose a UserConfiguration
implementation.
+ // hint: you need a custom way to look up principals
+ // hint: make use of CustomPrincipalConfiguration and
CustomPrincipalProvider
+ // and adjust it according to your needs!
+ return super.getSecurityProvider();
+ }
+
+ @Override
+ protected Configuration getConfiguration() {
+ // EXERCISE: define a suitable jaas configuration that doesn't tries to
+ // EXERCISE: validate credentials against the user information stored
in the repository
+ // hint: define a configuration with CustomLoginModule (and adjust the
latter for your needs)
+ return super.getConfiguration();
+ }
+
+ @Test
+ public void testUserManagementDescriptor() throws RepositoryException {
+ Oak oak = new Oak()
+ .with(new InitialContent())
+ .with(getSecurityProvider());
+ ContentRepository contentRepository = oak.createContentRepository();
+
+
assertFalse(contentRepository.getDescriptors().getValue(JackrabbitRepository.OPTION_USER_MANAGEMENT_SUPPORTED).getBoolean());
+
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testNoUserManagementSupported() {
+ getSecurityProvider().getConfiguration(UserConfiguration.class);
+ }
+
+ @Test
+ public void testLogin() throws LoginException, NoSuchWorkspaceException {
+ String expectedId = null; // EXERCISE define the userID for the login
+ Credentials creds = null; // EXERCISE define credentials that work in
your setup.
+ ContentSession s = login(creds);
+ AuthInfo authInfo = s.getAuthInfo();
+
+ assertNotSame(AuthInfo.EMPTY, authInfo);
+ assertEquals(expectedId, authInfo.getUserID());
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L16_RepositoryWithoutUserManagement.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L1_IntroductionTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L1_IntroductionTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L1_IntroductionTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L1_IntroductionTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,58 @@
+/*
+ * 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.user;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * <pre>
+ * Module: User Management
+ *
=============================================================================
+ *
+ * Title: Introduction to User Management
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand the usage of user management in Oak.
+ *
+ * Exercises:
+ *
+ * - Overview and Usages of User Management
+ * Search for usage of user management API (e.g. the {@link
org.apache.jackrabbit.api.security.user.UserManager}
+ * interface in Oak. List your findings and discuss the impact.
+ *
+ * Question: Where is the user management API being used?
+ * Question: What are the characteristics of this areas? E.g. are they
configurable/pluggable?
+ * Question: What can you say about the usage of user management in the
authorization code base?
+ *
+ * - Configuration
+ * Look at the default implementation of the {@link
org.apache.jackrabbit.oak.spi.security.user.UserConfiguration}
+ * and try to identify the configurable parts. Compare your results with the
+ * Oak documentation.
+ *
+ * Question: Can you provide a list of configuration options?
+ *
+ * - Pluggability
+ * Starting from the {@link UserConfiguration} again, investigate
+ * how the default implementation could be replaced.
+ *
+ * Question: Is it possible to combine different user management
implementations?
+ *
+ * </pre>
+ */
+public class L1_IntroductionTest extends AbstractJCRTest {
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L1_IntroductionTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L2_CreateAndGetTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L2_CreateAndGetTest.java?rev=1686235&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L2_CreateAndGetTest.java
(added)
+++
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L2_CreateAndGetTest.java
Thu Jun 18 14:30:16 2015
@@ -0,0 +1,132 @@
+/*
+ * 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.user;
+
+import java.security.Principal;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * <pre>
+ * Module: User Management
+ *
=============================================================================
+ *
+ * Title: User Management Basics
+ *
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Make yourself familiar with the basic user management functionality as
present
+ * in Jackrabbit API
+ *
+ * Exercises:
+ *
+ * - {@link #testCreateUser()}
+ * Use this test to create a new user. Play with the parameters.
+ * Question: What are valid values for the parameters?
+ * Question: Which parameters can be 'null'?
+ * Question: What's the effect if one/some parameters are 'null'?
+ *
+ * - {@link #testCreateGroup()}
+ * Use to method to create a new group. Play with the parameters.
+ * Question: What are valid values for the parameters?
+ * Question: Which parameters can be 'null'?
+ * Question: What's the effect if one/some parameters are 'null'?
+ *
+ * - {@link #testGetAuthorizable()}
+ * Play around wit the various methods defined on {@link
org.apache.jackrabbit.api.security.user.UserManager}
+ * to retrieve an existing user or group.
+ *
+ * </pre>
+ */
+public class L2_CreateAndGetTest extends AbstractJCRTest {
+
+ private UserManager userManager;
+
+ private User testUser;
+ private Group testGroup;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ userManager = ((JackrabbitSession) superuser).getUserManager();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ if (testUser != null) {
+ testUser.remove();
+ }
+ if (testGroup != null) {
+ testGroup.remove();
+ }
+ superuser.save();
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ public void testCreateUser() throws RepositoryException {
+ // EXERCISE: use the following parameters (with suitable values) to
create a new user.
+ // EXERCISE: play with the values. what are valid values? which params
can be null? what is the effect?
+ String userID = null;
+ String password = null;
+ Principal principal = null;
+ String intermediatePath = null;
+
+ // EXERCISE: use both methods to create a new user. what's the effect?
+ testUser = userManager.createUser(userID, password, principal,
intermediatePath);
+ //testUser = userManager.createUser(userID password);
+
+ superuser.save();
+ }
+
+ public void testCreateGroup() throws RepositoryException {
+ // EXERCISE: use the following parameters (with suitable values) to
create a new group.
+ // EXERCISE: play with the values. what are valid values? which params
can be null? what is the effect?
+ String groupID = null;
+ Principal principal = null;
+ String intermediatePath = null;
+
+ // EXERCISE: use both methods to create a new group. what's the effect?
+ testGroup = userManager.createGroup(groupID, principal,
intermediatePath);
+// testGroup = userManager.createGroup(groupID);
+// testGroup = userManager.createGroup(principal);
+// testGroup = userManager.createGroup(principal, intermediatePath);
+
+ superuser.save();
+ }
+
+ public void testGetAuthorizable() throws RepositoryException {
+ testUser = userManager.createUser("testUser", null, new
PrincipalImpl("testPrincipal"), null);
+ testGroup = userManager.createGroup("testGroup", new
PrincipalImpl("testGroupPrincipal"), null);
+ superuser.save();
+
+ // EXERCISE: use all methods provided on UserManager interface to
retrieve a given user/group.
+ // - lookup by id
+ // - lookup by path
+ // - lookup by principal
+ // - lookup by id + class
+ }
+}
\ No newline at end of file
Propchange:
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/user/L2_CreateAndGetTest.java
------------------------------------------------------------------------------
svn:eol-style = native