Author: tripod
Date: Tue Mar 11 01:41:23 2014
New Revision: 1576173
URL: http://svn.apache.org/r1576173
Log:
OAK-516 Create LdapLoginModule based on ExternalLoginModule (wip)
Added:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DebugTimer.java
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfig.java
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
Added:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DebugTimer.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DebugTimer.java?rev=1576173&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DebugTimer.java
(added)
+++
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DebugTimer.java
Tue Mar 11 01:41:23 2014
@@ -0,0 +1,77 @@
+/*
+ * 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.impl;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * {@code DebugTimer}...
+ */
+public class DebugTimer {
+
+ private static String[] units = {"ns", "us", "ms", "s"};
+
+ private List<TimeStamp> timestamps = new LinkedList<TimeStamp>();
+
+ private long now;
+
+ public DebugTimer() {
+ now = System.nanoTime();
+ }
+
+ public void mark(String msg) {
+ long then = now;
+ now = System.nanoTime();
+ timestamps.add(new TimeStamp(now-then, msg));
+ }
+
+ public String getString() {
+ if (timestamps.isEmpty()) {
+ return "";
+ }
+ StringBuilder b = new StringBuilder();
+ for (TimeStamp t: timestamps) {
+ if (b.length() > 0) {
+ b.append(", ");
+ } else {
+ b.append("(");
+ }
+ int u = 0;
+ double time = t.time;
+ while (time > 1000 && u<units.length-1) {
+ time = time / 1000;
+ u++;
+ }
+ b.append(String.format("%s=%.2f%s", t.msg, time, units[u]));
+ }
+ return b.append(')').toString();
+ }
+
+ private static class TimeStamp {
+
+ private final long time;
+
+ private final String msg;
+
+ private TimeStamp(long time, String msg) {
+ this.time = time;
+ this.msg = msg;
+ }
+ }
+}
\ No newline at end of file
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfig.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfig.java?rev=1576173&r1=1576172&r2=1576173&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfig.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfig.java
Tue Mar 11 01:41:23 2014
@@ -17,7 +17,6 @@
package org.apache.jackrabbit.oak.spi.security.authentication.external.impl;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -267,7 +266,12 @@ public class DefaultSyncConfig {
*/
@Nonnull
public Authorizable setAutoMembership(String ... autoMembership) {
- this.autoMembership = new
HashSet<String>(Arrays.asList(autoMembership));
+ this.autoMembership = new HashSet<String>();
+ for (String groupName: autoMembership) {
+ if (groupName.trim().length() > 0) {
+ this.autoMembership.add(groupName.trim());
+ }
+ }
return this;
}
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java?rev=1576173&r1=1576172&r2=1576173&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java
Tue Mar 11 01:41:23 2014
@@ -24,8 +24,11 @@ import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -96,6 +99,7 @@ public class DefaultSyncHandler implemen
/**
* Default constructor for OSGi
*/
+ @SuppressWarnings("UnusedDeclaration")
public DefaultSyncHandler() {
}
@@ -133,8 +137,6 @@ public class DefaultSyncHandler implemen
private final UserManager userManager;
- private final Root root;
-
private final ValueFactory valueFactory;
// we use the same wall clock for the entire context
@@ -144,7 +146,6 @@ public class DefaultSyncHandler implemen
private ContextImpl(ExternalIdentityProvider idp, UserManager
userManager, Root root) {
this.idp = idp;
this.userManager = userManager;
- this.root = root;
valueFactory = new ValueFactoryImpl(root, NamePathMapper.DEFAULT);
// initialize 'now'
@@ -167,25 +168,35 @@ public class DefaultSyncHandler implemen
@Override
public boolean sync(@Nonnull ExternalIdentity identity) throws
SyncException {
try {
+ DebugTimer timer = new DebugTimer();
+ boolean ret;
if (identity instanceof ExternalUser) {
User user = getAuthorizable(identity, User.class);
+ timer.mark("find");
if (user == null) {
user = createUser((ExternalUser) identity);
+ timer.mark("create");
}
- return syncUser((ExternalUser) identity, user);
+ ret = syncUser((ExternalUser) identity, user);
+ timer.mark("sync");
} else if (identity instanceof ExternalGroup) {
Group group = getAuthorizable(identity, Group.class);
+ timer.mark("find");
if (group == null) {
group = createGroup((ExternalGroup) identity);
+ timer.mark("create");
}
- return false;//syncGroup((ExternalGroup) identity, group);
+ ret = syncGroup((ExternalGroup) identity, group);
+ timer.mark("sync");
} else {
throw new IllegalArgumentException("identity must be user
or group but was: " + identity);
}
+ if (log.isDebugEnabled()) {
+ log.debug("sync({}) {}", identity.getId(),
timer.getString());
+ }
+ return ret;
} catch (RepositoryException e) {
throw new SyncException(e);
- } catch (ExternalIdentityException e) {
- throw new SyncException(e);
}
}
@@ -222,10 +233,9 @@ public class DefaultSyncHandler implemen
* @param externalUser the external user
* @return the repository user
* @throws RepositoryException if an error occurs
- * @throws ExternalIdentityException if an error occurs
*/
@CheckForNull
- private User createUser(ExternalUser externalUser) throws
RepositoryException, ExternalIdentityException {
+ private User createUser(ExternalUser externalUser) throws
RepositoryException {
Principal principal = new
PrincipalImpl(externalUser.getPrincipalName());
User user = userManager.createUser(
externalUser.getId(),
@@ -244,10 +254,9 @@ public class DefaultSyncHandler implemen
* @param externalGroup the external group
* @return the repository group
* @throws RepositoryException if an error occurs
- * @throws ExternalIdentityException if an error occurs
*/
@CheckForNull
- private Group createGroup(ExternalGroup externalGroup) throws
RepositoryException, ExternalIdentityException {
+ private Group createGroup(ExternalGroup externalGroup) throws
RepositoryException {
Principal principal = new
PrincipalImpl(externalGroup.getPrincipalName());
Group group = userManager.createGroup(
externalGroup.getId(),
@@ -259,21 +268,168 @@ public class DefaultSyncHandler implemen
}
- private boolean syncUser(ExternalUser external, User user) throws
RepositoryException {
+ private boolean syncUser(@Nonnull ExternalUser external, @Nonnull User
user) throws RepositoryException {
// first check if user is expired
// todo: add "forceSync" property for potential background sync
- if (!isExpired(user, config.user().getExpirationTime())) {
+ if (!isExpired(user, config.user().getExpirationTime(),
"Properties")) {
return false;
}
// synchronize the properties
syncProperties(external, user, config.user().getPropertyMapping());
+ // synchronize auto-group membership
+ applyMembership(user, config.user().getAutoMembership());
+
+ if (isExpired(user, config.user().getMembershipExpirationTime(),
"Membership")) {
+ // synchronize external memberships
+ syncMembership(external, user,
config.user().getMembershipNestingDepth());
+ }
+
// finally "touch" the sync property
user.setProperty(REP_LAST_SYNCED, nowValue);
return true;
}
+ private boolean syncGroup(ExternalGroup external, Group group) throws
RepositoryException {
+ // first check if user is expired
+ // todo: add "forceSync" property for potential background sync
+ if (!isExpired(group, config.group().getExpirationTime(),
"Properties")) {
+ return false;
+ }
+
+ // synchronize the properties
+ syncProperties(external, group,
config.group().getPropertyMapping());
+
+ // synchronize auto-group membership
+ applyMembership(group, config.group().getAutoMembership());
+
+ // finally "touch" the sync property
+ group.setProperty(REP_LAST_SYNCED, nowValue);
+ return true;
+ }
+
+ /**
+ * Recursively sync the memberships of an authorizable up-to the
specified depth. If the given depth
+ * is equal or less than 0, no syncing is performed.
+ *
+ * @param external the external identity
+ * @param auth the authorizable
+ * @param depth recursion depth.
+ * @throws RepositoryException
+ */
+ private void syncMembership(ExternalIdentity external, Authorizable
auth, long depth)
+ throws RepositoryException {
+ if (depth <= 0) {
+ return;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Syncing membership '{}' -> '{}'",
external.getExternalId().getString(), auth.getID());
+ }
+
+ final DebugTimer timer = new DebugTimer();
+ Iterable<ExternalIdentityRef> externalGroups;
+ try {
+ externalGroups = external.getDeclaredGroups();
+ } catch (ExternalIdentityException e) {
+ log.error("Error while retrieving external declared groups for
'{}'", external.getId(), e);
+ return;
+ }
+ timer.mark("fetching");
+
+ // first get the set of the existing groups that are synced ones
+ Map<String, Group> declaredExternalGroups = new HashMap<String,
Group>();
+ Iterator<Group> grpIter = auth.declaredMemberOf();
+ while (grpIter.hasNext()) {
+ Group grp = grpIter.next();
+ if (isSameIDP(grp)) {
+ declaredExternalGroups.put(grp.getID(), grp);
+ }
+ }
+ timer.mark("existing");
+
+ for (ExternalIdentityRef ref: externalGroups) {
+ log.debug("- processing membership {}", ref.getId());
+ // get group
+ ExternalGroup extGroup;
+ try {
+ extGroup = (ExternalGroup) idp.getIdentity(ref);
+ } catch (ClassCastException e) {
+ // this should really not be the case, so catching the CCE
is ok here.
+ log.warn("External identity '{}' is not a group, but
should be one.", ref.getString());
+ continue;
+ } catch (ExternalIdentityException e) {
+ log.warn("Unable to retrieve external group '{}' from
provider.", ref.getString(), e);
+ continue;
+ }
+ if (extGroup == null) {
+ log.warn("External group for ref '{}' could not be
retrieved from provider.", ref);
+ continue;
+ }
+ log.debug("- idp returned '{}'", extGroup.getId());
+
+ Group grp;
+ try {
+ grp = (Group)
userManager.getAuthorizable(extGroup.getId());
+ } catch (ClassCastException e) {
+ // this should really not be the case, so catching the CCE
is ok here.
+ log.warn("Authorizable '{}' is not a group, but should be
one.", extGroup.getId());
+ continue;
+ }
+ log.debug("- user manager returned '{}'", grp);
+
+ if (grp == null) {
+ grp = createGroup(extGroup);
+ log.debug("- created new group");
+ }
+ syncGroup(extGroup, grp);
+
+ // ensure membership
+ grp.addMember(auth);
+ log.debug("- added '{}' as member to '{}'", auth, grp);
+
+ // remember the declared group
+ declaredExternalGroups.remove(grp.getID());
+
+ // recursively apply further membership
+ if (depth > 1) {
+ log.debug("- recursively sync group membership of '{}'
(depth = {}).", grp.getID(), depth);
+ syncMembership(extGroup, grp, depth - 1);
+ } else {
+ log.debug("- group nesting level for '{}' reached",
grp.getID());
+ }
+ }
+ timer.mark("adding");
+ // remove us from the lost membership groups
+ for (Group grp: declaredExternalGroups.values()) {
+ grp.removeMember(auth);
+ log.debug("- removing member '{}' for group '{}'",
auth.getID(), grp.getID());
+ }
+ if (log.isDebugEnabled()) {
+ timer.mark("removing");
+ log.debug("syncMembership({}) {}", external.getId(),
timer.getString());
+ }
+ }
+
+ /**
+ * Ensures that the given authorizable is member of the specific
groups. Note that it does not create groups
+ * if missing, nor remove memberships of groups not in the given set.
+ * @param member the authorizable
+ * @param groups set of groups.
+ */
+ private void applyMembership(Authorizable member, Set<String> groups)
throws RepositoryException {
+ for (String groupName: groups) {
+ Authorizable group = userManager.getAuthorizable(groupName);
+ if (group == null) {
+ log.warn("Unable to apply auto-membership to {}. No such
group: {}", member.getID(), groupName);
+ } else if (group instanceof Group) {
+ ((Group) group).addMember(member);
+ } else {
+ log.warn("Unable to apply auto-membership to {}.
Authorizable '{}' is not a group.", member.getID(), groupName);
+ }
+ }
+ }
+
/**
* Syncs the properties specified in the {@code mapping} from the
external identity to the given authorizable.
* Note that this method does not check for value equality and just
blindly copies or deletes the properties.
@@ -310,71 +466,42 @@ public class DefaultSyncHandler implemen
* Checks if the given authorizable needs syncing based on the {@link
#REP_LAST_SYNCED} property.
* @param auth the authorizable to check
* @param expirationTime the expiration time to compare to.
+ * @param type debug message type
* @return {@code true} if the authorizable needs sync
*/
- private boolean isExpired(Authorizable auth, long expirationTime)
throws RepositoryException {
+ private boolean isExpired(Authorizable auth, long expirationTime,
String type) throws RepositoryException {
Value[] values = auth.getProperty(REP_LAST_SYNCED);
if (values == null || values.length == 0) {
if (log.isDebugEnabled()) {
- log.debug("{} '{}' needs sync. " + REP_LAST_SYNCED + " not
set.", auth.isGroup() ? "Group" : "User", auth.getID());
+ log.debug("{} of {} '{}' need sync. " + REP_LAST_SYNCED +
" not set.", new Object[] {
+ type,
+ auth.isGroup() ? "group" : "user",
+ auth.getID()
+ });
}
return true;
} else if (now - values[0].getLong() > expirationTime) {
if (log.isDebugEnabled()) {
- log.debug("{} '{}' needs sync. " + REP_LAST_SYNCED + "
expired ({} > {})", new Object[]{
- auth.isGroup() ? "Group" : "User", auth.getID(),
now - values[0].getLong(), expirationTime
+ log.debug("{} of {} '{}' need sync. " + REP_LAST_SYNCED +
" expired ({} > {})", new Object[]{
+ type,
+ auth.isGroup() ? "group" : "user",
+ auth.getID(),
+ now - values[0].getLong(), expirationTime
});
}
return true;
} else {
if (log.isDebugEnabled()) {
- log.debug("{} '{}' does not need sync.", auth.isGroup() ?
"Group" : "User", auth.getID());
+ log.debug("{} of {} '{}' do not need sync.", new Object[]{
+ type,
+ auth.isGroup() ? "group" : "user",
+ auth.getID()
+ });
}
return false;
}
}
- private boolean syncAuthorizable(ExternalIdentity externalUser,
Authorizable authorizable)
- throws RepositoryException, SyncException,
ExternalIdentityException {
- for (ExternalIdentityRef externalGroupRef :
externalUser.getDeclaredGroups()) {
- ExternalIdentity id = idp.getIdentity(externalGroupRef);
- if (id instanceof ExternalGroup) {
- ExternalGroup externalGroup = (ExternalGroup) id;
- String groupId = externalGroup.getId();
- Group group;
- Authorizable a = userManager.getAuthorizable(groupId);
- if (a == null) {
- group = createGroup(externalGroup);
- } else {
- group = (a.isGroup()) ? (Group) a : null;
- }
-
- if (group != null) {
- group.addMember(authorizable);
- } else {
- log.debug("No such group " + groupId + "; Ignoring
group membership.");
- }
- }
- }
-
- Map<String, ?> properties = externalUser.getProperties();
- for (String key : properties.keySet()) {
- Object prop = properties.get(key);
- if (prop instanceof Collection) {
- Value[] values = createValues((Collection) prop);
- if (values != null) {
- authorizable.setProperty(key, values);
- }
- } else {
- Value value = createValue(prop);
- if (value != null) {
- authorizable.setProperty(key, value);
- }
- }
- }
- return true;
- }
-
/**
* Creates a new JCR value of the given object, checking the internal
type.
* @param v the value
@@ -427,6 +554,27 @@ public class DefaultSyncHandler implemen
return values.toArray(new Value[values.size()]);
}
+ /**
+ * Checks if the given authorizable was synced from the same IDP by
comparing the IDP name of the
+ * {@value #REP_EXTERNAL_ID} property.
+ *
+ * todo: allow multiple IDPs on 1 authorizable
+ *
+ * @param auth the authorizable.
+ * @return {@code true} if same IDP.
+ */
+ private boolean isSameIDP(@Nullable Authorizable auth) throws
RepositoryException {
+ if (auth == null) {
+ return false;
+ }
+ Value[] v = auth.getProperty(REP_EXTERNAL_ID);
+ if (v == null || v.length == 0) {
+ return false;
+ }
+ ExternalIdentityRef ref =
ExternalIdentityRef.fromString(v[0].getString());
+ return idp.getName().equals(ref.getProviderName());
+ }
+
}
/**
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java?rev=1576173&r1=1576172&r2=1576173&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTest.java
Tue Mar 11 01:41:23 2014
@@ -97,23 +97,45 @@ public class ExternalLoginModuleTest ext
}
@Test
- @Ignore("group sync not implemented yet")
public void testSyncCreateGroup() throws Exception {
-// UserManager userManager = getUserManager(root);
-// 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();
-// }
+ UserManager userManager = getUserManager(root);
+ ContentSession cs = null;
+ try {
+ cs = login(new SimpleCredentials(userId, new char[0]));
+
+ root.refresh();
+ for (String id : new String[]{"a", "b", "c"}) {
+ assertNotNull(userManager.getAuthorizable(id));
+ }
+ for (String id : new String[]{"aa", "aaa"}) {
+ assertNull(userManager.getAuthorizable(id));
+ }
+ } finally {
+ if (cs != null) {
+ cs.close();
+ }
+ options.clear();
+ }
+ }
+
+ @Test
+ public void testSyncCreateGroupNesting() throws Exception {
+ syncConfig.user().setMembershipNestingDepth(2);
+ UserManager userManager = getUserManager(root);
+ ContentSession cs = null;
+ try {
+ cs = login(new SimpleCredentials(userId, new char[0]));
+
+ root.refresh();
+ for (String id : new String[]{"a", "b", "c", "aa", "aaa"}) {
+ assertNotNull(userManager.getAuthorizable(id));
+ }
+ } finally {
+ if (cs != null) {
+ cs.close();
+ }
+ options.clear();
+ }
}
@Test
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java?rev=1576173&r1=1576172&r2=1576173&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
Tue Mar 11 01:41:23 2014
@@ -58,6 +58,8 @@ public abstract class ExternalLoginModul
protected ExternalIdentityProvider idp;
+ protected DefaultSyncConfig syncConfig;
+
@Before
public void before() throws Exception {
super.before();
@@ -74,14 +76,15 @@ public abstract class ExternalLoginModul
options.put(ExternalLoginModule.PARAM_IDP_NAME, idp.getName());
// set default sync config
- DefaultSyncConfig cfg = new DefaultSyncConfig();
+ syncConfig = new DefaultSyncConfig();
Map<String, String> mapping = new HashMap<String, String>();
mapping.put("name", "name");
mapping.put("email", "email");
mapping.put("profile/name", "profile/name");
mapping.put("profile/age", "profile/age");
- cfg.user().setPropertyMapping(mapping);
- setSyncConfig(cfg);
+ syncConfig.user().setPropertyMapping(mapping);
+ syncConfig.user().setMembershipNestingDepth(1);
+ setSyncConfig(syncConfig);
}
@After
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java?rev=1576173&r1=1576172&r2=1576173&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
Tue Mar 11 01:41:23 2014
@@ -33,6 +33,8 @@ public class TestIdentityProvider implem
public TestIdentityProvider() {
+ addGroup(new TestGroup("aa"));
+ addGroup(new TestGroup("aaa"));
addGroup(new TestGroup("a").withGroups("aa", "aaa"));
addGroup(new TestGroup("b").withGroups("a"));
addGroup(new TestGroup("c"));
@@ -62,7 +64,11 @@ public class TestIdentityProvider implem
@Override
public ExternalIdentity getIdentity(@Nonnull ExternalIdentityRef ref)
throws ExternalIdentityException {
- return null;
+ ExternalIdentity id = externalUsers.get(ref.getId());
+ if (id != null) {
+ return id;
+ }
+ return externalGroups.get(ref.getId());
}
@Override