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 2013/02/06 16:10:41 UTC

svn commit: r1443002 - in /jackrabbit/oak/trunk/oak-core: ./ src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/ src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ src/test/java/org/apache/jackrabbit/oak/sec...

Author: angela
Date: Wed Feb  6 15:10:41 2013
New Revision: 1443002

URL: http://svn.apache.org/viewvc?rev=1443002&view=rev
Log:
OAK-516: Create LdapLoginModule based on ExternalLoginModule (tests; patch provided by manfred baedke)

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/InternalLdapServer.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginStandaloneTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginTestBase.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginWithRepoLoginTest.java
Modified:
    jackrabbit/oak/trunk/oak-core/pom.xml
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/JndiLdapSearch.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/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java

Modified: jackrabbit/oak/trunk/oak-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/pom.xml?rev=1443002&r1=1443001&r2=1443002&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core/pom.xml Wed Feb  6 15:10:41 2013
@@ -225,5 +225,11 @@
         <version>1.0.1</version>
         <scope>test</scope>
     </dependency>
+    <dependency>
+        <groupId>org.apache.directory.server</groupId>
+        <artifactId>apacheds-server-unit</artifactId>
+        <version>1.5.5</version>
+        <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/JndiLdapSearch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/JndiLdapSearch.java?rev=1443002&r1=1443001&r2=1443002&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/JndiLdapSearch.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/JndiLdapSearch.java Wed Feb  6 15:10:41 2013
@@ -89,11 +89,16 @@ public class JndiLdapSearch implements L
         Map<String, Object> properties = new HashMap<String, Object>();
         Map<String, String> syncMap = user instanceof LdapGroup ?
                 settings.getGroupAttributes() : settings.getUserAttributes();
