You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2012/10/17 15:37:06 UTC

svn commit: r1399245 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/security/ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ o...

Author: angela
Date: Wed Oct 17 13:37:05 2012
New Revision: 1399245

URL: http://svn.apache.org/viewvc?rev=1399245&view=rev
Log:
 OAK-91 - Implement Authentication Support (WIP)

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/GuestDefaultLoginModuleTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/TokenLoginModuleTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModuleTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerTest.java
      - copied, changed from r1398877, jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerImplTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeRegistrationTest.java
      - copied, changed from r1398877, jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/CustomPrivilegeTest.java
Removed:
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/CustomPrivilegeTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerImplTest.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/OpenSecurityProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractOakTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java Wed Oct 17 13:37:05 2012
@@ -55,6 +55,9 @@ public class SecurityProviderImpl implem
     public static final String PARAM_APP_NAME = "org.apache.jackrabbit.oak.auth.appName";
     private static final String DEFAULT_APP_NAME = "jackrabbit.oak";
 
+    public static final String PARAM_USER_OPTIONS = "org.apache.jackrabbit.oak.user.options";
+    public static final String PARAM_TOKEN_OPTIONS = "org.apache.jackrabbit.oak.token.options";
+
     private final ConfigurationParameters configuration;
 
     public SecurityProviderImpl() {
@@ -87,7 +90,8 @@ public class SecurityProviderImpl implem
 
     @Nonnull
     @Override
-    public TokenProvider getTokenProvider(Root root, ConfigurationParameters options) {
+    public TokenProvider getTokenProvider(Root root) {
+        ConfigurationParameters options = configuration.getConfigValue(PARAM_TOKEN_OPTIONS, new ConfigurationParameters());
         return new TokenProviderImpl(root, options, getUserConfiguration());
     }
 
@@ -106,7 +110,8 @@ public class SecurityProviderImpl implem
     @Nonnull
     @Override
     public UserConfiguration getUserConfiguration() {
-        return new UserConfigurationImpl();
+        ConfigurationParameters options = configuration.getConfigValue(PARAM_USER_OPTIONS, new ConfigurationParameters());
+        return new UserConfigurationImpl(options);
     }
 
     @Nonnull

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenAuthentication.java Wed Oct 17 13:37:05 2012
@@ -54,6 +54,8 @@ class TokenAuthentication implements Aut
             TokenCredentials tc = (TokenCredentials) credentials;
             if (!validateCredentials(tc)) {
                 throw new LoginException("Invalid token credentials.");
+            } else {
+                return true;
             }
         }
         // no tokenProvider or other credentials implementation -> not handled here.

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenLoginModule.java Wed Oct 17 13:37:05 2012
@@ -142,7 +142,7 @@ public final class TokenLoginModule exte
         SecurityProvider securityProvider = getSecurityProvider();
         Root root = getRoot();
         if (root != null && securityProvider != null) {
-            provider = securityProvider.getTokenProvider(root, options);
+            provider = securityProvider.getTokenProvider(root);
         }
         if (provider == null && callbackHandler != null) {
             try {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java Wed Oct 17 13:37:05 2012
@@ -27,7 +27,6 @@ import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.Map;
-
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.jcr.Credentials;
@@ -43,17 +42,17 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
 import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenInfo;
 import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider;
-import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtility;
 import org.apache.jackrabbit.oak.spi.security.user.AuthorizableType;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
+import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtility;
 import org.apache.jackrabbit.oak.util.NodeUtil;
 import org.apache.jackrabbit.util.ISO8601;
 import org.apache.jackrabbit.util.Text;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.jackrabbit.oak.api.Type.*;
+import static org.apache.jackrabbit.oak.api.Type.STRING;
 
 /**
  * Default implementation of the {@code TokenProvider} interface with the
@@ -82,7 +81,7 @@ public class TokenProviderImpl implement
      * Constant for the token attribute passed with simple credentials to
      * trigger the generation of a new token.
      */
-    private static final String TOKEN_ATTRIBUTE = ".token";
+    public static final String TOKEN_ATTRIBUTE = ".token";
 
     private static final String TOKEN_ATTRIBUTE_EXPIRY = TOKEN_ATTRIBUTE + ".exp";
     private static final String TOKEN_ATTRIBUTE_KEY = TOKEN_ATTRIBUTE + ".key";
@@ -124,55 +123,69 @@ public class TokenProviderImpl implement
     @Override
     public TokenInfo createToken(Credentials credentials) {
         SimpleCredentials sc = extractSimpleCredentials(credentials);
+        TokenInfo tokenInfo = null;
         if (sc != null) {
-            String userId = sc.getUserID();
-            try {
-                Tree userTree = userProvider.getAuthorizable(userId, AuthorizableType.USER);
-                if (userTree != null) {
-                    NodeUtil userNode = new NodeUtil(userTree);
-                    NodeUtil tokenParent = userNode.getChild(TOKENS_NODE_NAME);
-                    if (tokenParent == null) {
-                        tokenParent = userNode.addChild(TOKENS_NODE_NAME, TOKENS_NT_NAME);
-                    }
+            String[] attrNames = sc.getAttributeNames();
+            Map<String, String> attributes = new HashMap<String, String>(attrNames.length);
+            for (String attrName : sc.getAttributeNames()) {
+                attributes.put(attrName, sc.getAttribute(attrName).toString());
+            }
+            tokenInfo = createToken(sc.getUserID(), attributes);
+            if (tokenInfo != null) {
+                // also set the new token to the simple credentials.
+                sc.setAttribute(TOKEN_ATTRIBUTE, tokenInfo.getToken());
+            }
+        }
 
-                    long creationTime = new Date().getTime();
-                    Calendar creation = GregorianCalendar.getInstance();
-                    creation.setTimeInMillis(creationTime);
-                    String tokenName = Text.replace(ISO8601.format(creation), ":", ".");
-
-                    NodeUtil tokenNode = tokenParent.addChild(tokenName, TOKENS_NT_NAME);
-
-                    String key = generateKey(8);
-                    String token = new StringBuilder(tokenNode.getTree().getPath()).append(DELIM).append(key).toString();
-
-                    String tokenHash = PasswordUtility.buildPasswordHash(key);
-                    tokenNode.setString(TOKEN_ATTRIBUTE_KEY, tokenHash);
-                    final long expirationTime = creationTime + tokenExpiration;
-                    tokenNode.setDate(TOKEN_ATTRIBUTE_EXPIRY, expirationTime);
+        return tokenInfo;
+    }
 
-                    Map<String, String> attributes;
-                    for (String name : sc.getAttributeNames()) {
-                        if (!TOKEN_ATTRIBUTE.equals(name)) {
-                            String attr = sc.getAttribute(name).toString();
-                            tokenNode.setString(name, attr);
-                        }
-                    }
-                    root.commit();
+    @Override
+    public TokenInfo createToken(String userId, Map<String, ?> attributes) {
+        try {
+            Tree userTree = userProvider.getAuthorizable(userId, AuthorizableType.USER);
+            if (userTree != null) {
+                NodeUtil userNode = new NodeUtil(userTree);
+                NodeUtil tokenParent = userNode.getChild(TOKENS_NODE_NAME);
+                if (tokenParent == null) {
+                    tokenParent = userNode.addChild(TOKENS_NODE_NAME, TOKENS_NT_NAME);
+                }
 
-                    // also set the new token to the simple credentials.
-                    sc.setAttribute(TOKEN_ATTRIBUTE, token);
-                    return new TokenInfoImpl(tokenNode, token, userId);
-                } else {
-                    log.debug("Cannot create login token: No corresponding node for User " + userId + '.');
+                long creationTime = new Date().getTime();
+                Calendar creation = GregorianCalendar.getInstance();
+                creation.setTimeInMillis(creationTime);
+                String tokenName = Text.replace(ISO8601.format(creation), ":", ".");
+
+                NodeUtil tokenNode = tokenParent.addChild(tokenName, TOKENS_NT_NAME);
+
+                String key = generateKey(8);
+                String token = new StringBuilder(tokenNode.getTree().getPath()).append(DELIM).append(key).toString();
+
+                String tokenHash = PasswordUtility.buildPasswordHash(token);
+                tokenNode.setString(TOKEN_ATTRIBUTE_KEY, tokenHash);
+                final long expirationTime = creationTime + tokenExpiration;
+                tokenNode.setDate(TOKEN_ATTRIBUTE_EXPIRY, expirationTime);
+
+                for (String name : attributes.keySet()) {
+                    if (!TOKEN_ATTRIBUTE.equals(name)) {
+                        String attr = attributes.get(name).toString();
+                        tokenNode.setString(name, attr);
+                    }
                 }
+                root.commit();
 
-            } catch (NoSuchAlgorithmException e) {
-                log.debug("Failed to create login token ", e.getMessage());
-            } catch (UnsupportedEncodingException e) {
-                log.debug("Failed to create login token ", e.getMessage());
-            } catch (CommitFailedException e) {
-                log.debug("Failed to create login token ", e.getMessage());
+
+                return new TokenInfoImpl(tokenNode, token, userId);
+            } else {
+                log.debug("Cannot create login token: No corresponding node for User " + userId + '.');
             }
+
+        } catch (NoSuchAlgorithmException e) {
+            log.debug("Failed to create login token ", e.getMessage());
+        } catch (UnsupportedEncodingException e) {
+            log.debug("Failed to create login token ", e.getMessage());
+        } catch (CommitFailedException e) {
+            log.debug("Failed to create login token ", e.getMessage());
         }
 
         return null;
@@ -212,7 +225,7 @@ public class TokenProviderImpl implement
         Tree tokenTree = getTokenTree(tokenInfo);
         if (tokenTree != null) {
             NodeUtil tokenNode = new NodeUtil(tokenTree);
-            long expTime = tokenNode.getLong(TOKEN_ATTRIBUTE_EXPIRY, 0);
+            long expTime = getExpirationTime(tokenNode, 0);
             if (expTime - loginTime <= tokenExpiration/2) {
                 long expirationTime = loginTime + tokenExpiration;
                 try {
@@ -230,6 +243,15 @@ public class TokenProviderImpl implement
 
 
     //--------------------------------------------------------------------------
+    // TODO: that should be done by the property state or some utility
+    private static long getExpirationTime(NodeUtil tokenNode, long defaultValue) {
+        String date = tokenNode.getString(TOKEN_ATTRIBUTE_EXPIRY, null);
+        if (date == null) {
+            return defaultValue;
+        } else {
+            return ISO8601.parse(date).getTimeInMillis();
+        }
+    }
 
     @CheckForNull
     private static SimpleCredentials extractSimpleCredentials(Credentials credentials) {
@@ -293,7 +315,9 @@ public class TokenProviderImpl implement
     }
 
     //--------------------------------------------------------------------------
-
+    /**
+     * TokenInfo
+     */
     private static class TokenInfoImpl implements TokenInfo {
 
         private final String token;
@@ -312,7 +336,7 @@ public class TokenProviderImpl implement
             this.tokenPath = tokenNode.getTree().getPath();
             this.userId = userId;
 
-            expirationTime = tokenNode.getLong(TOKEN_ATTRIBUTE_EXPIRY, Long.MIN_VALUE);
+            expirationTime = getExpirationTime(tokenNode, Long.MIN_VALUE);
             key = tokenNode.getString(TOKEN_ATTRIBUTE_KEY, null);
 
             mandatoryAttributes = new HashMap<String, String>();
@@ -320,6 +344,9 @@ public class TokenProviderImpl implement
             for (PropertyState propertyState : tokenNode.getTree().getProperties()) {
                 String name = propertyState.getName();
                 String value = propertyState.getValue(STRING);
+                if (TOKEN_ATTRIBUTE_KEY.equals(name) || TOKEN_ATTRIBUTE_EXPIRY.equals(name)) {
+                    continue;
+                }
                 if (isMandatoryAttribute(name)) {
                     mandatoryAttributes.put(name, value);
                 } else if (isInfoAttribute(name)) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/OpenSecurityProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/OpenSecurityProvider.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/OpenSecurityProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/OpenSecurityProvider.java Wed Oct 17 13:37:05 2012
@@ -42,7 +42,7 @@ public class OpenSecurityProvider implem
 
     @Nonnull
     @Override
-    public TokenProvider getTokenProvider(Root root, org.apache.jackrabbit.oak.spi.security.ConfigurationParameters options) {
+    public TokenProvider getTokenProvider(Root root) {
         throw new UnsupportedOperationException();
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityProvider.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityProvider.java Wed Oct 17 13:37:05 2012
@@ -36,7 +36,7 @@ public interface SecurityProvider {
     LoginContextProvider getLoginContextProvider(NodeStore nodeStore);
 
     @Nonnull
-    TokenProvider getTokenProvider(Root root, ConfigurationParameters options);
+    TokenProvider getTokenProvider(Root root);
 
     @Nonnull
     AccessControlProvider getAccessControlProvider();

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModule.java Wed Oct 17 13:37:05 2012
@@ -115,11 +115,15 @@ public final class GuestLoginModule impl
 
     @Override
     public boolean commit() {
-        if (guestCredentials != null && !subject.isReadOnly()) {
-            subject.getPublicCredentials().add(guestCredentials);
-            subject.getPrincipals().add(EveryonePrincipal.getInstance());
+        if (authenticationSucceeded()) {
+            if (!subject.isReadOnly()) {
+                subject.getPublicCredentials().add(guestCredentials);
+                subject.getPrincipals().add(EveryonePrincipal.getInstance());
+            }
+            return true;
+        } else {
+            return false;
         }
-        return true;
     }
 
     @Override
@@ -130,7 +134,10 @@ public final class GuestLoginModule impl
 
     @Override
     public boolean logout() {
-        // nothing to do.
-        return true;
+        return authenticationSucceeded();
+    }
+
+    private boolean authenticationSucceeded() {
+        return guestCredentials != null;
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/TokenProvider.java Wed Oct 17 13:37:05 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authentication.token;
 
+import java.util.Map;
 import javax.annotation.CheckForNull;
 import javax.jcr.Credentials;
 
@@ -40,6 +41,9 @@ public interface TokenProvider {
     TokenInfo createToken(Credentials credentials);
 
     @CheckForNull
+    TokenInfo createToken(String userId, Map<String,?> attributes);
+
+    @CheckForNull
     TokenInfo getTokenInfo(String token);
 
     boolean removeToken(TokenInfo tokenInfo);

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractOakTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractOakTest.java?rev=1399245&r1=1399244&r2=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractOakTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractOakTest.java Wed Oct 17 13:37:05 2012
@@ -71,7 +71,7 @@ public abstract class AbstractOakTest {
         return getContentRepository().login(getAdminCredentials(), null);
     }
 
-    private Credentials getAdminCredentials() {
+    protected Credentials getAdminCredentials() {
         // TODO retrieve from config
         return new SimpleCredentials("admin", "admin".toCharArray());
     }

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java?rev=1399245&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/DefaultLoginModuleTest.java Wed Oct 17 13:37:05 2012
@@ -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.authentication;
+
+import java.util.Collections;
+import javax.jcr.GuestCredentials;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.oak.AbstractOakTest;
+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.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.security.SecurityProviderImpl;
+import org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
+import org.apache.jackrabbit.oak.spi.security.user.util.UserUtility;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+/**
+ * LoginTest...
+ */
+public class DefaultLoginModuleTest extends AbstractOakTest {
+
+    SecurityProvider securityProvider = new SecurityProviderImpl();
+
+    ContentSession admin;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        admin = createAdminSession();
+        Configuration.setConfiguration(new DefaultConfiguration());
+    }
+
+    @After
+    public void after() throws Exception {
+        Configuration.setConfiguration(null);
+        admin.close();
+    }
+
+    @Override
+    protected ContentRepository createRepository() {
+        return new Oak(createMicroKernelWithInitialContent()).with(securityProvider).createContentRepository();
+    }
+
+    @Test
+    public void testNullLogin() throws Exception {
+        ContentSession cs = null;
+        try {
+            cs = getContentRepository().login(null, null);
+            fail("Null login should fail");
+        } catch (LoginException e) {
+            // success
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
+    @Test
+    public void testGuestLogin() throws Exception {
+        ContentSession cs = getContentRepository().login(new GuestCredentials(), null);
+        try {
+            AuthInfo authInfo = cs.getAuthInfo();
+            String anonymousID = UserUtility.getAnonymousId(securityProvider.getUserConfiguration().getConfigurationParameters());
+            assertEquals(anonymousID, authInfo.getUserID());
+        } finally {
+            cs.close();
+        }
+    }
+
+    @Test
+    public void testAnonymousLogin() throws Exception {
+        String anonymousID = UserUtility.getAnonymousId(securityProvider.getUserConfiguration().getConfigurationParameters());
+
+        UserProvider up = securityProvider.getUserConfiguration().getUserProvider(admin.getLatestRoot());
+
+        // verify initial user-content looks like expected
+        Tree anonymous = up.getAuthorizable(anonymousID);
+        assertNotNull(anonymous);
+        assertNull(up.getPasswordHash(anonymous));
+
+        ContentSession cs = null;
+        try {
+            cs = getContentRepository().login(new SimpleCredentials(anonymousID, new char[0]), null);
+            fail("Login with anonymousID should fail since the initial setup doesn't provide a password.");
+        } catch (LoginException e) {
+            // success
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
+    @Test
+    public void testUserLogin() throws Exception {
+        String anonymousID = UserUtility.getAnonymousId(securityProvider.getUserConfiguration().getConfigurationParameters());
+
+        Root root = admin.getLatestRoot();
+        UserProvider up = securityProvider.getUserConfiguration().getUserProvider(root);
+
+        ContentSession cs = null;
+        try {
+            Tree userTree = up.createUser("test", null);
+            up.setPassword(userTree, "pw", true);
+            up.setPrincipalName(userTree, "test");
+            root.commit();
+
+            cs = getContentRepository().login(new SimpleCredentials("test", "pw".toCharArray()), null);
+            AuthInfo authInfo = cs.getAuthInfo();
+            assertEquals("test", authInfo.getUserID());
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            up.getAuthorizable("test").remove();
+            root.commit();
+        }
+    }
+
+    private class DefaultConfiguration extends Configuration {
+
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+            AppConfigurationEntry defaultEntry = new AppConfigurationEntry(
+                    LoginModuleImpl.class.getName(),
+                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                    Collections.<String, Object>emptyMap());
+
+            return new AppConfigurationEntry[] {defaultEntry};
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/GuestDefaultLoginModuleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/GuestDefaultLoginModuleTest.java?rev=1399245&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/GuestDefaultLoginModuleTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/GuestDefaultLoginModuleTest.java Wed Oct 17 13:37:05 2012
@@ -0,0 +1,104 @@
+/*
+ * 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.util.Collections;
+import javax.jcr.GuestCredentials;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+
+import org.apache.jackrabbit.oak.AbstractOakTest;
+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.security.SecurityProviderImpl;
+import org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.GuestLoginModule;
+import org.apache.jackrabbit.oak.spi.security.user.util.UserUtility;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * LoginTest...
+ */
+public class GuestDefaultLoginModuleTest extends AbstractOakTest {
+
+    SecurityProvider securityProvider = new SecurityProviderImpl();
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+        Configuration.setConfiguration(new GuestDefaultConfiguration());
+    }
+
+    @After
+    public void after() throws Exception {
+        Configuration.setConfiguration(null);
+    }
+
+    @Override
+    protected ContentRepository createRepository() {
+        return new Oak(createMicroKernelWithInitialContent()).with(securityProvider).createContentRepository();
+    }
+
+    @Test
+    public void testNullLogin() throws Exception {
+        ContentSession cs = getContentRepository().login(null, null);
+        try {
+            AuthInfo authInfo = cs.getAuthInfo();
+            String anonymousID = UserUtility.getAnonymousId(securityProvider.getUserConfiguration().getConfigurationParameters());
+            assertEquals(anonymousID, authInfo.getUserID());
+        } finally {
+            cs.close();
+        }
+    }
+
+    @Test
+    public void testGuestLogin() throws Exception {
+        ContentSession cs = getContentRepository().login(new GuestCredentials(), null);
+        try {
+            AuthInfo authInfo = cs.getAuthInfo();
+            String anonymousID = UserUtility.getAnonymousId(securityProvider.getUserConfiguration().getConfigurationParameters());
+            assertEquals(anonymousID, authInfo.getUserID());
+        } finally {
+            cs.close();
+        }
+    }
+
+    private class GuestDefaultConfiguration extends Configuration {
+
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+            AppConfigurationEntry guestEntry = new AppConfigurationEntry(
+                    GuestLoginModule.class.getName(),
+                    AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL,
+                    Collections.<String, Object>emptyMap());
+
+            AppConfigurationEntry defaultEntry = new AppConfigurationEntry(
+                    LoginModuleImpl.class.getName(),
+                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                    Collections.<String, Object>emptyMap());
+
+            return new AppConfigurationEntry[] {guestEntry, defaultEntry};
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/TokenLoginModuleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/TokenLoginModuleTest.java?rev=1399245&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/TokenLoginModuleTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/TokenLoginModuleTest.java Wed Oct 17 13:37:05 2012
@@ -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.authentication;
+
+import java.util.Collections;
+import javax.jcr.GuestCredentials;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.api.security.authentication.token.TokenCredentials;
+import org.apache.jackrabbit.oak.AbstractOakTest;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.security.SecurityProviderImpl;
+import org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule;
+import org.apache.jackrabbit.oak.security.authentication.token.TokenProviderImpl;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenInfo;
+import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * LoginTest...
+ */
+public class TokenLoginModuleTest extends AbstractOakTest {
+
+    SecurityProvider securityProvider = new SecurityProviderImpl();
+    ContentSession admin;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        admin = createAdminSession();
+        Configuration.setConfiguration(new TokenConfiguration());
+    }
+
+    @After
+    public void after() throws Exception {
+        Configuration.setConfiguration(null);
+        admin.close();
+    }
+
+    @Override
+    protected ContentRepository createRepository() {
+        return new Oak(createMicroKernelWithInitialContent()).with(securityProvider).createContentRepository();
+    }
+
+    @Test
+    public void testNullLogin() throws Exception {
+        ContentSession cs = null;
+        try {
+            cs = getContentRepository().login(null, null);
+            fail("Null login should fail");
+        } catch (LoginException e) {
+            // success
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
+    @Test
+    public void testGuestLogin() throws Exception {
+        ContentSession cs = null;
+        try {
+            cs = getContentRepository().login(new GuestCredentials(), null);
+            fail("GuestCredentials login should fail");
+        } catch (LoginException e) {
+            // success
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
+    @Test
+    public void testSimpleCredentialsWithAttribute() throws Exception {
+        ContentSession cs = null;
+        try {
+            SimpleCredentials sc = new SimpleCredentials("test", new char[0]);
+            sc.setAttribute(TokenProviderImpl.TOKEN_ATTRIBUTE, "");
+
+            cs = getContentRepository().login(sc, null);
+            fail("Unsupported credentials login should fail");
+        } catch (LoginException e) {
+            // success
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
+    @Test
+    public void testInvalidTokenCredentials() throws Exception {
+        ContentSession cs = null;
+        try {
+            cs = getContentRepository().login(new TokenCredentials("invalid"), null);
+            fail("Invalid token credentials login should fail");
+        } catch (LoginException e) {
+            // success
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+        }
+    }
+
+    @Test
+    public void testValidTokenCredentials() throws Exception {
+        Root root = admin.getLatestRoot();
+        TokenProvider tp = securityProvider.getTokenProvider(root);
+
+        SimpleCredentials sc = (SimpleCredentials) getAdminCredentials();
+        TokenInfo info = tp.createToken(sc.getUserID(), Collections.<String, Object>emptyMap());
+
+        ContentSession cs = getContentRepository().login(new TokenCredentials(info.getToken()), null);
+        try {
+            assertEquals(sc.getUserID(), cs.getAuthInfo().getUserID());
+        } finally {
+            cs.close();
+        }
+
+    }
+
+    private class TokenConfiguration extends Configuration {
+
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+            AppConfigurationEntry defaultEntry = new AppConfigurationEntry(
+                    TokenLoginModule.class.getName(),
+                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                    Collections.<String, Object>emptyMap());
+
+            return new AppConfigurationEntry[] {defaultEntry};
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java?rev=1399245&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImplTest.java Wed Oct 17 13:37:05 2012
@@ -0,0 +1,63 @@
+/*
+ * 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.AbstractOakTest;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.junit.Test;
+
+/**
+ * TokenProviderImplTest...
+ */
+public class TokenProviderImplTest extends AbstractOakTest {
+
+    @Override
+    protected ContentRepository createRepository() {
+        // TODO
+        return null;
+    }
+
+    @Test
+    public void testDoCreateToken() throws Exception {
+        // TODO
+    }
+
+    @Test
+    public void testCreateTokenFromCredentials() throws Exception {
+        // TODO
+    }
+
+    @Test
+    public void testCreateTokenFromUserId() throws Exception {
+        // TODO
+    }
+
+    @Test
+    public void testGetTokenInfo() throws Exception {
+        // TODO
+    }
+
+    @Test
+    public void testRemoveToken() throws Exception {
+        // TODO
+    }
+
+    @Test
+    public void testResetTokenExpiration() throws Exception {
+        // TODO
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModuleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModuleTest.java?rev=1399245&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModuleTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/GuestLoginModuleTest.java Wed Oct 17 13:37:05 2012
@@ -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.spi.security.authentication;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import javax.jcr.Credentials;
+import javax.jcr.GuestCredentials;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.apache.jackrabbit.oak.spi.security.authentication.callback.CredentialsCallback;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * GuestLoginModuleTest...
+ */
+public class GuestLoginModuleTest {
+
+    private LoginModule guestLoginModule = new GuestLoginModule();
+
+    @Test
+    public void testNullLogin() throws LoginException {
+        Subject subject = new Subject();
+        CallbackHandler cbh = new TestCallbackHandler(null);
+        Map sharedState = new HashMap();
+        guestLoginModule.initialize(subject, cbh, sharedState, Collections.<String, Object>emptyMap());
+
+        assertTrue(guestLoginModule.login());
+        Object sharedCreds = sharedState.get(AbstractLoginModule.SHARED_KEY_CREDENTIALS);
+        assertNotNull(sharedCreds);
+        assertTrue(sharedCreds instanceof GuestCredentials);
+
+        assertTrue(guestLoginModule.commit());
+        assertFalse(subject.getPrincipals(EveryonePrincipal.class).isEmpty());
+        assertFalse(subject.getPublicCredentials(GuestCredentials.class).isEmpty());
+    }
+
+    @Test
+    public void testGuestCredentials() throws LoginException {
+        Subject subject = new Subject();
+        CallbackHandler cbh = new TestCallbackHandler(new GuestCredentials());
+        Map sharedState = new HashMap();
+        guestLoginModule.initialize(subject, cbh, sharedState, Collections.<String, Object>emptyMap());
+
+        assertFalse(guestLoginModule.login());
+        assertFalse(sharedState.containsKey(AbstractLoginModule.SHARED_KEY_CREDENTIALS));
+
+        assertFalse(guestLoginModule.commit());
+        assertTrue(subject.getPrincipals().isEmpty());
+        assertTrue(subject.getPublicCredentials().isEmpty());
+    }
+
+    @Test
+    public void testSimpleCredentials() throws LoginException {
+        Subject subject = new Subject();
+        CallbackHandler cbh = new TestCallbackHandler(new SimpleCredentials("test", new char[0]));
+        Map sharedState = new HashMap();
+        guestLoginModule.initialize(subject, cbh, sharedState, Collections.<String, Object>emptyMap());
+
+        assertFalse(guestLoginModule.login());
+        assertFalse(sharedState.containsKey(AbstractLoginModule.SHARED_KEY_CREDENTIALS));
+
+        assertFalse(guestLoginModule.commit());
+        assertTrue(subject.getPrincipals().isEmpty());
+        assertTrue(subject.getPublicCredentials().isEmpty());
+    }
+
+    //--------------------------------------------------------------------------
+
+    private class TestCallbackHandler implements CallbackHandler {
+
+        private final Credentials creds;
+
+        private TestCallbackHandler(Credentials creds) {
+            this.creds = creds;
+        }
+        @Override
+        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+            for (Callback callback : callbacks) {
+                if (callback instanceof CredentialsCallback) {
+                    ((CredentialsCallback) callback).setCredentials(creds);
+                } else {
+                    throw new UnsupportedCallbackException(callback);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

Copied: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerTest.java (from r1398877, jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerImplTest.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerTest.java?p2=jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerTest.java&p1=jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerImplTest.java&r1=1398877&r2=1399245&rev=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeManagerTest.java Wed Oct 17 13:37:05 2012
@@ -34,7 +34,7 @@ import org.junit.Test;
 /**
  * PrivilegeManagerTest...
  */
-public class PrivilegeManagerImplTest extends AbstractPrivilegeTest {
+public class PrivilegeManagerTest extends AbstractPrivilegeTest {
 
     private PrivilegeManager privilegeManager;
 
@@ -50,6 +50,7 @@ public class PrivilegeManagerImplTest ex
         super.tearDown();
     }
 
+    @Test
     public void testGetRegisteredPrivileges() throws RepositoryException {
         Privilege[] registered = privilegeManager.getRegisteredPrivileges();
         Set<Privilege> set = new HashSet<Privilege>();
@@ -62,7 +63,8 @@ public class PrivilegeManagerImplTest ex
         }
         assertTrue(set.isEmpty());
     }
-    
+
+    @Test
     public void testGetPrivilege() throws RepositoryException {
         for (String privName : NON_AGGR_PRIVILEGES) {
             Privilege p = privilegeManager.getPrivilege(privName);
@@ -75,6 +77,7 @@ public class PrivilegeManagerImplTest ex
         }
     }
 
+    @Test
     public void testJcrAll() throws RepositoryException {
         Privilege all = privilegeManager.getPrivilege(Privilege.JCR_ALL);
         assertPrivilege(all, JCR_ALL, true, false);

Copied: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeRegistrationTest.java (from r1398877, jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/CustomPrivilegeTest.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeRegistrationTest.java?p2=jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeRegistrationTest.java&p1=jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/CustomPrivilegeTest.java&r1=1398877&r2=1399245&rev=1399245&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/CustomPrivilegeTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/privilege/PrivilegeRegistrationTest.java Wed Oct 17 13:37:05 2012
@@ -47,7 +47,7 @@ import org.junit.Test;
  *
  * TODO: more tests for cyclic aggregation
  */
-public class CustomPrivilegeTest extends AbstractPrivilegeTest {
+public class PrivilegeRegistrationTest extends AbstractPrivilegeTest {
 
     private Repository repository;
     private Session session;
@@ -306,6 +306,9 @@ public class CustomPrivilegeTest extends
         }
     }
 
+    /**
+     * @since oak
+     */
     @Test
     public void testRegisterCustomPrivilegesVisibleInContent() throws RepositoryException {
         Workspace workspace = session.getWorkspace();
@@ -329,6 +332,9 @@ public class CustomPrivilegeTest extends
         }
     }
 
+    /**
+     * @since oak
+     */
     @Test
     public void testCustomPrivilegeVisibleToNewSession() throws RepositoryException {
         boolean isAbstract = false;
@@ -347,6 +353,9 @@ public class CustomPrivilegeTest extends
         }
     }
 
+    /**
+     * @since oak
+     */
     @Test
     public void testCustomPrivilegeVisibleAfterRefresh() throws RepositoryException {
         Session s2 = getAdminSession();
@@ -375,6 +384,9 @@ public class CustomPrivilegeTest extends
         }
     }
 
+    /**
+     * @since oak
+     */
     @Test
     public void testRegisterPrivilegeWithPendingChanges() throws RepositoryException {
         try {