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/11/02 10:54:26 UTC
svn commit: r1404905 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/spi/security/
main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/
test/java/org/apache/jackrabbit/oak/security/ test/java/org/apache...
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", "test@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