Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L5_GuestLoginTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L5_GuestLoginTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L5_GuestLoginTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L5_GuestLoginTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,151 @@
+/*
+ * 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.authentication;
+
+import javax.jcr.GuestCredentials;
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: Guest Login (aka Anonymous Login)
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand how to login as guest, the meaning of the {@link 
javax.jcr.GuestCredentials}
+ * and how this is linked to the 'anonymous' user.
+ *
+ * Exercises:
+ *
+ * - {@link #testAnonymousGuestLogin()}
+ *   Walk through the anonymous login {@link #testAnonymousGuestLogin()}
+ *   Question: Can you identify ares in the default authentication setup that 
apply special handling for anonymous?
+ *
+ * - {@link #testAnonymousSimpleCredentialsLogin()}
+ *   Try to login as anonymous with SimpleCredentials
+ *   Question: Why can't you login as anonymous with {@link 
javax.jcr.SimpleCredentials}?
+ *
+ * - {@link #testAnonymousSimpleCredentialsLoginSuccess}
+ *   In order to understand what makes the guest-login special compared to a
+ *   regular user-login, modify the test-case such that a regular login with
+ *   SimpleCredentials succeeds.
+ *
+ * - {@link #testDisableGuestLogin()}
+ *   Use this test to prevent anonymous access in an existing/running oak 
repository.
+ *   Modify the test such that it success. How many variants do you find?
+ *
+ *
+ * Additional Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * - Run a Sling (Granite|Cq) application and identify how the Sling 
Authentication
+ *   deals with guest login.
+ *   Question: What is the Sling way to disable anonymous (guest) access?
+ *
+ *
+ * Related Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * - {@link L6_AnonymousIdTest ()}
+ * - {@link 
org.apache.jackrabbit.oak.security.user.L15_RepositoryWithoutAnonymousTest ()}
+ * - {@link L9_NullLoginTest ()}
+ *
+ * </pre>
+ *
+ * @see javax.jcr.GuestCredentials
+ * @see org.apache.jackrabbit.api.security.user.User#getCredentials()
+ * @see org.apache.jackrabbit.api.security.user.User#changePassword(String, 
String)
+ * @see org.apache.jackrabbit.api.security.user.User#disable(String)
+ */
+public class L5_GuestLoginTest extends AbstractJCRTest {
+
+    private Repository repository;
+    private Session testSession;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        repository = getHelper().getRepository();
+        superuser.save();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            if (testSession != null && testSession.isLive()) {
+                testSession.logout();
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testAnonymousGuestLogin() throws RepositoryException {
+        testSession = repository.login(new GuestCredentials());
+    }
+
+    public void testAnonymousSimpleCredentialsLogin() throws 
RepositoryException {
+        testSession = repository.login(new GuestCredentials());
+
+        String anonymousID = testSession.getUserID();
+        testSession.logout();
+
+        try {
+            testSession = repository.login(new SimpleCredentials(anonymousID, 
new char[0]));
+            fail("Anonymous cannot login with simple credentials.");
+        } catch (LoginException e) {
+            // success
+            // EXERCISE: explain why
+        }
+    }
+
+    public void testAnonymousSimpleCredentialsLoginSuccess() throws 
RepositoryException {
+        testSession = repository.login(new GuestCredentials());
+
+        String anonymousID = testSession.getUserID();
+
+        // EXERCISE: how to you need to modify the test-case that this would 
work?
+
+        Session anonymousUserSession = repository.login(new 
SimpleCredentials(anonymousID, new char[0]));
+        assertEquals(UserConstants.DEFAULT_ANONYMOUS_ID, 
testSession.getUserID());
+    }
+
+    public void testDisableGuestLogin() throws RepositoryException {
+
+        // EXERCISE : identify ways to prevent anonymous login with 
GuestCredentials in an existing repository
+        //            extend the test here such that the login below fails
+        // 1:
+        // 2:
+
+        try {
+            testSession = repository.login(new GuestCredentials());
+            fail("Anonymous login must fail.");
+        } catch (LoginException e) {
+            // success
+        }
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L5_GuestLoginTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L6_AnonymousIdTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L6_AnonymousIdTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L6_AnonymousIdTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L6_AnonymousIdTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,116 @@
+/*
+ * 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.authentication;
+
+import javax.jcr.GuestCredentials;
+import javax.jcr.RepositoryException;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * <pre>
+ * Module: Authentication | User Management
+ * 
=============================================================================
+ *
+ * Title: Anonymous Id
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand that the ID of the anonymous user in the system is configurable
+ * and thus must not be treated as constant (hardcoding) in an application 
(Sling|Granite|CQ).
+ *
+ * Exercises:
+ *
+ * - {@link #testAnonymousID()}
+ *   Login as anonymous again and test the resulting userID
+ *   Question: What is the expected value of {@link 
javax.jcr.Session#getUserID()}
+ *   upon guest login? Explain why.
+ *
+ * - {@link #testDifferentAnonymousID()}
+ *   Define the configuration settings that will create you an Oak repository 
instance
+ *   that has a different anonymous ID.
+ *
+ *
+ * Additional Exercise
+ * 
-----------------------------------------------------------------------------
+ *
+ * In Adobe Granite exists an Osgi service that allows you to retrive the ID
+ * of the 'anonymous' user without hardcoding.
+ *
+ * - Find the service and test how you can obtain the anonymous ID.
+ *
+ * </pre>
+ *
+ * @see javax.jcr.GuestCredentials
+ */
+public class L6_AnonymousIdTest extends AbstractSecurityTest {
+
+    private ContentSession testSession;
+
+    @Override
+    public void before() throws Exception {
+        super.before();
+    }
+
+    @Override
+    public void after() throws Exception {
+        try {
+            if (testSession != null) {
+                testSession.close();
+            }
+        } finally {
+            super.after();
+        }
+    }
+
+    @Test
+    public void testAnonymousID() throws RepositoryException, LoginException {
+        testSession = login(new GuestCredentials());
+
+        String anonymousID = testSession.getAuthInfo().getUserID();
+
+        // EXERCISE: what value do you expect for 'anonymousID'? explain why. 
is there a solution without hardcoding?
+        String expectedID = null;
+
+        assertEquals(expectedID, anonymousID);
+    }
+
+    // NOTE: chang this test-configuration for testDifferentAnonymousID()
+    @Override
+    protected ConfigurationParameters getSecurityConfigParameters() {
+        // EXERCISE: un-comment for 'testDifferentAnonymousID'
+//        ConfigurationParameters userConfig = 
ConfigurationParameters.of(UserConstants.PARAM_ANONYMOUS_ID, 
"differentAnonymousId");
+//        return ConfigurationParameters.of(UserConfiguration.NAME, 
userConfig);
+        return ConfigurationParameters.EMPTY;
+    }
+
+    @Test
+    public void testDifferentAnonymousID() throws Exception {
+        // EXERCISE : use built-in oak configuration settings to have a 
different anonymous ID -> uncomment the configuration parameters in 
'getSecurityConfigParameters' above
+
+        testSession = login(new GuestCredentials());
+
+        String expectedId = null; // EXERCISE: write the expected ID
+        assertEquals(expectedId, testSession.getAuthInfo().getUserID());
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L6_AnonymousIdTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L7_ImpersonationTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L7_ImpersonationTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L7_ImpersonationTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L7_ImpersonationTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,210 @@
+/*
+ * 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.authentication;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+import javax.jcr.LoginException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Impersonation;
+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;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: Impersonation
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Become familiar with {@link 
javax.jcr.Session#impersonate(javax.jcr.Credentials)}
+ * and how this is implemented in Oak.
+ * Please note that this exercise mixes authentication with user management
+ * functionality.
+ *
+ * Exercises:
+ *
+ *
+ * - {@link #testImpersonateTestUser()}
+ *   This test illustrates how a given session can be allowed to impersonate
+ *   another user. Use this test to walk through the impersonation step by step
+ *   and identify which principal must be granted impersonation in order to
+ *   get the test pass without exception.
+ *
+ *   Question: Can you explain where the impersonation information is being 
stored in the repository?
+ *   Question: Can you explain where the impersonation is being evaluated.
+ *   Question: Why is impersonation being granted to a Principal and not a 
userID?
+ *
+ * - {@link #testImpersonateOneSelf()}
+ *   Walk through {@link Session#impersonate(javax.jcr.Credentials)} in this
+ *   test case and test if the test user can impersonate himself; fix the test
+ *   accordingly.
+ *
+ *   Question: Can you identify the location of the code that makes this 
pass/fail?
+ *   Question: Can you identify how this behavior could be changed by a 
different repository configuration?
+ *
+ * - {@link #testAdminCanImpersonateEveryone()}
+ *   Walk through {@link Session#impersonate(javax.jcr.Credentials)} in this
+ *   test case and explain why the admin user is allowed to impersonate the
+ *   test user although impersonation is not explicitly granted.
+ *
+ *   Question: What kind of security concerns can you identify with this 
shortcut?
+ *             Discuss and explain your findings.
+ *
+ *
+ * Advanced Exercise:
+ * 
-----------------------------------------------------------------------------
+ *
+ * Once you feel familiar with the various security modules (including access
+ * control and user management), you may want to come back to this advanced
+ * exercise that requires an understanding of all areas.
+ *
+ * - Impersonation and pluggable authentication
+ *   Once you feel comfortable with the pluggable nature of the authentication
+ *   module, discuss how replacing the default login module chain will affect
+ *   how {@link Session#impersonate(javax.jcr.Credentials)} works.
+ *
+ *   Question: Can you think of a different mechanism on how to validate if a 
given
+ *             impersonation requestion should succeed?
+ *   Question: What are the classes present with Oak that you need to deal with
+ *             in your custom implementation?
+ *
+ * - {@link #testAdvancedImpersonationTest()}
+ *   This advanced tests mixes all three security areas involved in the 
impersonation:
+ *   1. Authorization: the required permission to write the list of 
impersonators
+ *   2. User Management: API to grant (and revoke) impersonation.
+ *   3. Authentication: The impersonation itself.
+ *
+ * </pre>
+ *
+ * @see javax.jcr.Session#impersonate(javax.jcr.Credentials)
+ * @see org.apache.jackrabbit.api.security.user.Impersonation
+ * @see 
org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials
+ */
+public class L7_ImpersonationTest extends AbstractJCRTest {
+
+    private UserManager userManager;
+
+    private User testUser;
+    private User anotherUser;
+
+    private List<Session> sessionList = new ArrayList<Session>();
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        userManager = ((JackrabbitSession) superuser).getUserManager();
+        testUser = ExerciseUtility.createTestUser(userManager);
+        anotherUser = ExerciseUtility.createTestUser(userManager);
+        superuser.save();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            for (Session s : sessionList) {
+                if (s.isLive()) {
+                    s.logout();
+                }
+            }
+            if (testUser != null) {
+                testUser.remove();
+            }
+            if (anotherUser != null) {
+                anotherUser.remove();
+            }
+            superuser.save();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testImpersonateTestUser() throws RepositoryException {
+        Principal principal = null; // EXERCISE: fill in the correct principal 
such that the test passes.
+
+        Impersonation impersonation = anotherUser.getImpersonation();
+        impersonation.grantImpersonation(principal);
+        superuser.save();
+
+        Session testSession = 
superuser.getRepository().login(ExerciseUtility.getTestCredentials(testUser.getID()));
+        sessionList.add(testSession);
+
+        Session impersonated = testSession.impersonate(new 
SimpleCredentials(anotherUser.getID(), new char[0]));
+        sessionList.add(impersonated);
+
+        assertEquals(anotherUser.getID(), impersonated.getUserID());
+    }
+
+    public void testImpersonateOneSelf() throws RepositoryException {
+        // EXERCISE: walk through this impersonation. does it work? if it 
does: why?
+
+        Session testSession = 
superuser.getRepository().login(ExerciseUtility.getTestCredentials(testUser.getID()));
+        sessionList.add(testSession);
+
+        Session impersonated = testSession.impersonate(new 
SimpleCredentials(testUser.getID(), new char[0]));
+        sessionList.add(impersonated);
+
+        assertEquals(testUser.getID(), impersonated.getUserID());
+    }
+
+    public void testAdminCanImpersonateEveryone() throws RepositoryException {
+        // EXERCISE: walk through this impersonation. does it work? if it 
does: why?
+
+        Session impersonated = superuser.impersonate(new 
SimpleCredentials(anotherUser.getID(), new char[0]));
+        sessionList.add(impersonated);
+
+        assertEquals(anotherUser.getID(), impersonated.getUserID());
+    }
+
+    public void testAdvancedImpersonationTest() throws RepositoryException {
+        // EXERCISE: change the permission setup such that the test-user is 
allowed to make himself an impersonator of 'another' user.
+
+        Session testSession = 
superuser.getRepository().login(ExerciseUtility.getTestCredentials(testUser.getID()));
+        sessionList.add(testSession);
+
+        UserManager uMgr = ((JackrabbitSession) testSession).getUserManager();
+        User another = uMgr.getAuthorizable(anotherUser.getID(), User.class);
+        assertNotNull(another);
+
+        Principal princ = 
uMgr.getAuthorizable(testUser.getID()).getPrincipal();
+        another.getImpersonation().grantImpersonation(princ);
+        testSession.save();
+
+        testSession.impersonate(new SimpleCredentials(anotherUser.getID(), new 
char[0])).logout();
+
+        // EXERCISE: change the impersonation of 'anotherUser' again such that 
the impersonate call fails
+        // EXERCISE: withouth changing the permission setup. what API calls do 
you have at hand?
+
+        try {
+            Session s = testSession.impersonate(new 
SimpleCredentials(anotherUser.getID(), new char[0]));
+            sessionList.add(s);
+            fail("Test user must no longer be able to edit the impersonation 
of the test user");
+        } catch (LoginException e) {
+            // success
+        }
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L7_ImpersonationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L8_PreAuthTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L8_PreAuthTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L8_PreAuthTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L8_PreAuthTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,115 @@
+/*
+ * 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.authentication;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.junit.Test;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: Pre-Authentication with LoginModule Chain
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand how a pre-authentication can be used in combination with the
+ * {@link LoginModule} chain according to the description provided in
+ * 
http://jackrabbit.apache.org/oak/docs/security/authentication/preauthentication.html
+ *
+ * Exercises:
+ *
+ * - {@link #testPreAuthenticatedLogin()}
+ *   Modify the {@link 
org.apache.jackrabbit.oak.security.authentication.CustomLoginModule}
+ *   such that the simplified pre-auth in the test-case passes.
+ *
+ * - With the same setup at hand explain why the {@code CustomCredentials} must
+ *   be package protected. Come up with a vulnerability/exploit if this 
credentials
+ *   implemenation was exposed to the public.
+ *
+ *
+ * Additional Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * In a Sling base repository installation (Granite|CQ) make use of your
+ * understanding of pre-authentication with LoginModule chain involvement
+ * and defined a dedicated bundle that comes with a package that contains the
+ * following classes
+ *
+ * - A Credentials implemenation that is package private and cannot be abused
+ *   outside of the scope of this bundle.
+ * - Sling AuthenticationHandler implementation that performs the pre-auth and
+ *   passes the package private Credentials to the repository login
+ * - LoginModule implementation (that receives the package private Credentials
+ *   and updates the shared state accordingly).
+ *
+ *
+ * Related Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * - {@link L3_LoginModuleTest}
+ * - {@link L9_NullLoginTest}
+ *
+ * </pre>
+ *
+ * @see 
org.apache.jackrabbit.oak.spi.security.authentication.PreAuthenticatedLogin
+ * @see <a 
href="http://jackrabbit.apache.org/oak/docs/security/authentication/preauthentication.html";>Pre-Authentication
 Documentation</a>
+ */
+public class L8_PreAuthTest extends AbstractSecurityTest {
+
+    @Override
+    protected Configuration getConfiguration() {
+        final ConfigurationParameters config = getSecurityConfigParameters();
+        return new Configuration() {
+            @Override
+            public AppConfigurationEntry[] getAppConfigurationEntry(String 
applicationName) {
+                Map<String, ?> options = 
getSecurityConfigParameters().getConfigValue(applicationName, 
Collections.<String, Object>emptyMap());
+                return new AppConfigurationEntry[]{
+                        new 
AppConfigurationEntry(CustomLoginModule.class.getName(), 
AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL, options),
+                        new 
AppConfigurationEntry(LoginModuleImpl.class.getName(), 
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options)};
+            }
+        };
+    }
+
+    @Test
+    public void testPreAuthenticatedLogin() throws IOException, 
LoginException, NoSuchWorkspaceException {
+        // EXERCISE: adjust the CustomLoginModule such that the following test 
passes, the jaas configuration has already been adjusted for you above.
+
+        // login as admin with CustomCredentials and without a password
+        // -> no password verification in the module required as this is 
expected
+        //    to have already happened during the pre-auth setp (which is 
missing here)
+        String loginID = 
getUserConfiguration().getParameters().getConfigValue(UserConstants.DEFAULT_ADMIN_ID,
 UserConstants.DEFAULT_ADMIN_ID);
+        ContentSession contentSession = login(new CustomCredentials(loginID, 
null, Collections.EMPTY_MAP));
+
+        // EXERCISE: add verification of the AuthInfo according to your 
implementation of the custom login module.
+
+        contentSession.close();
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L8_PreAuthTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L9_NullLoginTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L9_NullLoginTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L9_NullLoginTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L9_NullLoginTest.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.authentication;
+
+import java.security.PrivilegedExceptionAction;
+import javax.jcr.GuestCredentials;
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.security.auth.Subject;
+import javax.security.auth.login.Configuration;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: Null Login with PrePopulated Subject (Pre-Authentication without 
LoginModule)
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Understand the meaning and usage of the pre-authenticated login with
+ * {@link javax.jcr.Repository#login()} (i.e. {@code null} credentials).
+ *
+ * Exercises:
+ *
+ * - {@link #testNullLogin()}
+ *   Step through a regular JCR login without credentials and explain why this
+ *   is expected to fail.
+ *
+ * - {@link #testSuccessfulNullLogin()}
+ *   This test-case illustrates a usage of the 'null' login. Complete the test
+ *   by creating/populating a valid {@link Subject} and verify your 
expectations
+ *   after a successful login.
+ *
+ *
+ * Additional Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * In Jackrabbit 2.x the null-credentials login was treated as login of the
+ * anonymous guest user.
+ *
+ * - Use {@link #testJr2CompatibleLoginConfiguration} to configure the
+ *   {@link javax.security.auth.login.LoginContext} such that the repository 
behaves
+ *   like Jackrabbit 2.x and treats {@link javax.jcr.Repository#login()}
+ *   (null-login) as anonymous login.
+ *
+ *
+ * Related Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * - {@link L3_LoginModuleTest}
+ * - {@link L8_PreAuthTest}
+ *
+ * </pre>
+ *
+ * @see <a 
href="http://jackrabbit.apache.org/oak/docs/security/authentication/preauthentication.html";>Pre-Authentication
 Documentation</a>
+ */
+public class L9_NullLoginTest extends AbstractJCRTest {
+
+    private Repository repository;
+    private Session testSession;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        repository = getHelper().getRepository();
+        superuser.save();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            if (testSession != null && testSession.isLive()) {
+                testSession.logout();
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testNullLogin() throws RepositoryException {
+        try {
+            testSession = repository.login();
+            fail();
+        } catch (LoginException e) {
+            // success
+            // EXERCISE: explain what is going on and why it is expected to 
fail.
+        }
+    }
+
+    public void testSuccessfulNullLogin() throws Exception {
+        // EXERCISE: populate a subject that results in successful null-login
+        Subject subject = null;
+        String expectedId = null;
+
+        testSession = Subject.doAs(subject, new 
PrivilegedExceptionAction<Session>() {
+            @Override
+            public Session run() throws RepositoryException {
+                return repository.login(null, null);
+            }
+        });
+
+        assertEquals(expectedId, testSession.getUserID());
+    }
+
+    public void testJr2CompatibleLoginConfiguration() throws 
RepositoryException {
+        // EXERCISE: define the JAAS configuration that allows you to have 
null-login treated as anonymous login.
+        Configuration configuration = null;
+
+        Configuration.setConfiguration(configuration);
+        try {
+            testSession = repository.login();
+
+            Session guest = repository.login(new GuestCredentials());
+            String expectedId = guest.getUserID();
+            guest.logout();
+
+            assertEquals(expectedId, testSession.getUserID());
+        } finally {
+            Configuration.setConfiguration(null);
+        }
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/L9_NullLoginTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/external/L1_IntroductionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/external/L1_IntroductionTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/external/L1_IntroductionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/external/L1_IntroductionTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,49 @@
+/*
+ * 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.authentication.external;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: Introduction
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * TODO
+ *
+ * Exercises:
+ *
+ * - {@link #TODO}
+ *
+ *
+ * Additional Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * TODO
+ *
+ * </pre>
+ *
+ * @see TODO
+ */
+public class L1_IntroductionTest extends AbstractSecurityTest {
+
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/external/L1_IntroductionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L1_IntroductionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L1_IntroductionTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L1_IntroductionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L1_IntroductionTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,49 @@
+/*
+ * 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.authentication.token;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: Introduction
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * TODO
+ *
+ * Exercises:
+ *
+ * - {@link #TODO}
+ *
+ *
+ * Additional Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * TODO
+ *
+ * </pre>
+ *
+ * @see TODO
+ */
+public class L1_IntroductionTest extends AbstractSecurityTest {
+
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L1_IntroductionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L2_TokenLoginTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L2_TokenLoginTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L2_TokenLoginTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L2_TokenLoginTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,49 @@
+/*
+ * 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.authentication.token;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: Token Login
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * TODO
+ *
+ * Exercises:
+ *
+ * - {@link #TODO}
+ *
+ *
+ * Additional Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * TODO
+ *
+ * </pre>
+ *
+ * @see TODO
+ */
+public class L2_TokenLoginTest extends AbstractSecurityTest {
+
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L2_TokenLoginTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L3_TokenProviderTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L3_TokenProviderTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L3_TokenProviderTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L3_TokenProviderTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,49 @@
+/*
+ * 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.authentication.token;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+
+/**
+ * <pre>
+ * Module: Authentication
+ * 
=============================================================================
+ *
+ * Title: TokenProvider
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * TODO
+ *
+ * Exercises:
+ *
+ * - {@link #TODO}
+ *
+ *
+ * Additional Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * TODO
+ *
+ * </pre>
+ *
+ * @see TODO
+ */
+public class L3_TokenProviderTest extends AbstractSecurityTest {
+
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/L3_TokenProviderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/IntroductionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/IntroductionTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/IntroductionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/IntroductionTest.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.authorization;
+
+import javax.jcr.security.AccessControlManager;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+
+/**
+ * <pre>
+ * Module: Authorization
+ * 
=============================================================================
+ *
+ * Title: Introduction to Authorization
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Get a basic understanding how authorization is organized in Oak and become
+ * familiar with distiction between access control management and permission
+ * evaluation.
+ *
+ * Exercises:
+ *
+ * - Read JCR Specification and the Oak Documentation with focus on 
authorization
+ *   and the distiction between access control management and permission
+ *   evaluation.
+ *
+ *   Question: Can you explain the difference between access control 
management and permission evaluation?
+ *
+ * - Overview
+ *   Take a look at the package structure in {@code 
org.apache.jackrabbit.oak.spi.security.authorization}
+ *   and {@code org.apache.jackrabbit.oak.security.authorization} and try to
+ *   become familiar with the interfaces and classes defined therein.
+ *   Look for usages of the key entry points ({@link AccessControlManager} and
+ *   {@link PermissionProvider} and try to get a big picture.
+ *
+ *   Question: Can you identify this distinction when looking at {@link 
AuthorizationConfiguration}?
+ *   Question: What can you say about the usage of {@link 
AccessControlManager} in oak-core and oak-jcr?
+ *   Question: What can you say about the usage of {@link PermissionProvider} 
in oak-core and oak-jcr?
+ *
+ * - Configuration
+ *   Look at the default implementation of the {@link 
AuthorizationConfiguration}
+ *   and try to identify the configurable parts. Compare your results with the
+ *   Oak documentation.
+ *
+ *   Question: Can you provide a separate list for access control management 
and permission options?
+ *   Question: Are the configuration options that affect both parts?
+ *
+ * - Pluggability
+ *   Starting from the {@link AuthorizationConfiguration} again, investigate
+ *   how the default implementation could be replaced.
+ *
+ *   Question: Is it possible to combine different authorization 
implementations?
+ *
+ * </pre>
+ */
+public class IntroductionTest extends AbstractSecurityTest {
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/IntroductionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L1_IntroductionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L1_IntroductionTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L1_IntroductionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L1_IntroductionTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+
+/**
+ * <pre>
+ * Module: Authorization (Access Control Management)
+ * 
=============================================================================
+ *
+ * Title: Introduction to Access Control Management
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Become familiar with the JCR Access Control Management API and the 
extensions
+ * provided by Jackrabbit API. Understand how access control management is
+ * used and exposed in Oak and finally gain insight into some details of the
+ * default implementation.
+ *
+ * Exercises:
+ *
+ * - Overview and Usages of AccessControl Management
+ *   Search for usage of the access control management API (e.g. {@link 
javax.jcr.security.AccessControlManager})
+ *   in Oak _and_ Jackrabbit JCR Commons.
+ *
+ *   Question: Where is the access control manager being used for?
+ *   Question: Who is the expected API consumer?
+ *   Question: What are the characteristics of this areas?
+ *   Question: Can identify areas where oak-jcr and oak-core actually make use 
of the access control management API?
+ *
+ * - Configuration
+ *   Look at the default implementation(s) of the {@link 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration}
+ *   and try to identify the configurable parts with respect to access control.
+ *   Compare your results with the Oak documentation.
+ *
+ *   Question: Can you provide a list of configuration options for access 
control s.str.?
+ *   Question: Can you identify where these configuration options are being 
evaluated?
+ *   Question: Which options also affect the permission evaluation?
+ *
+ * - Pluggability
+ *   Become familar with the pluggable parts of the access control management
+ *
+ *   Question: What means does Oak provide to change or extend the access 
control management?
+ *   Question: Can you identify the interfaces that you needed to implement?
+ *   Question: Would it be possible to only replace the implementation of 
{@link AccessControlManager}?
+ *             How could you achieve this?
+ *             And what would be the consequences for the whole authorization 
module?
+ *
+ *
+ * Advanced Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * See {@link L7_RestrictionsTest}
+ * for some advanced exercises with respect to custom restrictions.
+ *
+ *
+ * Related Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * - {@link L2_AccessControlManagerTest}
+ * - {@link L3_AccessControlListTest}
+ * - {@link L4_EffectivePoliciesTest}
+ * - {@link L7_RestrictionsTest}
+ *
+ * </pre>
+ */
+public class L1_IntroductionTest extends AbstractSecurityTest {
+
+
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L1_IntroductionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L2_AccessControlManagerTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L2_AccessControlManagerTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L2_AccessControlManagerTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L2_AccessControlManagerTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
+
+import java.security.Principal;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import 
org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.plugins.name.NamespaceConstants;
+import org.apache.jackrabbit.oak.security.ExerciseUtility;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * <pre>
+ * Module: Authorization (Access Control Management)
+ * 
=============================================================================
+ *
+ * Title: Access Control Manager and Policies
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Learn about the details of the {@link 
javax.jcr.security.AccessControlManager}
+ * and the differences to {@link 
org.apache.jackrabbit.api.security.JackrabbitAccessControlManager}.
+ * Become familiar with getting, modifying and applying access control 
policies.
+ * Finally you will be able to make use of the access control related utilities
+ * as provided by the jackrabbit-jcr-commons package.
+ *
+ * Exercises:
+ *
+ * - {@link #testGetAccessControlManager()}
+ *   Complete the test by retrieving the regular JCR and the Jackrabbit access
+ *   control manager.
+ *
+ *   Question: What kind of test could/should you perform in order not to risk 
any runtime exceptions
+ *   Question: Does JCR API provide means to avoid {@link 
javax.jcr.UnsupportedRepositoryOperationException}?
+ *
+ * - {@link #testRetrievePoliciesAtTestRoot()}
+ *   Understand the difference between {@code getApplicablePolicies} and 
{@code getPolicies}.
+ *   Fix the test such that it passes.
+ *
+ * - {@link #testRetrievePoliciesAtNamespaceRoot()}
+ *   Same as before for {@link 
org.apache.jackrabbit.oak.plugins.name.NamespaceConstants#NAMESPACES_PATH}.
+ *
+ *   Question: What are the differences?
+ *   Question: Can you explain it?
+ *   Question: What would you need to do in order to get the same result for 
the test root?
+ *
+ * - {@link #testModifyPolicy()}
+ *   This test modifies the access control list exposed by the default 
implementation at the test root.
+ *   Fix the test such that it passes.
+ *
+ *   Question: What is the expected return value of {@code 
getApplicablePolicies} and {@code getPolicies}
+ *             after modifying the ACL?
+ *   Question: What is the nature of the ACE created by the test case? Deny? 
Allow? Why?
+ *
+ * - {@link #testAddAceWithUtility()}
+ *   Similar to {@link #testModifyPolicy()} this test modifies the policy at 
the
+ *   test root however using the one variant of the utility methods provided by
+ *   jackrabbit-jcr-commons. Fix the test such that it passes.
+ *
+ *   Question: Can you summarize the difference to the test above?
+ *   Question: Can you explain the behavior?
+ *
+ * - {@link #testSetPolicy()}
+ *   Same as {@link #testModifyPolicy()}. Fix the test case such that it 
passes.
+ *   Hint: The title of the test indicates the expected fix :-)
+ *
+ * - {@link #testRemovePolicy()}
+ *   Test illustrating how to remove access control policies. Explain why the
+ *   initial call to remove the policy fails.
+ *
+ * - {@link #testTransientNature()}
+ *   Test case illustrating the transient nature of access control 
modifications.
+ *   Fix the test case such that it passes.
+ *
+ * - {@link #testRetrievePoliciesAsReadOnlySession()}
+ *   This case illustrates the fact the reading access control management 
requires
+ *   additional permissions. Explaing why the read-only session cannot call
+ *   either of the methods to retrieve policies at the test root and fix the
+ *   test case accordingly.
+ *
+ *   Question: How many variants to do see to fix the test?
+ *
+ * - {@link #testWritePoliciesAsReadOnlySession()}
+ *   This case illustrates the fact the writing access control content requires
+ *   additional permissions. Explaing why the read-only session cannot set the
+ *   policy at the test root and fix the test case accordingly.
+ *
+ *   Question: How many variants to do see to fix the test?
+ *
+ *
+ * Additional Exercises
+ * 
-----------------------------------------------------------------------------
+ *
+ * While the default implementation currently mostly exposes {@link 
AccessControlList}
+ * policies, the specification defines the nature of access control policies an
+ * implementation detail.
+ *
+ * - {@link testPoliciesAtNullPath()}
+ *   All test above use a regular, absolute path pointing to a Node to read and
+ *   write access control policies.
+ *   As of JSR 283 it is also allowed to use 'null' instead. Use this exercise
+ *   to recap the meaning 'null' in this context by looking at the JCR Javadoc.
+ *   Fix the test by providing the correct set of privileges that can be 
granted here.
+ *
+ *   Question: What privileges can only be granted/revoked at the 'null' path?
+ *   Question: Can you extend the test to verify your expectations?
+ *
+ * - Look for other implementations of the {@link 
javax.jcr.security.AccessControlPolicy}
+ *   interface in Oak and list your findings.
+ *
+ *   Question: Can you find other policies?
+ *   Question: Can you describe the nature of these policies?
+ *   Question: Can you identify the impact this may have on API consumers that 
make assumptions about the type of policies?
+ *
+ * - Take a second look at the {@link 
org.apache.jackrabbit.api.security.JackrabbitAccessControlManager}.
+ *
+ *   Question: What additional methods exist with respect to retrieving access 
control policies?
+ *   Question: Can you explain how to use these methods?
+ *   Question: Explore how the default implementation handles these calls.
+ *
+ *
+ * Related Exercises
+ * 
-----------------------------------------------------------------------------
+ *
+ * - {@link L3_AccessControlListTest}
+ * - {@link L4_EffectivePoliciesTest}
+ * - {@link L7_RestrictionsTest}
+ *
+ * </pre>
+ *
+ * @see javax.jcr.security.AccessControlManager
+ * @see javax.jcr.security.AccessControlPolicy
+ */
+public class L2_AccessControlManagerTest extends AbstractJCRTest {
+
+    private AccessControlManager acMgr;
+    private Principal testPrincipal;
+    private String testID;
+
+    private Session testSession;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        acMgr = superuser.getAccessControlManager();
+
+        User testUser = ExerciseUtility.createTestUser(((JackrabbitSession) 
superuser).getUserManager());
+        testPrincipal = testUser.getPrincipal();
+        testID = testUser.getID();
+        superuser.save();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            if (testSession != null && testSession.isLive()) {
+                testSession.logout();
+            }
+
+            Authorizable testUser = ((JackrabbitSession) 
superuser).getUserManager().getAuthorizable(testPrincipal);
+            if (testUser != null) {
+                testUser.remove();
+                superuser.save();
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testGetAccessControlManager() throws RepositoryException {
+
+        // EXERCISE retrieve the access control manager using standard JCR API
+        AccessControlManager acMgr = null;
+        assertNotNull(acMgr);
+
+        // EXERCISE retrieve the jackrabbit access control manager using 
standard API, without risking a class-cast exception.
+        JackrabbitAccessControlManager jackrabbitAcMgr = null;
+        assertNotNull(jackrabbitAcMgr);
+    }
+
+    public void testRetrievePoliciesAtTestRoot() throws RepositoryException {
+        AccessControlPolicy[] policies = acMgr.getPolicies(testRoot);
+        int expectedLength = -1; // EXERCISE
+        assertEquals(expectedLength, policies.length);
+
+
+        AccessControlPolicyIterator policyIterator = 
acMgr.getApplicablePolicies(testRoot);
+        int expectedSize = -1; // EXERCISE
+        assertEquals(expectedSize, policyIterator.getSize());
+
+        // EXERCISE: look at the utility methods and explain the expected 
return value
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, testRoot);
+        JackrabbitAccessControlList acl2 = 
AccessControlUtils.getAccessControlList(superuser, testRoot);
+        assertEquals(acl, acl2); // EXERCISE: is this correct?
+    }
+
+    public void testRetrievePoliciesAtNamespaceRoot() throws 
RepositoryException {
+        AccessControlPolicy[] policies = 
acMgr.getPolicies(NamespaceConstants.NAMESPACES_PATH);
+        int expectedLength = -1; // EXERCISE
+        assertEquals(expectedLength, policies.length);
+
+
+        AccessControlPolicyIterator policyIterator = 
acMgr.getApplicablePolicies(NamespaceConstants.NAMESPACES_PATH);
+        int expectedSize = -1; // EXERCISE
+        assertEquals(expectedSize, policyIterator.getSize());
+
+        // EXERCISE: look at the utility methods and explain the expected 
return value
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, 
NamespaceConstants.NAMESPACES_PATH);
+        JackrabbitAccessControlList acl2 = 
AccessControlUtils.getAccessControlList(superuser, 
NamespaceConstants.NAMESPACES_PATH);
+        assertEquals(acl, acl2); // EXERCISE: is this correct?
+    }
+
+    public void testModifyPolicy() throws RepositoryException {
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, testRoot);
+
+        assertNotNull(acl);
+        assertEquals(0, acl.getAccessControlEntries().length);
+
+        acl.addAccessControlEntry(EveryonePrincipal.getInstance(), new 
Privilege[] {acMgr.privilegeFromName(Privilege.JCR_READ)});
+        int expectedLength = -1; // EXERCISE
+        assertEquals(expectedLength, acl.getAccessControlEntries().length);
+
+        int expectedSize = -1; // EXERCISE
+        assertEquals(expectedSize, 
acMgr.getApplicablePolicies(testRoot).getSize());
+
+        expectedLength = -1; // EXERCISE
+        assertEquals(expectedLength, acMgr.getPolicies(testRoot).length);
+    }
+
+    public void testAddAceWithUtility() throws RepositoryException {
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, testRoot);
+
+        boolean success = AccessControlUtils.addAccessControlEntry(superuser, 
testRoot, testPrincipal, new String[] {Privilege.JCR_READ}, false);
+        boolean expectedSuccess = false; // EXERCISE
+        assertEquals(expectedSuccess, success);
+
+        int expectedLength = -1; // EXERCISE
+        assertEquals(expectedLength, acl.getAccessControlEntries().length);
+
+        int expectedSize = -1; // EXERCISE
+        assertEquals(expectedSize, 
acMgr.getApplicablePolicies(testRoot).getSize());
+
+        AccessControlPolicy[] policies = acMgr.getPolicies(testRoot);
+        expectedLength = -1; // EXERCISE
+        assertEquals(expectedLength, policies.length);
+
+        acl = null;
+        for (AccessControlPolicy policy : policies) {
+            if (policy instanceof JackrabbitAccessControlList) {
+                acl = (JackrabbitAccessControlList) policy;
+            }
+        }
+        JackrabbitAccessControlList acl2 = 
AccessControlUtils.getAccessControlList(acMgr, testRoot);
+
+        // EXERCISE: is the following expected to succeed?
+        assertEquals(acl, acl2);
+
+        int expectedAceLength = -1; // EXERCISE
+        assertEquals(expectedAceLength, acl.getAccessControlEntries().length);
+    }
+
+    public void testSetPolicy() throws RepositoryException {
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, testRoot);
+
+        assertTrue(acl.addEntry(testPrincipal, 
AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_READ), false));
+
+        // EXERCISE: fix the test.
+
+        assertFalse(acMgr.getApplicablePolicies(testRoot).hasNext());
+
+        AccessControlPolicy[] policies = acMgr.getPolicies(testRoot);
+        assertEquals(1, policies.length);
+        assertTrue(policies[0] instanceof JackrabbitAccessControlList);
+
+        JackrabbitAccessControlList acl2 = (JackrabbitAccessControlList) 
policies[0];
+
+        assertFalse(acl2.isEmpty());
+        assertEquals(1, acl2.size());
+        AccessControlEntry ace = acl2.getAccessControlEntries()[0];
+
+        assertTrue(ace instanceof JackrabbitAccessControlEntry);
+        assertEquals(testPrincipal, ace.getPrincipal());
+        assertFalse(((JackrabbitAccessControlEntry) ace).isAllow());
+    }
+
+    public void testRemovePolicy() throws RepositoryException {
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, testRoot);
+
+        // EXERCISE: explain why
+        try {
+            acMgr.removePolicy(testRoot, acl);
+            fail("EXERCISE");
+        } catch (AccessControlException e) {
+            // success
+        }
+
+        AccessControlUtils.addAccessControlEntry(superuser, testRoot, 
testPrincipal, new String[] {Privilege.JCR_READ}, false);
+
+        acl = AccessControlUtils.getAccessControlList(acMgr, testRoot);
+        acMgr.removePolicy(testRoot, acl);
+    }
+
+    public void testTransientNature() throws RepositoryException {
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, testRoot);
+        assertTrue(acl.addEntry(testPrincipal, 
AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_READ), false));
+        acMgr.setPolicy(testRoot, acl);
+
+        assertEquals(acl, AccessControlUtils.getAccessControlList(acMgr, 
testRoot));
+
+        // EXERCISE: fix the test case
+
+        Session s = getHelper().getSuperuserSession();
+        try {
+            AccessControlPolicy[] policies = 
s.getAccessControlManager().getPolicies(testRoot);
+            assertEquals(1, policies.length);
+            assertEquals(acl, policies[0]);
+        } finally {
+            if (s.isLive()) {
+                s.logout();
+            }
+        }
+    }
+
+    public void testRetrievePoliciesAsReadOnlySession() throws 
RepositoryException {
+        testSession = 
superuser.getRepository().login(ExerciseUtility.getTestCredentials(testID));
+
+        // EXERCISE: Fix the test and explain your fix.
+        AccessControlPolicyIterator policyIterator = 
testSession.getAccessControlManager().getApplicablePolicies(testRoot);
+        AccessControlPolicy[] policies = 
testSession.getAccessControlManager().getPolicies(testRoot);
+    }
+
+    public void testWritePoliciesAsReadOnlySession() throws 
RepositoryException {
+        testSession = 
superuser.getRepository().login(ExerciseUtility.getTestCredentials(testID));
+
+        // EXERCISE: Fix the test and explain your fix.
+        // NOTE: that obviously is prone to cause troubles as the policies is 
retrieved with a different session!
+        AccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, 
testRoot);
+
+        testSession.getAccessControlManager().setPolicy(testRoot, acl);
+    }
+
+    public void testPoliciesAtNullPath() throws RepositoryException {
+        String testPath = null;
+        Privilege[] privileges = null; // EXERCISE define the set of privs 
that can/must be granted at the 'null' path.
+
+        AccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, 
testPath);
+        acl.addAccessControlEntry(testPrincipal, privileges);
+        acMgr.setPolicy(testPath, acl);
+
+        superuser.save();
+
+        // EXERCISE explain (or even verify) the expected result
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L2_AccessControlManagerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L3_AccessControlListTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L3_AccessControlListTest.java?rev=1686235&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L3_AccessControlListTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L3_AccessControlListTest.java
 Thu Jun 18 14:30:16 2015
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
+
+import java.security.Principal;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import 
org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.security.ExerciseUtility;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+/**
+ * <pre>
+ * Module: Authorization (Access Control Management)
+ * 
=============================================================================
+ *
+ * Title: Access Control List in Detail
+ * 
-----------------------------------------------------------------------------
+ *
+ * Goal:
+ * Learn to use additional ways to modify an JCR or Jackrabbit ACL.
+ *
+ * Exercises:
+ *
+ * - {@link #testEmptyList()}
+ *   Get familiar with the concept of an empty ACL and what methods the 
Jackrabbit
+ *   API extensions provides. Fix the test case.
+ *
+ *   Question: Can you set an empty ACL?
+ *   Question: If that works, what is the nature of the ACL if you retrieve it 
using AccessControlManager#getPolicies()?
+ *
+ * - {@link #testAddEntries()}
+ *   Use this test to play with the different ways of adding one (or multiple) 
ACE
+ *   to the list. Verify your expectations and keep an eye on the size of the 
ACL.
+ *
+ * - {@link #testRemoveEntries()}
+ *   Remove one ACE that has been added to the policy before and verify the 
result.
+ *
+ * - {@link #testReorderEntries()}
+ *   Reorder the ACEs created for this test according to the instructions in 
the
+ *   test. Make sure the test passes.
+ *
+ * - {@link #testGetPath()}
+ *   Test illustrating the {@link 
org.apache.jackrabbit.api.security.JackrabbitAccessControlList#getPath()}.
+ *   Fill in the expected path and explain the meaning of the path
+ *
+ *   Question: Can you use the path exposed by the ACL to set the policy? If 
not fix the test accordingly
+ *
+ *
+ * Related Exercises:
+ * 
-----------------------------------------------------------------------------
+ *
+ * - {@link L5_AccessControlListImplTest}
+ * - {@link L7_RestrictionsTest}
+ * - {@link 
org.apache.jackrabbit.oak.security.privilege.L3_BuiltInPrivilegesTest}
+ * - {@link 
org.apache.jackrabbit.oak.security.authorization.permission.L4_PrivilegesAndPermissionsTest}
+ *
+ *
+ * </pre>
+ *
+ * @see javax.jcr.security.AccessControlList
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlList
+ * @see javax.jcr.security.AccessControlEntry
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry
+ */
+public class L3_AccessControlListTest extends AbstractJCRTest {
+
+    private AccessControlManager acMgr;
+    private JackrabbitAccessControlList acl;
+    private Principal testPrincipal;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        acMgr = superuser.getAccessControlManager();
+
+        testPrincipal = ExerciseUtility.createTestGroup(((JackrabbitSession) 
superuser).getUserManager()).getPrincipal();
+        superuser.save();
+
+        acl = AccessControlUtils.getAccessControlList(superuser, testRoot);
+        if (acl == null) {
+            throw new NotExecutableException();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            Authorizable testGroup = ((JackrabbitSession) 
superuser).getUserManager().getAuthorizable(testPrincipal);
+            if (testGroup != null) {
+                testGroup.remove();
+                superuser.save();
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testEmptyList() throws RepositoryException {
+        AccessControlEntry[] entries = acl.getAccessControlEntries();
+        int expectedLength = -1; // EXERCISE
+        assertEquals(expectedLength, entries.length);
+
+        int expectedSize = -1; // EXERCISE
+        assertEquals(expectedSize, acl.size());
+
+        boolean expectedIsEmpty = false; // EXERCISE
+        assertEquals(expectedIsEmpty, acl.isEmpty());
+
+        // EXERCISE: can you set an empty ACL? if not fix the test accordingly.
+        acMgr.setPolicy(testRoot, acl);
+
+        // EXERCISE: retrieve the policy with acMgr.getPolicies(). what will 
the ACL look like?
+    }
+
+    public void testAddEntries() throws RepositoryException {
+        Privilege[] privileges1 = 
AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_READ, 
Privilege.JCR_WRITE);
+        Privilege[] privileges2 = 
AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_ALL);
+
+        Principal principal1 = testPrincipal;
+        Principal principal2 = EveryonePrincipal.getInstance();
+
+        // EXERCISE : make use of the different variants provided by JCR and 
Jackrabbit API to set ACEs to the list.
+        // EXERCISE : verify the expected result and test the size/nature of 
the ACL afterwards
+        // HINT the test AccessControlListImpl test will make you familiar 
with some implementation details
+    }
+
+    public void testRemoveEntry() throws RepositoryException {
+        assertTrue(AccessControlUtils.addAccessControlEntry(superuser, 
testRoot, testPrincipal, new String[]{Privilege.JCR_READ}, true));
+        assertTrue(AccessControlUtils.addAccessControlEntry(superuser, 
testRoot, EveryonePrincipal.getInstance(), new String[]{Privilege.JCR_READ}, 
false));
+
+        // EXERCISE remove the Everyone-ACE from the list and verify that the 
list still contains the entry for testPrincipal.
+
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(superuser, testRoot);
+        assertNotNull(acl);
+        assertEquals(1, acl.size());
+    }
+
+    public void testReorderEntries() throws Exception {
+        Privilege[] read = AccessControlUtils.privilegesFromNames(acMgr, 
Privilege.JCR_READ, Privilege.JCR_READ_ACCESS_CONTROL);
+        Privilege[] write = AccessControlUtils.privilegesFromNames(acMgr, 
Privilege.JCR_WRITE);
+
+        acl.addAccessControlEntry(testPrincipal, read);
+        acl.addEntry(testPrincipal, write, false);
+        acl.addAccessControlEntry(EveryonePrincipal.getInstance(), write);
+
+        AccessControlEntry[] entries = acl.getAccessControlEntries();
+
+        assertEquals(3, entries.length);
+        AccessControlEntry first = entries[0];
+        AccessControlEntry second = entries[1];
+        AccessControlEntry third = entries[2];
+
+        // EXERCISE: reorder 'second' to the first position
+
+        entries = acl.getAccessControlEntries();
+        assertEquals(second, entries[0]);
+        assertEquals(first, entries[1]);
+        assertEquals(third, entries[2]);
+
+        // EXERCISE reorder 'third' before 'first'
+
+        entries = acl.getAccessControlEntries();
+        assertEquals(second, entries[0]);
+        assertEquals(third, entries[1]);
+        assertEquals(first, entries[2]);
+
+        // EXERCISE reorder 'second' to the end of the list
+
+        entries = acl.getAccessControlEntries();
+        assertEquals(third, entries[0]);
+        assertEquals(first, entries[1]);
+        assertEquals(second, entries[2]);
+    }
+
+    public void testGetPath() throws RepositoryException {
+        String expectedPath = null; // EXERCISE
+        assertEquals(expectedPath, acl.getPath());
+
+        // EXERCISE: does that the following code work? why? if not fix the 
code
+        acMgr.setPolicy(acl.getPath(), acl);
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-exercise/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/L3_AccessControlListTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to