Author: angela
Date: Fri Nov  2 09:54:25 2012
New Revision: 1404905

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

Added:
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestLoginModule.java
Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/DefaultSyncHandler.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalUser.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncMode.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/AbstractSecurityTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java?rev=1404905&r1=1404904&r2=1404905&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java
 Fri Nov  2 09:54:25 2012
@@ -55,6 +55,10 @@ public class ConfigurationParameters {
     //--------------------------------------------------------< private >---
     @SuppressWarnings("unchecked")
     private static <T> T convert(Object configProperty, T defaultValue) {
+        if (configProperty == null) {
+            return defaultValue;
+        }
+
         T value;
         String str = configProperty.toString();
         Class targetClass = (defaultValue == null) ? configProperty.getClass() 
: defaultValue.getClass();

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/DefaultSyncHandler.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/DefaultSyncHandler.java?rev=1404905&r1=1404904&r2=1404905&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/DefaultSyncHandler.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/DefaultSyncHandler.java
 Fri Nov  2 09:54:25 2012
@@ -21,9 +21,11 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.CheckForNull;
+import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
 
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.Group;
@@ -109,7 +111,7 @@ public class DefaultSyncHandler implemen
     @CheckForNull
     private User createUser(ExternalUser externalUser) throws 
RepositoryException, SyncException {
         if (mode.contains(SyncMode.MODE_CREATE_USER)) {
-            User user = userManager.createUser(externalUser.getId(), null, 
externalUser.getPrincipal(), externalUser.getPath());
+            User user = userManager.createUser(externalUser.getId(), 
externalUser.getPassword(), externalUser.getPrincipal(), 
externalUser.getPath());
             syncAuthorizable(externalUser, user);
             return user;
         } else {
@@ -157,24 +159,46 @@ public class DefaultSyncHandler implemen
             Object prop = properties.get(key);
             if (prop instanceof Collection) {
                 Value[] values = createValues((Collection) prop);
-                authorizable.setProperty(key, values);
+                if (values != null) {
+                    authorizable.setProperty(key, values);
+                }
             } else {
                 Value value = createValue(prop);
-                authorizable.setProperty(key, value);
+                if (value != null) {
+                    authorizable.setProperty(key, value);
+                }
             }
         }
     }
 
-    private Value createValue(Object propValue) {
-        // TODO
-        return null;
+    @CheckForNull
+    private Value createValue(Object propValue) throws ValueFormatException {
+        int type = getType(propValue);
+        if (type == PropertyType.UNDEFINED) {
+            return null;
+        } else {
+            return valueFactory.createValue(propValue.toString(), type);
+        }
     }
 
-    private Value[] createValues(Collection<?> propValues) {
+    @CheckForNull
+    private Value[] createValues(Collection<?> propValues) throws 
ValueFormatException {
         List<Value> values = new ArrayList<Value>();
         for (Object obj : propValues) {
-            values.add(createValue(obj));
+            Value v = createValue(obj);
+            if (v != null) {
+                values.add(v);
+            }
         }
         return values.toArray(new Value[values.size()]);
     }
+
+    private static int getType(Object propValue) {
+        // TODO: add proper type detection
+        if (propValue == null) {
+            return PropertyType.UNDEFINED;
+        } else {
+            return PropertyType.STRING;
+        }
+    }
 }
\ No newline at end of file

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java?rev=1404905&r1=1404904&r2=1404905&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java
 Fri Nov  2 09:54:25 2012
@@ -24,7 +24,6 @@ import javax.security.auth.login.LoginEx
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.Root;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.AbstractLoginModule;
-import org.apache.jackrabbit.util.Text;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,19 +65,22 @@ public abstract class ExternalLoginModul
      * @throws SyncException
      */
     protected SyncHandler getSyncHandler() throws SyncException {
-        String shClass = options.getConfigValue(PARAM_SYNC_HANDLER, 
DEFAULT_SYNC_HANDLER);
-        Object syncHandler;
-        try {
-            // FIXME this will create problems within OSGi environment
-            syncHandler = Class.forName(shClass).newInstance();
-        } catch (Exception e) {
-            throw new SyncException("Error while getting SyncHandler:", e);
-        }
-
-        if (syncHandler instanceof SyncHandler) {
+        Object syncHandler = options.getConfigValue(PARAM_SYNC_HANDLER, null);
+        if (syncHandler == null) {
+            return new DefaultSyncHandler();
+        } else if (syncHandler instanceof SyncHandler) {
             return (SyncHandler) syncHandler;
         } else {
-            throw new SyncException("Invalid SyncHandler class configured: " + 
syncHandler.getClass().getName());
+            try {
+                Object sh = 
Class.forName(syncHandler.toString()).newInstance();
+                if (sh instanceof SyncHandler) {
+                    return (SyncHandler) sh;
+                } else {
+                    throw new SyncException("Invalid SyncHandler 
configuration: " + sh);
+                }
+            } catch (Exception e) {
+                throw new SyncException("Error while getting SyncHandler:", e);
+            }
         }
     }
 
@@ -115,12 +117,12 @@ public abstract class ExternalLoginModul
         try {
             SyncHandler handler = getSyncHandler();
             Root root = getRoot();
-            String smValue = options.getConfigValue(PARAM_SYNC_MODE, null);
+            Object smValue = options.getConfigValue(PARAM_SYNC_MODE, null);
             SyncMode syncMode;
             if (smValue == null) {
                 syncMode = DEFAULT_SYNC_MODE;
             } else {
-                syncMode = SyncMode.fromStrings(Text.explode(smValue, ',', 
false));
+                syncMode = SyncMode.fromObject(smValue);
             }
             if (handler.initialize(getUserManager(), root, syncMode, options)) 
{
                 handler.sync(getExternalUser());

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalUser.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalUser.java?rev=1404905&r1=1404904&r2=1404905&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalUser.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalUser.java
 Fri Nov  2 09:54:25 2012
@@ -27,6 +27,8 @@ public interface ExternalUser {
 
     String getId();
 
+    String getPassword();
+
     Principal getPrincipal();
 
     String getPath();

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncMode.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncMode.java?rev=1404905&r1=1404904&r2=1404905&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncMode.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncMode.java
 Fri Nov  2 09:54:25 2012
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authentication.external;
 
+import org.apache.jackrabbit.util.Text;
+
 /**
  * SyncMode... TODO: define sync-modes
  */
@@ -26,8 +28,9 @@ public class SyncMode {
     public static final int MODE_CREATE_GROUPS = 2;
     public static final int MODE_UPDATE = 4;
 
-    public static final String CREATE_USER_NAME = "createUser";
-    public static final String CREATE_GROUP_NAME = "createGroup";
+    public static final String NO_SYNC = "";
+    public static final String CREATE_USER = "createUser";
+    public static final String CREATE_GROUP = "createGroup";
     public static final String UPDATE = "update";
 
     public static final SyncMode DEFAULT_SYNC = new 
SyncMode(MODE_CREATE_USER|MODE_CREATE_GROUPS|MODE_UPDATE);
@@ -42,15 +45,27 @@ public class SyncMode {
         return (this.mode & mode) == mode;
     }
 
+    public static SyncMode fromObject(Object smValue) {
+        if (smValue instanceof SyncMode) {
+            return (SyncMode) smValue;
+        } else if (smValue instanceof String[]) {
+            return fromStrings((String[]) smValue);
+        } else {
+            return fromStrings(Text.explode(smValue.toString(), ',', false));
+        }
+    }
+
     public static SyncMode fromString(String name) {
         int mode;
-        if (CREATE_USER_NAME.equals(name)) {
+        if (CREATE_USER.equals(name)) {
             mode = MODE_CREATE_USER;
-        } else if (CREATE_GROUP_NAME.equals(name)) {
+        } else if (CREATE_GROUP.equals(name)) {
             mode = MODE_CREATE_GROUPS;
         } else if (UPDATE.equals(name)) {
             mode = MODE_UPDATE;
-        } else {
+        } else if (name.isEmpty()) {
+            mode = MODE_NO_SYNC;
+        }else {
             throw new IllegalArgumentException("invalid sync mode name " + 
name);
         }
         return fromInt(mode);

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/AbstractSecurityTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/AbstractSecurityTest.java?rev=1404905&r1=1404904&r2=1404905&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/AbstractSecurityTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/AbstractSecurityTest.java
 Fri Nov  2 09:54:25 2012
@@ -66,6 +66,7 @@ public abstract class AbstractSecurityTe
         }
         return securityProvider;
     }
+
     protected Configuration getConfiguration() {
         return new OakConfiguration();
     }

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java?rev=1404905&r1=1404904&r2=1404905&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java
 Fri Nov  2 09:54:25 2012
@@ -103,6 +103,16 @@ public class ConfigurationParametersTest
         assertEquals("1000", options.getConfigValue("Int3", "1000"));
     }
 
+    @Test
+    public void testNullValue() {
+        ConfigurationParameters options = new 
ConfigurationParameters(Collections.singletonMap("test", null));
+
+        assertNull(options.getConfigValue("test", null));
+        assertEquals("value", options.getConfigValue("test", "value"));
+        TestObject testObject = new TestObject("t");
+        assertEquals(testObject, options.getConfigValue("test", testObject));
+    }
+
 
 
     private class TestObject {

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java?rev=1404905&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
 Fri Nov  2 09:54:25 2012
@@ -0,0 +1,306 @@
+/*
+ * 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.external;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+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.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.security.AbstractSecurityTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * ExternalLoginModuleTest...
+ */
+public class ExternalLoginModuleTest extends AbstractSecurityTest {
+
+    private final HashMap<String, Object> options = new HashMap<String, 
Object>();
+
+    private String userId;
+    private Set<String> ids = new HashSet<String>();
+
+    private UserManager userManager;
+
+    private Root root;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        userId = TestLoginModule.externalUser.getId();
+        ids.add(userId);
+        for (ExternalGroup group : TestLoginModule.externalGroups) {
+            ids.add(group.getId());
+        }
+
+        root = admin.getLatestRoot();
+        userManager = 
securityProvider.getUserConfiguration().getUserManager(root, 
NamePathMapper.DEFAULT);
+    }
+
+    @After
+    public void after() throws Exception {
+        try {
+            for (String id : ids) {
+                Authorizable a = userManager.getAuthorizable(id);
+                if (a != null) {
+                    a.remove();
+                }
+            }
+            root.commit();
+        } finally {
+            root.refresh();
+            super.after();
+        }
+    }
+
+
+
+    @Test
+    public void testLoginFailed() throws Exception {
+       try {
+           ContentSession cs = login(new SimpleCredentials("unknown", new 
char[0]));
+           cs.close();
+           fail("login failure expected");
+       } catch (LoginException e) {
+           // success
+       } finally {
+           assertNull(userManager.getAuthorizable(userId));
+       }
+    }
+
+    @Test
+    public void testSyncCreateUser() throws Exception {
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, SyncMode.CREATE_USER);
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+            for (String id : ids) {
+                if (id.equals(userId)) {
+                    Authorizable a = userManager.getAuthorizable(id);
+                    assertNotNull(a);
+                    for (String prop : 
TestLoginModule.externalUser.getProperties().keySet()) {
+                        assertTrue(a.hasProperty(prop));
+                    }
+                } else {
+                    assertNull(userManager.getAuthorizable(id));
+                }
+            }
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testSyncCreateGroup() throws Exception {
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, 
SyncMode.CREATE_GROUP);
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+            for (String id : ids) {
+                assertNull(userManager.getAuthorizable(id));
+            }
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testSyncCreateUserAndGroups() throws Exception {
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, new String[] 
{SyncMode.CREATE_USER,SyncMode.CREATE_GROUP});
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+            for (String id : ids) {
+                if (id.equals(userId)) {
+                    Authorizable a = userManager.getAuthorizable(id);
+                    assertNotNull(a);
+                    for (String prop : 
TestLoginModule.externalUser.getProperties().keySet()) {
+                        assertTrue(a.hasProperty(prop));
+                    }
+                } else {
+                    assertNotNull(userManager.getAuthorizable(id));
+                }
+            }
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testSyncUpdate() throws Exception {
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, SyncMode.UPDATE);
+
+        // create user upfront in order to test update mode
+        ExternalUser externalUser = TestLoginModule.externalUser;
+        Authorizable user = userManager.createUser(externalUser.getId(), 
externalUser.getPassword());
+        root.commit();
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+            for (String id : ids) {
+                if (id.equals(userId)) {
+                    Authorizable a = userManager.getAuthorizable(id);
+                    assertNotNull(a);
+                    for (String prop : 
TestLoginModule.externalUser.getProperties().keySet()) {
+                        assertTrue(a.hasProperty(prop));
+                    }
+                } else {
+                    assertNull(userManager.getAuthorizable(id));
+                }
+            }
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testSyncUpdateAndGroups() throws Exception {
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, new String[] 
{SyncMode.UPDATE, SyncMode.CREATE_GROUP});
+
+        // create user upfront in order to test update mode
+        ExternalUser externalUser = TestLoginModule.externalUser;
+        Authorizable user = userManager.createUser(externalUser.getId(), 
externalUser.getPassword());
+        root.commit();
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+            for (String id : ids) {
+                if (id.equals(userId)) {
+                    Authorizable a = userManager.getAuthorizable(id);
+                    assertNotNull(a);
+                    for (String prop : 
TestLoginModule.externalUser.getProperties().keySet()) {
+                        assertTrue(a.hasProperty(prop));
+                    }
+                } else {
+                    assertNotNull(userManager.getAuthorizable(id));
+                }
+            }
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testDefaultSync() throws Exception {
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, null);
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+            for (String id : ids) {
+                if (id.equals(userId)) {
+                    Authorizable a = userManager.getAuthorizable(id);
+                    assertNotNull(a);
+                    for (String prop : 
TestLoginModule.externalUser.getProperties().keySet()) {
+                        assertTrue(a.hasProperty(prop));
+                    }
+                } else {
+                    assertNotNull(userManager.getAuthorizable(id));
+                }
+            }
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testNoSync() throws Exception {
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, "");
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+            for (String id : ids) {
+                assertNull(userManager.getAuthorizable(id));
+            }
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    protected Configuration getConfiguration() {
+        return new Configuration() {
+            @Override
+            public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+                AppConfigurationEntry entry = new AppConfigurationEntry(
+                        TestLoginModule.class.getName(),
+                        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                        options);
+                return new AppConfigurationEntry[] {entry};
+            }
+        };
+    }
+
+
+
+}
\ No newline at end of file

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestLoginModule.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestLoginModule.java?rev=1404905&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestLoginModule.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestLoginModule.java
 Fri Nov  2 09:54:25 2012
@@ -0,0 +1,145 @@
+/*
+ * 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.external;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.jcr.Credentials;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.login.LoginException;
+
+/**
+ * ExternalLoginModuleImpl... TODO
+ */
+public class TestLoginModule extends ExternalLoginModule {
+
+    static Set<ExternalGroup> externalGroups = new HashSet<ExternalGroup>();
+    static {
+        externalGroups.add(new TestGroup("a", new String[] {"aa", "aaa"}));
+        externalGroups.add(new TestGroup("b", new String[] {"a"}));
+        externalGroups.add(new TestGroup("c", new String[0]));
+    }
+
+    static Map<String,Object> props = new HashMap<String, Object>();
+    static {
+        props.put("name", "Test User");
+        props.put("profile/name", "Public Name");
+        props.put("profile/age", 72);
+        props.put("./email", "t...@testuser.com");
+    }
+    static ExternalUser externalUser = new TestUser("testUser", 
externalGroups, props);
+
+    boolean success;
+
+    @Override
+    protected boolean loginSucceeded() {
+        return success;
+    }
+
+    @Override
+    protected ExternalUser getExternalUser() {
+        return externalUser;
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        Credentials creds = getCredentials();
+        if (creds instanceof SimpleCredentials) {
+            if (externalUser.getId().equals(((SimpleCredentials) 
creds).getUserID())) {
+                success = true;
+                return success;
+            } else {
+                throw new LoginException("Invalid user");
+            }
+        } else {
+            return false;
+        }
+    }
+
+    
//--------------------------------------------------------------------------
+
+    private static class TestUser implements ExternalUser {
+
+        private final String userId;
+        private final Set<ExternalGroup> groups;
+        private final Map props;
+
+        private TestUser(String userId, Set<ExternalGroup> groups, Map<String, 
Object> props) {
+            this.userId = userId;
+            this.groups = groups;
+            this.props = props;
+        }
+
+        @Override
+        public String getId() {
+            return userId;
+        }
+
+        @Override
+        public String getPassword() {
+            return null;
+        }
+
+        @Override
+        public Principal getPrincipal() {
+            return new Principal() {
+                @Override
+                public String getName() {
+                    return userId;
+                }
+            };
+        }
+
+        @Override
+        public String getPath() {
+            return null;
+        }
+
+        @Override
+        public Set<ExternalGroup> getGroups() {
+            return groups;
+        }
+
+        @Override
+        public Map<String, ?> getProperties() {
+            return props;
+        }
+    }
+
+    private static class TestGroup extends TestUser implements ExternalGroup {
+
+        private final String[] groupNames;
+
+        private TestGroup(String id, String[] groupNames) {
+            super(id, Collections.<ExternalGroup>emptySet(), 
Collections.<String, Object>emptyMap());
+            this.groupNames = groupNames;
+        }
+
+        @Override
+        public Set<ExternalGroup> getGroups() {
+            Set<ExternalGroup> groups = new HashSet<ExternalGroup>();
+            for (String gn : groupNames) {
+                groups.add(new TestGroup(gn, new String[0]));
+            }
+            return groups;
+        }
+    }
+}
\ No newline at end of file


Reply via email to