+        Map<String, String> lcSyncMap = new HashMap<String, String>();
+        for (Map.Entry<String, String> entry : syncMap.entrySet()) {
+            String key = entry.getKey();
+            lcSyncMap.put(key == null? null : key.toLowerCase(), entry.getValue());
+        }
         while (namingEnumeration.hasMore()) {
             Attribute attribute = namingEnumeration.next();
-            String key = attribute.getID();
-            if (syncMap.containsKey(key)) {
-                properties.put(syncMap.get(key), parseAttributeValue(attribute));
+            String key = attribute.getID().toLowerCase();
+            if (lcSyncMap.containsKey(key)) {
+                properties.put(lcSyncMap.get(key), parseAttributeValue(attribute));
             }
         }
         user.setProperties(properties);

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=1443002&r1=1443001&r2=1443002&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 Wed Feb  6 15:10:41 2013
@@ -111,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(), externalUser.getPassword(), externalUser.getPrincipal(), externalUser.getPath());
+            User user = userManager.createUser(externalUser.getId(), externalUser.getPassword(), externalUser.getPrincipal(), null);
             syncAuthorizable(externalUser, user);
             return user;
         } else {
@@ -122,7 +122,7 @@ public class DefaultSyncHandler implemen
     @CheckForNull
     private Group createGroup(ExternalGroup externalGroup) throws RepositoryException, SyncException {
         if (mode.contains(SyncMode.MODE_CREATE_GROUPS)) {
-            Group group = userManager.createGroup(externalGroup.getId(), externalGroup.getPrincipal(), externalGroup.getPath());
+            Group group = userManager.createGroup(externalGroup.getId(), externalGroup.getPrincipal(), null);
             syncAuthorizable(externalGroup, group);
             return group;
         } else {

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/InternalLdapServer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/InternalLdapServer.java?rev=1443002&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/InternalLdapServer.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/InternalLdapServer.java Wed Feb  6 15:10:41 2013
@@ -0,0 +1,102 @@
+/*
+ * 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.ldap;
+
+import java.io.File;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.unit.AbstractServerTest;
+
+class InternalLdapServer extends AbstractServerTest {
+
+    public static final String GROUP_MEMBER_ATTR = "member";
+    public static final String GROUP_CLASS_ATTR = "groupOfNames";
+
+    public static final String ADMIN_PW = "secret";
+
+    public void setUp() throws Exception {
+        super.setUp();
+        doDelete = true;
+    }
+
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Override
+    protected void configureDirectoryService() throws Exception {
+        directoryService.setWorkingDirectory(new File("target", "apacheds"));
+        doDelete(directoryService.getWorkingDirectory());
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public String addUser(String firstName, String lastName, String userId, String password)
+            throws Exception {
+        String cn = firstName + ' ' + lastName;
+        String dn = buildDn(cn, false);
+        StringBuilder entries = new StringBuilder();
+        entries.append("dn: ").append(dn).append('\n')
+                .append("objectClass: inetOrgPerson\n").append("cn: ").append(cn)
+                .append('\n').append("sn: ").append(lastName)
+                .append('\n').append("givenName:").append(firstName)
+                .append('\n').append("uid: ").append(userId)
+                .append('\n').append("userPassword: ").append(password).append("\n\n");
+        injectEntries(entries.toString());
+        return dn;
+    }
+
+    public String addGroup(String name) throws Exception {
+        String dn = buildDn(name, true);
+        StringBuilder entries = new StringBuilder();
+        entries.append("dn: ").append(dn).append('\n').append("objectClass: ")
+                .append(GROUP_CLASS_ATTR).append('\n').append(GROUP_MEMBER_ATTR)
+                .append(":\n").append("cn: ").append(name).append("\n\n");
+        injectEntries(entries.toString());
+        return dn;
+    }
+
+    public void addMember(String groupDN, String memberDN) throws Exception {
+        LdapContext ctxt = getWiredContext();
+        BasicAttributes attrs = new BasicAttributes();
+        attrs.put("member", memberDN);
+        ctxt.modifyAttributes(groupDN, DirContext.ADD_ATTRIBUTE, attrs);
+    }
+
+    public void removeMember(String groupDN, String memberDN) throws Exception {
+        LdapContext ctxt = getWiredContext();
+        BasicAttributes attrs = new BasicAttributes();
+        attrs.put("member", memberDN);
+        ctxt.modifyAttributes(groupDN, DirContext.REMOVE_ATTRIBUTE, attrs);
+    }
+
+    private static String buildDn(String name, boolean isGroup) {
+        StringBuilder dn = new StringBuilder();
+        dn.append(name).append(',');
+        if (isGroup) {
+            dn.append(ServerDNConstants.GROUPS_SYSTEM_DN);
+        } else {
+            dn.append(ServerDNConstants.USERS_SYSTEM_DN);
+        }
+        return dn.toString();
+    }
+}

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginStandaloneTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginStandaloneTest.java?rev=1443002&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginStandaloneTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginStandaloneTest.java Wed Feb  6 15:10:41 2013
@@ -0,0 +1,144 @@
+/*
+ * 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.ldap;
+
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalLoginModule;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncMode;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+@Ignore //ignore for the moment because "mvn test" runs into PermGen memory issues
+public class LdapLoginStandaloneTest extends LdapLoginTestBase {
+
+    @Override
+    protected Configuration getConfiguration() {
+        return new Configuration() {
+            @Override
+            public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+                return new AppConfigurationEntry[]{
+                        new AppConfigurationEntry(
+                                LdapLoginModule.class.getName(),
+                                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                                options)
+                };
+            }
+        };
+    }
+    @Test
+    public void testSyncUpdateAndGroups() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, new String[]{SyncMode.UPDATE, SyncMode.CREATE_GROUP});
+
+        // create user upfront in order to test update mode
+        userManager.createUser(USER_ID, USER_PWD);
+        root.commit();
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(USER_ID, USER_PWD.toCharArray()));
+
+            root.refresh();
+            Authorizable user = userManager.getAuthorizable(USER_ID);
+            assertNotNull(user);
+            assertTrue(user.hasProperty(USER_PROP));
+            Authorizable group = userManager.getAuthorizable(GROUP_DN);
+            assertTrue(group.hasProperty(GROUP_PROP));
+            assertNotNull(group);
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testDefaultSync() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, null);
+
+        // create user upfront in order to test update mode
+        userManager.createUser(USER_ID, USER_PWD);
+        root.commit();
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(USER_ID, USER_PWD.toCharArray()));
+
+            root.refresh();
+            Authorizable user = userManager.getAuthorizable(USER_ID);
+            assertNotNull(user);
+            assertTrue(user.hasProperty(USER_PROP));
+            Authorizable group = userManager.getAuthorizable(GROUP_DN);
+            assertTrue(group.hasProperty(GROUP_PROP));
+            assertNotNull(group);
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testSyncUpdate() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, SyncMode.UPDATE);
+
+        // create user upfront in order to test update mode
+        userManager.createUser(USER_ID, USER_PWD);
+        root.commit();
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(USER_ID, USER_PWD.toCharArray()));
+
+            root.refresh();
+            Authorizable user = userManager.getAuthorizable(USER_ID);
+            assertNotNull(user);
+            assertTrue(user.hasProperty(USER_PROP));
+            assertNull(userManager.getAuthorizable(GROUP_DN));
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+}

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginTestBase.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginTestBase.java?rev=1443002&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginTestBase.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginTestBase.java Wed Feb  6 15:10:41 2013
@@ -0,0 +1,269 @@
+/*
+ * 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.ldap;
+
+import java.util.HashMap;
+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.directory.server.constants.ServerDNConstants;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalLoginModule;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.SyncMode;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+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;
+
+public abstract class LdapLoginTestBase extends AbstractSecurityTest {
+
+    protected static final InternalLdapServer LDAP_SERVER = new InternalLdapServer();
+
+    protected static final String USER_ID = "foobar";
+    protected static final String USER_PWD = "foobar";
+    protected static final String USER_FIRSTNAME = "Foo";
+    protected static final String USER_LASTNAME = "Bar";
+    protected static final String USER_ATTR = "givenName";
+    protected static final String USER_PROP = "profile/name";
+    protected static final String GROUP_PROP = "profile/member";
+    protected static final String GROUP_NAME = "foobargroup";
+
+    protected static String GROUP_DN;
+
+    //initialize LDAP server only once (fast, but might turn out to be not sufficiently flexible in the future)
+    protected static final boolean USE_COMMON_LDAP_FIXTURE = true;
+
+    protected final HashMap<String, Object> options = new HashMap<String, Object>();
+
+    protected UserManager userManager;
+
+    @BeforeClass
+    public static void beforeClass() throws Exception {
+        if (USE_COMMON_LDAP_FIXTURE) {
+            LDAP_SERVER.setUp();
+            createLdapFixture();
+        }
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception {
+        if (USE_COMMON_LDAP_FIXTURE) {
+            LDAP_SERVER.tearDown();
+        }
+    }
+
+    @Override
+    protected Configuration getConfiguration() {
+        return new Configuration() {
+            @Override
+            public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+                return new AppConfigurationEntry[]{
+                        new AppConfigurationEntry(
+                                LdapLoginModule.class.getName(),
+                                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                                options)
+                };
+            }
+        };
+    }
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            LDAP_SERVER.setUp();
+        }
+
+        options.put(LdapSettings.KEY_HOST, "127.0.0.1");
+        options.put(LdapSettings.KEY_PORT, String.valueOf(LDAP_SERVER.getPort()));
+        options.put(LdapSettings.KEY_AUTHDN, ServerDNConstants.ADMIN_SYSTEM_DN);
+        options.put(LdapSettings.KEY_AUTHPW, InternalLdapServer.ADMIN_PW);
+        options.put(LdapSettings.KEY_USERROOT, ServerDNConstants.USERS_SYSTEM_DN);
+        options.put(LdapSettings.KEY_GROUPROOT, ServerDNConstants.GROUPS_SYSTEM_DN);
+        options.put(LdapSettings.KEY_AUTOCREATEUSER + USER_ATTR, USER_PROP);
+        options.put(LdapSettings.KEY_AUTOCREATEGROUP + InternalLdapServer.GROUP_MEMBER_ATTR, GROUP_PROP);
+        options.put(LdapSettings.KEY_GROUPFILTER, "(objectclass=" + InternalLdapServer.GROUP_CLASS_ATTR + ')');
+        options.put(LdapSettings.KEY_GROUPMEMBERSHIPATTRIBUTE, InternalLdapServer.GROUP_MEMBER_ATTR);
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, SyncMode.CREATE_USER);
+
+        userManager = securityProvider.getUserConfiguration().getUserManager(root, NamePathMapper.DEFAULT);
+    }
+
+    @After
+    public void after() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            LDAP_SERVER.tearDown();
+        }
+
+        try {
+            Authorizable a = userManager.getAuthorizable(USER_ID);
+            if (a != null) {
+                a.remove();
+            }
+            if (GROUP_DN != null) {
+                a = userManager.getAuthorizable(GROUP_DN);
+                if (a != null) {
+                    a.remove();
+                }
+            }
+            root.commit();
+        } finally {
+            root.refresh();
+            super.after();
+        }
+    }
+
+    @Test
+    public void testLoginFailed() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        try {
+            ContentSession cs = login(new SimpleCredentials(USER_ID, new char[0]));
+            cs.close();
+            fail("login failure expected");
+        } catch (LoginException e) {
+            // success
+        } finally {
+            assertNull(userManager.getAuthorizable(USER_ID));
+        }
+    }
+
+    @Test
+    public void testSyncCreateUser() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, SyncMode.CREATE_USER);
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(USER_ID, USER_PWD.toCharArray()));
+
+            root.refresh();
+            Authorizable user = userManager.getAuthorizable(USER_ID);
+            assertNotNull(user);
+            assertTrue(user.hasProperty(USER_PROP));
+            assertNull(userManager.getAuthorizable(GROUP_DN));
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testSyncCreateGroup() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, SyncMode.CREATE_GROUP);
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(USER_ID, USER_PWD.toCharArray()));
+
+            root.refresh();
+            assertNull(userManager.getAuthorizable(USER_ID));
+            assertNull(userManager.getAuthorizable(GROUP_DN));
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testSyncCreateUserAndGroups() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, new String[]{SyncMode.CREATE_USER, SyncMode.CREATE_GROUP});
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(USER_ID, USER_PWD.toCharArray()));
+
+            root.refresh();
+            Authorizable user = userManager.getAuthorizable(USER_ID);
+            assertNotNull(user);
+            assertTrue(user.hasProperty(USER_PROP));
+            Authorizable group = userManager.getAuthorizable(GROUP_DN);
+            assertTrue(group.hasProperty(GROUP_PROP));
+            assertNotNull(group);
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    @Test
+    public void testNoSync() throws Exception {
+
+        if (!USE_COMMON_LDAP_FIXTURE) {
+            createLdapFixture();
+        }
+
+        options.put(ExternalLoginModule.PARAM_SYNC_MODE, "");
+
+        ContentSession cs = null;
+        try {
+            cs = login(new SimpleCredentials(USER_ID, USER_PWD.toCharArray()));
+
+            root.refresh();
+            assertNull(userManager.getAuthorizable(USER_ID));
+            assertNull(userManager.getAuthorizable(GROUP_DN));
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+    protected static void createLdapFixture() throws Exception {
+        LDAP_SERVER.addMember(
+                GROUP_DN = LDAP_SERVER.addGroup(GROUP_NAME),
+                LDAP_SERVER.addUser(USER_FIRSTNAME, USER_LASTNAME, USER_ID, USER_PWD));
+    }
+}

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginWithRepoLoginTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginWithRepoLoginTest.java?rev=1443002&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginWithRepoLoginTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapLoginWithRepoLoginTest.java Wed Feb  6 15:10:41 2013
@@ -0,0 +1,47 @@
+/*
+ * 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.ldap;
+
+import java.util.Collections;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+
+import org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl;
+import org.junit.Ignore;
+
+@Ignore //ignore for the moment because "mvn test" runs into PermGen memory issues
+public class LdapLoginWithRepoLoginTest extends LdapLoginTestBase {
+
+    @Override
+    protected Configuration getConfiguration() {
+        return new Configuration() {
+            @Override
+            public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+                return new AppConfigurationEntry[]{
+                        new AppConfigurationEntry(
+                                LoginModuleImpl.class.getName(),
+                                AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT,
+                                Collections.<String, Object>emptyMap()),
+                        new AppConfigurationEntry(
+                                LdapLoginModule.class.getName(),
+                                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                                options)
+                };
+            }
+        };
+    }
+}

Modified: 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=1443002&r1=1443001&r2=1443002&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java Wed Feb  6 15:10:41 2013
@@ -42,7 +42,7 @@ import static org.junit.Assert.fail;
  */
 public class ExternalLoginModuleTest extends AbstractSecurityTest {
 
-    private final HashMap<String, Object> options = new HashMap<String, Object>();
+    protected final HashMap<String, Object> options = new HashMap<String, Object>();
 
     private String userId;
     private Set<String> ids = new HashSet<String>();