Author: dj
Date: Thu Aug 18 14:22:59 2016
New Revision: 1756792
URL: http://svn.apache.org/viewvc?rev=1756792&view=rev
Log:
OAK-4679 : Backport OAK-4119, OAK-4101, OAK-4087 and OAK-4344
- backported OAK-4087
Added:
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/SyncHandlerMapping.java
- copied unchanged from r1746408,
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/SyncHandlerMapping.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleAutoMembershipTest.java
- copied unchanged from r1746408,
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleAutoMembershipTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/PrincipalProviderAutoMembershipTest.java
- copied unchanged from r1746408,
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/PrincipalProviderAutoMembershipTest.java
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/external/
- copied from r1746408,
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/authentication/external/
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/
- copied from r1743674,
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/
Removed:
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/defaultusersync.md
Modified:
jackrabbit/oak/branches/1.4/ (props changed)
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContext.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProvider.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContextTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/AbstractPrincipalTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProviderTest.java
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/usersync.md
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/principal/principalprovider.md
jackrabbit/oak/branches/1.4/oak-run/pom.xml
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/AbstractExternalTest.java
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncAllExternalUsersTest.java
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncExternalUsersTest.java
Propchange: jackrabbit/oak/branches/1.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Aug 18 14:22:59 2016
@@ -1,3 +1,3 @@
/jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735081,1735141,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738136,1738138,1738207,1738252,1738775,1738795,1738833,1738950,1738957,1738963,1739712,1739760,1739867,1739894,1739959-1739960,1740114,1740116,1740250,1740333,1740360,1740625-1740626,1740774,1740837,1740971,1741016,1741032,1741339,1741343,1742077,1742117,1742363,1742520,1742888,1742916,1743097,1743172,1743343,1744265,1744292,1744959,1745038,1745197,1745368,1746086,1746117,1746342,1746345,1746696,1746981,1747198,1747200,1747341-1747342,1747492,1747512,1748505,1748553,1748722,1748870,1749275,1749350,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287,1750457,1750462,1750465,1750495,1750626,1750809,1750886,1751410,1751445-1751446,1751478,1751755,1751871,1752198,1752202,1752273-1752274,1752438,1752447
,1752508,1752616,1752659,1752672,1753262,1753331-1753332,1753355,1753444,1754117,1754239,1755157,1756520,1756580
+/jackrabbit/oak/trunk:1733615,1733875,1733913,1733929,1734230,1734254,1734279,1734941,1735052,1735081,1735141,1735267,1735405,1735484,1735549,1735564,1735588,1735622,1735638,1735919,1735983,1736176,1737309-1737310,1737334,1737349,1737998,1738004,1738136,1738138,1738207,1738252,1738775,1738795,1738833,1738950,1738957,1738963,1739712,1739760,1739867,1739894,1739959-1739960,1740114,1740116,1740250,1740333,1740360,1740625-1740626,1740774,1740837,1740971,1741016,1741032,1741339,1741343,1742077,1742117,1742363,1742520,1742888,1742916,1743097,1743172,1743343,1743674,1744265,1744292,1744670,1744672,1744959,1745038,1745127,1745197,1745368,1746086,1746117,1746342,1746345,1746408,1746696,1746981,1747198,1747200,1747341-1747342,1747492,1747512,1748505,1748553,1748722,1748870,1749275,1749350,1749464,1749475,1749645,1749662,1749815,1749872,1749875,1749899,1750052,1750076-1750077,1750287,1750457,1750462,1750465,1750495,1750626,1750809,1750886,1751410,1751445-1751446,1751478,1751755,1751871,1752198
,1752202,1752273-1752274,1752438,1752447,1752508,1752616,1752659,1752672,1753262,1753331-1753332,1753355,1753444,1754117,1754239,1755157,1756520,1756580
/jackrabbit/trunk:1345480
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContext.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContext.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContext.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContext.java
Thu Aug 18 14:22:59 2016
@@ -135,6 +135,11 @@ public class DynamicSyncContext extends
}
}
+ @Override
+ protected void applyMembership(@Nonnull Authorizable member, @Nonnull
Set<String> groups) throws RepositoryException {
+ log.debug("Dynamic membership sync enabled => omit setting
auto-membership for {} ", member.getID());
+ }
+
/**
* Recursively collect the principal names of the given declared group
* references up to the given depth.
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java
Thu Aug 18 14:22:59 2016
@@ -70,12 +70,12 @@ public class ExternalLoginModule extends
/**
* Name of the parameter that configures the name of the external identity
provider.
*/
- public static final String PARAM_IDP_NAME = "idp.name";
+ public static final String PARAM_IDP_NAME =
SyncHandlerMapping.PARAM_IDP_NAME;
/**
* Name of the parameter that configures the name of the synchronization
handler.
*/
- public static final String PARAM_SYNC_HANDLER_NAME = "sync.handlerName";
+ public static final String PARAM_SYNC_HANDLER_NAME =
SyncHandlerMapping.PARAM_SYNC_HANDLER_NAME;
private ExternalIdentityProviderManager idpManager;
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java
Thu Aug 18 14:22:59 2016
@@ -17,12 +17,12 @@
package org.apache.jackrabbit.oak.spi.security.authentication.external.impl;
import java.util.Hashtable;
-
import javax.jcr.Repository;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.security.auth.spi.LoginModule;
+import com.google.common.collect.ImmutableMap;
import org.apache.felix.jaas.LoginModuleFactory;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -43,8 +43,6 @@ import org.osgi.service.component.Compon
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ImmutableMap;
-
/**
* Implements a LoginModuleFactory that creates {@link ExternalLoginModule}s
and allows to configure login modules
* via OSGi config.
@@ -56,7 +54,7 @@ import com.google.common.collect.Immutab
configurationFactory = true
)
@Service
-public class ExternalLoginModuleFactory implements LoginModuleFactory {
+public class ExternalLoginModuleFactory implements LoginModuleFactory,
SyncHandlerMapping {
private static final Logger log =
LoggerFactory.getLogger(ExternalLoginModuleFactory.class);
@@ -92,14 +90,14 @@ public class ExternalLoginModuleFactory
label = "Identity Provider Name",
description = "Name of the identity provider (for example:
'ldap')."
)
- public static final String PARAM_IDP_NAME =
ExternalLoginModule.PARAM_IDP_NAME;
+ public static final String PARAM_IDP_NAME =
SyncHandlerMapping.PARAM_IDP_NAME;
@Property(
value = "default",
label = "Sync Handler Name",
description = "Name of the sync handler."
)
- public static final String PARAM_SYNC_HANDLER_NAME =
ExternalLoginModule.PARAM_SYNC_HANDLER_NAME;
+ public static final String PARAM_SYNC_HANDLER_NAME =
SyncHandlerMapping.PARAM_SYNC_HANDLER_NAME;
@Reference
private SyncManager syncManager;
@@ -120,6 +118,7 @@ public class ExternalLoginModuleFactory
*/
private Registration mbeanRegistration;
+ //----------------------------------------------------< SCR integration
>---
/**
* Activates the LoginModuleFactory service
* @param context the component context
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProvider.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProvider.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProvider.java
Thu Aug 18 14:22:59 2016
@@ -19,12 +19,14 @@ package org.apache.jackrabbit.oak.spi.se
import java.security.Principal;
import java.security.acl.Group;
import java.text.ParseException;
+import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -54,6 +56,7 @@ import org.apache.jackrabbit.oak.api.Tre
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityRef;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIdentityConstants;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
@@ -95,12 +98,18 @@ class ExternalGroupPrincipalProvider imp
private final Root root;
private final NamePathMapper namePathMapper;
+
private final UserManager userManager;
+ private final AutoMembershipPrincipals autoMembershipPrincipals;
- ExternalGroupPrincipalProvider(Root root, UserConfiguration uc,
NamePathMapper namePathMapper) {
+ ExternalGroupPrincipalProvider(@Nonnull Root root, @Nonnull
UserConfiguration uc,
+ @Nonnull NamePathMapper namePathMapper,
+ @Nonnull Map<String, String[]>
autoMembershipMapping) {
this.root = root;
this.namePathMapper = namePathMapper;
+
userManager = uc.getUserManager(root, namePathMapper);
+ autoMembershipPrincipals = new
AutoMembershipPrincipals(autoMembershipMapping);
}
//--------------------------------------------------< PrincipalProvider
>---
@@ -164,6 +173,15 @@ class ExternalGroupPrincipalProvider imp
}
//------------------------------------------------------------< private
>---
+ @CheckForNull
+ private String getIdpName(@Nonnull Tree userTree) {
+ PropertyState ps = userTree.getProperty(REP_EXTERNAL_ID);
+ if (ps != null) {
+ return
ExternalIdentityRef.fromString(ps.getValue(Type.STRING)).getProviderName();
+ } else {
+ return null;
+ }
+ }
private Set<Group> getGroupPrincipals(@CheckForNull Authorizable
authorizable) throws RepositoryException {
if (authorizable != null && !authorizable.isGroup()) {
@@ -178,10 +196,14 @@ class ExternalGroupPrincipalProvider imp
if (userTree.exists() && UserUtil.isType(userTree,
AuthorizableType.USER) && userTree.hasProperty(REP_EXTERNAL_PRINCIPAL_NAMES)) {
PropertyState ps =
userTree.getProperty(REP_EXTERNAL_PRINCIPAL_NAMES);
if (ps != null) {
+ // we have an 'external' user that has been synchronized with
the dynamic-membership option
Set<Group> groupPrincipals = Sets.newHashSet();
for (String principalName : ps.getValue(Type.STRINGS)) {
groupPrincipals.add(new
ExternalGroupPrincipal(principalName));
}
+
+ // add existing group principals as defined with the
_autoMembership_ option.
+
groupPrincipals.addAll(autoMembershipPrincipals.get(getIdpName(userTree)));
return groupPrincipals;
}
}
@@ -194,6 +216,10 @@ class ExternalGroupPrincipalProvider imp
* {@link #REP_EXTERNAL_PRINCIPAL_NAMES} properties that match the given
* name or name hint.
*
+ * NOTE: ignore any principals listed in the {@link
DefaultSyncConfig.User#autoMembership}
+ * because they are expected to exist in the system and thus will be found
+ * by another principal provider instance.
+ *
* @param nameHint The principal name or name hint to be searched for.
* @param exactMatch boolean flag indicating if the query should search for
* exact matching.
@@ -409,4 +435,54 @@ class ExternalGroupPrincipalProvider imp
return null;
}
}
+
+ private final class AutoMembershipPrincipals {
+
+ private final Map<String, String[]> autoMembershipMapping;
+ private final Map<String, Set<Group>> principalMap;
+
+ private AutoMembershipPrincipals(@Nonnull Map<String, String[]>
autoMembershipMapping) {
+ this.autoMembershipMapping = autoMembershipMapping;
+ this.principalMap = new ConcurrentHashMap<String,
Set<Group>>(autoMembershipMapping.size());
+ }
+
+ @Nonnull
+ private Collection<Group> get(@CheckForNull String idpName) {
+ if (idpName == null) {
+ return ImmutableSet.of();
+ }
+
+ Set<Group> principals;
+ if (!principalMap.containsKey(idpName)) {
+ String[] vs = autoMembershipMapping.get(idpName);
+ if (vs == null) {
+ principals = ImmutableSet.of();
+ } else {
+ ImmutableSet.Builder<Group> builder =
ImmutableSet.builder();
+ for (String groupId : autoMembershipMapping.get(idpName)) {
+ try {
+ Authorizable gr =
userManager.getAuthorizable(groupId);
+ if (gr != null && gr.isGroup()) {
+ Principal grPrincipal = gr.getPrincipal();
+ if (grPrincipal instanceof Group) {
+ builder.add((Group) grPrincipal);
+ } else {
+ log.warn("Principal of group {} is not of
type java.security.acl.Group -> Ignoring", groupId);
+ }
+ } else {
+ log.warn("Configured auto-membership group {}
does not exist -> Ignoring", groupId);
+ }
+ } catch (RepositoryException e) {
+ log.debug("Failed to retrieved 'auto-membership'
group with id {}", groupId, e);
+ }
+ }
+ principals = builder.build();
+ }
+ principalMap.put(idpName, principals);
+ } else {
+ principals = principalMap.get(idpName);
+ }
+ return principals;
+ }
+ }
}
\ No newline at end of file
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.java
Thu Aug 18 14:22:59 2016
@@ -18,6 +18,8 @@ package org.apache.jackrabbit.oak.spi.se
import java.security.Principal;
import java.security.acl.Group;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -26,8 +28,11 @@ import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -46,6 +51,8 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncHandler;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncConfigImpl;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.SyncHandlerMapping;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalManagerImpl;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
@@ -54,6 +61,8 @@ import org.apache.jackrabbit.oak.spi.xml
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Implementation of the {@code PrincipalConfiguration} interface that provides
@@ -73,7 +82,10 @@ import org.osgi.util.tracker.ServiceTrac
@Service({PrincipalConfiguration.class, SecurityConfiguration.class})
public class ExternalPrincipalConfiguration extends ConfigurationBase
implements PrincipalConfiguration {
+ private static final Logger log =
LoggerFactory.getLogger(ExternalPrincipalConfiguration.class);
+
private SyncConfigTracker syncConfigTracker;
+ private SyncHandlerMappingTracker syncHandlerMappingTracker;
@SuppressWarnings("UnusedDeclaration")
public ExternalPrincipalConfiguration() {
@@ -96,7 +108,7 @@ public class ExternalPrincipalConfigurat
public PrincipalProvider getPrincipalProvider(Root root, NamePathMapper
namePathMapper) {
if (dynamicMembershipEnabled()) {
UserConfiguration uc =
getSecurityProvider().getConfiguration(UserConfiguration.class);
- return new ExternalGroupPrincipalProvider(root, uc,
namePathMapper);
+ return new ExternalGroupPrincipalProvider(root, uc,
namePathMapper, syncConfigTracker.getAutoMembership());
} else {
return EmptyPrincipalProvider.INSTANCE;
}
@@ -132,8 +144,13 @@ public class ExternalPrincipalConfigurat
@Activate
private void activate(BundleContext bundleContext, Map<String, Object>
properties) {
setParameters(ConfigurationParameters.of(properties));
- syncConfigTracker = new SyncConfigTracker(bundleContext);
+ syncHandlerMappingTracker = new
SyncHandlerMappingTracker(bundleContext);
+ syncHandlerMappingTracker.open();
+
+ syncConfigTracker = new SyncConfigTracker(bundleContext,
syncHandlerMappingTracker);
syncConfigTracker.open();
+
+
}
@SuppressWarnings("UnusedDeclaration")
@@ -142,6 +159,9 @@ public class ExternalPrincipalConfigurat
if (syncConfigTracker != null) {
syncConfigTracker.close();
}
+ if (syncHandlerMappingTracker != null) {
+ syncHandlerMappingTracker.close();
+ }
}
//------------------------------------------------------------< private
>---
@@ -196,11 +216,14 @@ public class ExternalPrincipalConfigurat
*/
private static final class SyncConfigTracker extends ServiceTracker {
+ private final SyncHandlerMappingTracker mappingTracker;
+
private Set<ServiceReference> enablingRefs = new
HashSet<ServiceReference>();
private boolean isEnabled = false;
- public SyncConfigTracker(BundleContext context) {
+ public SyncConfigTracker(@Nonnull BundleContext context, @Nonnull
SyncHandlerMappingTracker mappingTracker) {
super(context, SyncHandler.class.getName(), null);
+ this.mappingTracker = mappingTracker;
}
@Override
@@ -234,5 +257,83 @@ public class ExternalPrincipalConfigurat
private static boolean hasDynamicMembership(ServiceReference
reference) {
return
PropertiesUtil.toBoolean(reference.getProperty(DefaultSyncConfigImpl.PARAM_USER_DYNAMIC_MEMBERSHIP),
DefaultSyncConfigImpl.PARAM_USER_DYNAMIC_MEMBERSHIP_DEFAULT);
}
+
+ private Map<String, String[]> getAutoMembership() {
+ Map<String, String[]> autoMembership = new HashMap<String,
String[]>();
+ for (ServiceReference ref : enablingRefs) {
+ String syncHandlerName =
PropertiesUtil.toString(ref.getProperty(DefaultSyncConfigImpl.PARAM_NAME),
DefaultSyncConfigImpl.PARAM_NAME_DEFAULT);
+ String[] membership =
PropertiesUtil.toStringArray(ref.getProperty(DefaultSyncConfigImpl.PARAM_GROUP_AUTO_MEMBERSHIP),
new String[0]);
+
+ for (String idpName :
mappingTracker.getIdpNames(syncHandlerName)) {
+ String[] previous = autoMembership.put(idpName,
membership);
+ if (previous != null) {
+ String msg = (Arrays.equals(previous, membership)) ?
"Duplicate" : "Colliding";
+ log.debug(msg + " auto-membership configuration for
IDP '{}'; replacing previous values {} by {} defined by SyncHandler '{}'",
+ idpName, Arrays.toString(previous),
Arrays.toString(membership), syncHandlerName);
+ }
+ }
+ }
+ return autoMembership;
+ }
+ }
+
+ /**
+ * {@code ServiceTracker} to detect any {@link SyncHandler} that has
+ * dynamic membership enabled.
+ */
+ private static final class SyncHandlerMappingTracker extends
ServiceTracker {
+
+ private Map<ServiceReference, String[]> referenceMap = new
HashMap<ServiceReference, String[]>();
+
+ public SyncHandlerMappingTracker(@Nonnull BundleContext context) {
+ super(context, SyncHandlerMapping.class.getName(), null);
+ }
+
+ @Override
+ public Object addingService(ServiceReference reference) {
+ addMapping(reference);
+ return super.addingService(reference);
+ }
+
+ @Override
+ public void modifiedService(ServiceReference reference, Object
service) {
+ addMapping(reference);
+ super.modifiedService(reference, service);
+ }
+
+ @Override
+ public void removedService(ServiceReference reference, Object service)
{
+ referenceMap.remove(reference);
+ super.removedService(reference, service);
+ }
+
+ private void addMapping(ServiceReference reference) {
+ String idpName =
PropertiesUtil.toString(reference.getProperty(ExternalLoginModuleFactory.PARAM_IDP_NAME),
null);
+ String syncHandlerName =
PropertiesUtil.toString(reference.getProperty(ExternalLoginModuleFactory.PARAM_SYNC_HANDLER_NAME),
null);
+
+ if (idpName != null && syncHandlerName != null) {
+ referenceMap.put(reference, new String[]{syncHandlerName,
idpName});
+ } else {
+ log.warn("Ignoring SyncHandlerMapping with incomplete mapping
of IDP '{}' and SyncHandler '{}'", idpName, syncHandlerName);
+ }
+ }
+
+ private Iterable<String> getIdpNames(@Nonnull final String
syncHandlerName) {
+ return Iterables.filter(Iterables.transform(referenceMap.values(),
new Function<String[], String>() {
+ @Nullable
+ @Override
+ public String apply(@Nullable String[] input) {
+ if (input != null && input.length == 2) {
+ if (syncHandlerName.equals(input[0])) {
+ return input[1];
+ } // else: different sync-handler
+ } else {
+ log.warn("Unexpected value of reference map.
Expected String[] with length = 2");
+ }
+ return null;
+ }
+ }
+ ), Predicates.notNull());
+ }
}
}
\ No newline at end of file
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleTestBase.java
Thu Aug 18 14:22:59 2016
@@ -57,10 +57,10 @@ public abstract class ExternalLoginModul
testIdpReg = whiteboard.register(ExternalIdentityProvider.class, idp,
Collections.<String, Object>emptyMap());
- options.put(ExternalLoginModule.PARAM_SYNC_HANDLER_NAME, "default");
- options.put(ExternalLoginModule.PARAM_IDP_NAME, idp.getName());
-
setSyncConfig(syncConfig);
+
+ options.put(ExternalLoginModule.PARAM_SYNC_HANDLER_NAME,
syncConfig.getName());
+ options.put(ExternalLoginModule.PARAM_IDP_NAME, idp.getName());
}
@After
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
Thu Aug 18 14:22:59 2016
@@ -92,7 +92,7 @@ public class TestIdentityProvider implem
@Nonnull
@Override
public String getName() {
- return "test";
+ return idpName;
}
@Override
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContextTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContextTest.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContextTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DynamicSyncContextTest.java
Thu Aug 18 14:22:59 2016
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.spi.se
import java.util.HashSet;
import java.util.Set;
+import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.jcr.RepositoryException;
@@ -31,6 +32,7 @@ import com.google.common.collect.Iterabl
import com.google.common.collect.Sets;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
@@ -418,6 +420,21 @@ public class DynamicSyncContextTest exte
assertFalse(r.hasPendingChanges());
}
+ @Test
+ public void testAutoMembership() throws Exception {
+ Group gr = userManager.createGroup("group" + UUID.randomUUID());
+ r.commit();
+
+ syncConfig.user().setAutoMembership(gr.getID(), "non-existing-group");
+
+ SyncResult result = syncContext.sync(idp.getUser(USER_ID));
+ assertSame(SyncResult.Status.ADD, result.getStatus());
+
+ User u = userManager.getAuthorizable(USER_ID, User.class);
+ assertFalse(gr.isDeclaredMember(u));
+ assertFalse(gr.isMember(u));
+ }
+
private static final class TestUserWithGroupRefs extends
TestIdentityProvider.TestIdentity implements ExternalUser {
private Iterable<ExternalIdentityRef> declaredGroupRefs;
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/AbstractPrincipalTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/AbstractPrincipalTest.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/AbstractPrincipalTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/AbstractPrincipalTest.java
Thu Aug 18 14:22:59 2016
@@ -17,9 +17,11 @@
package
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.principal;
import java.security.Principal;
+import java.util.Set;
import java.util.UUID;
import javax.annotation.Nonnull;
+import com.google.common.collect.ImmutableMap;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -63,7 +65,9 @@ public abstract class AbstractPrincipalT
@Nonnull
PrincipalProvider createPrincipalProvider() {
- return new ExternalGroupPrincipalProvider(root,
getSecurityProvider().getConfiguration(UserConfiguration.class),
NamePathMapper.DEFAULT);
+ Set<String> autoMembership = syncConfig.user().getAutoMembership();
+ return new ExternalGroupPrincipalProvider(root,
getSecurityProvider().getConfiguration(UserConfiguration.class),
+ NamePathMapper.DEFAULT, ImmutableMap.of(idp.getName(),
autoMembership.toArray(new String[autoMembership.size()])));
}
@Override
Modified:
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProviderTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProviderTest.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProviderTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalGroupPrincipalProviderTest.java
Thu Aug 18 14:22:59 2016
@@ -53,7 +53,7 @@ import static org.junit.Assert.fail;
public class ExternalGroupPrincipalProviderTest extends AbstractPrincipalTest {
- private void syncWithMembership(@Nonnull ExternalUser externalUser, long
depth) throws Exception {
+ void syncWithMembership(@Nonnull ExternalUser externalUser, long depth)
throws Exception {
DefaultSyncConfig sc = new DefaultSyncConfig();
sc.user().setMembershipNestingDepth(depth);
@@ -68,7 +68,11 @@ public class ExternalGroupPrincipalProvi
root.refresh();
}
- private Set<Principal> getDeclaredGroupPrincipals(@Nonnull String userId)
throws ExternalIdentityException {
+ Set<Principal> getExpectedGroupPrincipals(@Nonnull String userId) throws
Exception {
+ return getDeclaredGroupPrincipals(userId);
+ }
+
+ Set<Principal> getDeclaredGroupPrincipals(@Nonnull String userId) throws
Exception {
Set<Principal> principals =
ImmutableSet.copyOf(Iterables.transform(idp.getUser(userId).getDeclaredGroups(),
new Function<ExternalIdentityRef, Principal>() {
@Nullable
@Override
@@ -76,16 +80,24 @@ public class ExternalGroupPrincipalProvi
try {
return new
PrincipalImpl(idp.getIdentity(input).getPrincipalName());
} catch (ExternalIdentityException e) {
- fail(e.getMessage());
- return null;
+ throw new RuntimeException(e);
}
- }
-
- ;
+ };
}));
return principals;
}
+ void collectExpectedPrincipals(Set<Principal> grPrincipals, @Nonnull
Iterable<ExternalIdentityRef> declaredGroups, long depth) throws Exception {
+ if (depth <= 0) {
+ return;
+ }
+ for (ExternalIdentityRef ref : declaredGroups) {
+ ExternalIdentity ei = idp.getIdentity(ref);
+ grPrincipals.add(new PrincipalImpl(ei.getPrincipalName()));
+ collectExpectedPrincipals(grPrincipals, ei.getDeclaredGroups(),
depth - 1);
+ }
+ }
+
@Test
public void testGetPrincipalLocalUser() throws Exception {
assertNull(principalProvider.getPrincipal(getTestUser().getPrincipal().getName()));
@@ -233,7 +245,7 @@ public class ExternalGroupPrincipalProvi
Authorizable user = getUserManager(root).getAuthorizable(USER_ID);
assertNotNull(user);
- Set<Principal> expected = getDeclaredGroupPrincipals(USER_ID);
+ Set<Principal> expected = getExpectedGroupPrincipals(USER_ID);
Set<? extends Principal> principals =
principalProvider.getGroupMembership(user.getPrincipal());
assertEquals(expected, principals);
@@ -274,17 +286,6 @@ public class ExternalGroupPrincipalProvi
assertEquals(expectedGrPrincipals, principals);
}
- private void collectExpectedPrincipals(Set<Principal> grPrincipals,
@Nonnull Iterable<ExternalIdentityRef> declaredGroups, long depth) throws
ExternalIdentityException {
- if (depth <= 0) {
- return;
- }
- for (ExternalIdentityRef ref : declaredGroups) {
- ExternalIdentity ei = idp.getIdentity(ref);
- grPrincipals.add(new PrincipalImpl(ei.getPrincipalName()));
- collectExpectedPrincipals(grPrincipals, ei.getDeclaredGroups(),
depth - 1);
- }
- }
-
@Test
public void testGetGroupMembershipExternalGroup() throws Exception {
Authorizable group =
getUserManager(root).getAuthorizable("secondGroup");
@@ -313,7 +314,7 @@ public class ExternalGroupPrincipalProvi
@Test
public void testGetPrincipalsExternalUser() throws Exception {
Set<? extends Principal> principals =
principalProvider.getPrincipals(USER_ID);
- assertEquals(getDeclaredGroupPrincipals(USER_ID), principals);
+ assertEquals(getExpectedGroupPrincipals(USER_ID), principals);
}
@Test
Modified:
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md
(original)
+++
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md
Thu Aug 18 14:22:59 2016
@@ -64,7 +64,7 @@ if the user is not yet present in the lo
check the credentials with the external system during the `login()` method.
The details of the default user/group synchronization mechanism are described
in section
-[User and Group Synchronization : The Default
Implementation](defaultusersync.html)
+[User and Group Synchronization : The Default
Implementation](external/defaultusersync.html)
##### Supported Credentials
Modified:
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/usersync.md
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/usersync.md?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/usersync.md
(original)
+++
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/usersync.md
Thu Aug 18 14:22:59 2016
@@ -51,7 +51,7 @@ for the following tasks:
Oak 1.0 provides a default implementation of the user synchronization API that
allow
to plug additional `SyncHandler` implementations.
-Default implementation is described in section [User and Group Synchronization
: The Default Implementation](defaultusersync.html).
+Default implementation is described in section [User and Group Synchronization
: The Default Implementation](external/defaultusersync.html).
### Pluggability
Modified:
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/principal/principalprovider.md
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/principal/principalprovider.md?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/principal/principalprovider.md
(original)
+++
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/principal/principalprovider.md
Thu Aug 18 14:22:59 2016
@@ -79,7 +79,7 @@ principals on the IDP but relies on a pe
the names of these external principals are synchronized to based on a
configurable
expiration time.
-See section [User and Group Synchronization : The Default
Implementation](../authentication/defaultusersync.html)
+See section [User and Group Synchronization : The Default
Implementation](../authentication/external/defaultusersync.html)
for additional details.
Since Oak 1.5.3
Modified: jackrabbit/oak/branches/1.4/oak-run/pom.xml
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-run/pom.xml?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-run/pom.xml (original)
+++ jackrabbit/oak/branches/1.4/oak-run/pom.xml Thu Aug 18 14:22:59 2016
@@ -282,6 +282,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-auth-external</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>7.0.64</version>
@@ -407,6 +412,12 @@
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
<!-- Findbugs annotations -->
<dependency>
<groupId>com.google.code.findbugs</groupId>
Modified:
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractTest.java
Thu Aug 18 14:22:59 2016
@@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory;
/**
* Abstract base class for individual performance benchmarks.
*/
-abstract class AbstractTest<T> extends Benchmark implements CSVResultGenerator
{
+public abstract class AbstractTest<T> extends Benchmark implements
CSVResultGenerator {
/**
* A random string to guarantee concurrently running tests don't overwrite
Modified:
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java?rev=1756792&r1=1756791&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
Thu Aug 18 14:22:59 2016
@@ -32,6 +32,9 @@ import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.apache.commons.io.FileUtils;
+import
org.apache.jackrabbit.oak.benchmark.authentication.external.ExternalLoginTest;
+import
org.apache.jackrabbit.oak.benchmark.authentication.external.SyncAllExternalUsersTest;
+import
org.apache.jackrabbit.oak.benchmark.authentication.external.SyncExternalUsersTest;
import org.apache.jackrabbit.oak.benchmark.wikipedia.WikipediaImport;
import org.apache.jackrabbit.oak.fixture.JackrabbitRepositoryFixture;
import org.apache.jackrabbit.oak.fixture.OakFixture;
@@ -128,6 +131,10 @@ public class BenchmarkRunner {
.defaultsTo(Boolean.FALSE);
OptionSpec<String> supportedPaths = parser.accepts("supportedPaths",
"Supported paths in composite setup.")
.withOptionalArg().ofType(String.class).withValuesSeparatedBy(',');
+ OptionSpec<Boolean> dynamicMembership =
parser.accepts("dynamicMembership", "Enable dynamic membership handling during
synchronisation of external users.")
+
.withOptionalArg().ofType(Boolean.class).defaultsTo(Boolean.FALSE);
+ OptionSpec<String> autoMembership = parser.accepts("autoMembership",
"Ids of those groups a given external identity automatically become member of.")
+
.withOptionalArg().ofType(String.class).withValuesSeparatedBy(',');
OptionSpec<String> nonOption = parser.nonOptions();
OptionSpec help = parser.acceptsAll(asList("h", "?", "help"), "show
help").forHelp();
OptionSet options = parser.parse(args);
@@ -341,7 +348,12 @@ public class BenchmarkRunner {
wikipedia.value(options),
flatStructure.value(options),
report.value(options), withStorage.value(options)),
- new ReplicaCrashResilienceTest()
+ new ReplicaCrashResilienceTest(),
+
+ // benchmarks for oak-auth-external
+ new ExternalLoginTest(numberOfUsers.value(options),
numberOfGroups.value(options), expiration.value(options),
dynamicMembership.value(options), autoMembership.values(options)),
+ new SyncAllExternalUsersTest(numberOfUsers.value(options),
numberOfGroups.value(options), expiration.value(options),
dynamicMembership.value(options), autoMembership.values(options)),
+ new SyncExternalUsersTest(numberOfUsers.value(options),
numberOfGroups.value(options), expiration.value(options),
dynamicMembership.value(options), autoMembership.values(options),
batchSize.value(options))
};
Set<String> argset = Sets.newHashSet(nonOption.values(options));
Modified:
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/AbstractExternalTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/AbstractExternalTest.java?rev=1756792&r1=1743674&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/AbstractExternalTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/AbstractExternalTest.java
Thu Aug 18 14:22:59 2016
@@ -33,6 +33,8 @@ import javax.security.auth.login.Configu
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.oak.Oak;
import org.apache.jackrabbit.oak.benchmark.AbstractTest;
import org.apache.jackrabbit.oak.fixture.JcrCreator;
@@ -52,30 +54,44 @@ import org.apache.jackrabbit.oak.spi.sec
import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncHandler;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncManager;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncConfigImpl;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIDPManagerImpl;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.SyncHandlerMapping;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.SyncManagerImpl;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.principal.ExternalPrincipalConfiguration;
+import
org.apache.jackrabbit.oak.spi.security.principal.CompositePrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
+import org.apache.sling.testing.mock.osgi.context.OsgiContextImpl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Base benchmark test for external authentication.
*
* The setup currently defines the following configuration options:
*
- * - {@code numberofUsers} : number of user accounts that are 'known' to the
IDP
- * - {@code numberofGroups}: number of groups 'known' to the IDP and equally
used to define the membershipSize of each user.
+ * - {@code numberOfUsers} : number of user accounts that are 'known' to the
IDP
+ * - {@code numberOfGroups}: number of groups 'known' to the IDP and equally
used to define the membershipSize of each user.
* - {@code expirationTime}: expiration time as set with
* {@link DefaultSyncConfig.Authorizable#setExpirationTime(long)}, used for
both users and groups
* - {@code dynamicMembership}: boolean flag to enable dynamic membership (see
OAK-4101)
*
* Note: by default the {@link
DefaultSyncConfig.User#setMembershipNestingDepth(long)}
* is set to 1 and each user will become member of each of the groups as
defined
- * by {@code numberofGroups}.
+ * by {@code numberOfGroups}.
*/
abstract class AbstractExternalTest extends AbstractTest {
private static final String PATH_PREFIX = "pathPrefix";
+
+ private final Random random = new Random();
+ private final ExternalPrincipalConfiguration
externalPrincipalConfiguration = new ExternalPrincipalConfiguration();
+
final DefaultSyncConfig syncConfig = new DefaultSyncConfig();
final SyncHandler syncHandler = new DefaultSyncHandler(syncConfig);
@@ -84,19 +100,23 @@ abstract class AbstractExternalTest exte
SyncManagerImpl syncManager;
ExternalIdentityProviderManager idpManager;
- private final Random random = new Random();
-
- protected AbstractExternalTest(int numberofUsers, int numberofGroups, long
expTime, boolean dynamicMembership) {
- idp = new TestIdentityProvider(numberofUsers, numberofGroups);
-
syncConfig.user().setMembershipNestingDepth(1).setExpirationTime(expTime).setPathPrefix(PATH_PREFIX);
-
syncConfig.group().setExpirationTime(expTime).setPathPrefix(PATH_PREFIX);
- // TODO OAK-4101 :
syncConfig.user().setDynamicMembership(dynamicMembership);
+ protected AbstractExternalTest(int numberOfUsers, int numberOfGroups,
+ long expTime, boolean dynamicMembership,
+ @Nonnull List<String> autoMembership) {
+ idp = new TestIdentityProvider(numberOfUsers, numberOfGroups);
+ syncConfig.user()
+ .setMembershipNestingDepth(1)
+ .setDynamicMembership(dynamicMembership)
+ .setAutoMembership(autoMembership.toArray(new
String[autoMembership.size()]))
+ .setExpirationTime(expTime).setPathPrefix(PATH_PREFIX);
+ syncConfig.group()
+ .setExpirationTime(expTime).setPathPrefix(PATH_PREFIX);
}
protected abstract Configuration createConfiguration();
protected String getRandomUserId() {
- int index = random.nextInt(((TestIdentityProvider) idp).numberofUsers);
+ int index = random.nextInt(((TestIdentityProvider) idp).numberOfUsers);
return "u" + index;
}
@@ -112,6 +132,19 @@ abstract class AbstractExternalTest exte
super.run(iterable, concurrencyLevels);
}
+ @Override
+ protected void beforeSuite() throws Exception {
+ Set<String> autoMembership = syncConfig.user().getAutoMembership();
+ if (!autoMembership.isEmpty()) {
+ Session s = loginAdministrative();
+ UserManager userManager = ((JackrabbitSession) s).getUserManager();
+ for (String groupId : autoMembership) {
+ userManager.createGroup(groupId, new PrincipalImpl(groupId),
PATH_PREFIX);
+ }
+ s.save();
+ }
+ }
+
/**
* Remove any user/group accounts that have been synchronized into the
repo.
*
@@ -146,6 +179,27 @@ abstract class AbstractExternalTest exte
whiteboard.register(ExternalIdentityProvider.class, idp,
Collections.emptyMap());
whiteboard.register(SyncHandler.class, syncHandler,
Collections.emptyMap());
+ // assert proper init of the
'externalPrincipalConfiguration' if dynamic membership is enabled
+ if (syncConfig.user().getDynamicMembership()) {
+ OsgiContextImpl context = new OsgiContextImpl();
+
+ // register the ExternalPrincipal configuration in
order to have it's
+ // activate method invoked.
+
context.registerInjectActivateService(externalPrincipalConfiguration);
+
+ // now register the sync-handler with the dynamic
membership config
+ // in order to enable dynamic membership with the
external principal configuration
+ Map props = ImmutableMap.of(
+
DefaultSyncConfigImpl.PARAM_USER_DYNAMIC_MEMBERSHIP,
syncConfig.user().getDynamicMembership(),
+
DefaultSyncConfigImpl.PARAM_GROUP_AUTO_MEMBERSHIP,
syncConfig.user().getAutoMembership());
+ context.registerService(SyncHandler.class,
WhiteboardUtils.getService(whiteboard, SyncHandler.class), props);
+
+ Map shMappingProps = ImmutableMap.of(
+ SyncHandlerMapping.PARAM_IDP_NAME,
idp.getName(),
+ SyncHandlerMapping.PARAM_SYNC_HANDLER_NAME,
syncConfig.getName());
+ context.registerService(SyncHandlerMapping.class, new
SyncHandlerMapping() {}, shMappingProps);
+ }
+
SecurityProvider sp = new
TestSecurityProvider(ConfigurationParameters.EMPTY);
return new Jcr(oak).with(sp);
}
@@ -158,25 +212,24 @@ abstract class AbstractExternalTest exte
private final class TestSecurityProvider extends SecurityProviderImpl {
public TestSecurityProvider(@Nonnull ConfigurationParameters
configuration) {
super(configuration);
- // TODO: enable once OAK-4104 is commited
- // PrincipalConfiguration principalConfiguration =
getConfiguration(PrincipalConfiguration.class);
- // if (!(principalConfiguration instanceof
CompositePrincipalConfiguration)) {
- // throw new IllegalStateException();
- // } else {
- // PrincipalConfiguration defConfig =
checkNotNull(((CompositePrincipalConfiguration)
principalConfiguration).getDefaultConfig());
- // bindPrincipalConfiguration((new
ExternalPrincipalConfiguration(this)));
- // bindPrincipalConfiguration(defConfig);
- // }
+ PrincipalConfiguration principalConfiguration =
getConfiguration(PrincipalConfiguration.class);
+ if (!(principalConfiguration instanceof
CompositePrincipalConfiguration)) {
+ throw new IllegalStateException();
+ } else {
+ PrincipalConfiguration defConfig =
checkNotNull(((CompositePrincipalConfiguration)
principalConfiguration).getDefaultConfig());
+ bindPrincipalConfiguration(externalPrincipalConfiguration);
+ bindPrincipalConfiguration(defConfig);
+ }
}
}
private final class TestIdentityProvider implements
ExternalIdentityProvider {
- private final int numberofUsers;
+ private final int numberOfUsers;
private final int membershipSize;
- private TestIdentityProvider(int numberofUsers, int membershipSize) {
- this.numberofUsers = numberofUsers;
+ private TestIdentityProvider(int numberOfUsers, int membershipSize) {
+ this.numberOfUsers = numberOfUsers;
this.membershipSize = membershipSize;
}
@@ -219,8 +272,8 @@ abstract class AbstractExternalTest exte
@Nonnull
@Override
public Iterator<ExternalUser> listUsers() {
- Set<ExternalUser> all = new HashSet<>();
- for (long i = 0; i < numberofUsers; i++) {
+ Set<ExternalUser> all = new HashSet<ExternalUser>();
+ for (long i = 0; i < numberOfUsers; i++) {
all.add(new TestUser(i));
}
return all.iterator();
@@ -229,7 +282,7 @@ abstract class AbstractExternalTest exte
@Nonnull
@Override
public Iterator<ExternalGroup> listGroups() {
- Set<ExternalGroup> all = new HashSet<>();
+ Set<ExternalGroup> all = new HashSet<ExternalGroup>();
for (long i = 0; i < membershipSize; i++) {
all.add(new TestGroup(i));
}
@@ -238,7 +291,7 @@ abstract class AbstractExternalTest exte
Iterable<ExternalIdentityRef> getDeclaredGroupRefs(String userId) {
if (userId.charAt(0) == 'u') {
- Set<ExternalIdentityRef> groupRefs = new HashSet<>();
+ Set<ExternalIdentityRef> groupRefs = new
HashSet<ExternalIdentityRef>();
for (long i = 0; i < membershipSize; i++) {
groupRefs.add(new ExternalIdentityRef("g"+ i,
idp.getName()));
}
Modified:
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java?rev=1756792&r1=1743674&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/ExternalLoginTest.java
Thu Aug 18 14:22:59 2016
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.oak.benchmark.authentication.external;
+import java.util.List;
+import javax.annotation.Nonnull;
import javax.jcr.SimpleCredentials;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
@@ -34,8 +36,9 @@ import org.apache.jackrabbit.oak.spi.sec
*/
public class ExternalLoginTest extends AbstractExternalTest {
- public ExternalLoginTest(int numberofUsers, int numberofGroups, long
expTime, boolean dynamicMembership) {
- super(numberofUsers, numberofGroups, expTime, dynamicMembership);
+ public ExternalLoginTest(int numberOfUsers, int numberOfGroups, long
expTime,
+ boolean dynamicMembership, @Nonnull List<String>
autoMembership) {
+ super(numberOfUsers, numberOfGroups, expTime, dynamicMembership,
autoMembership);
}
@Override
Modified:
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncAllExternalUsersTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncAllExternalUsersTest.java?rev=1756792&r1=1743674&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncAllExternalUsersTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncAllExternalUsersTest.java
Thu Aug 18 14:22:59 2016
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.oak.benchmark.authentication.external;
+import java.util.List;
+import javax.annotation.Nonnull;
import javax.security.auth.login.Configuration;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
@@ -30,8 +32,9 @@ public class SyncAllExternalUsersTest ex
private SynchronizationMBean bean;
- public SyncAllExternalUsersTest(int numberofUsers, int membershipSize,
long expTime, boolean dynamicMembership) {
- super(numberofUsers, membershipSize, expTime, dynamicMembership);
+ public SyncAllExternalUsersTest(int numberOfUsers, int membershipSize,
long expTime,
+ boolean dynamicMembership, @Nonnull
List<String> autoMembership) {
+ super(numberOfUsers, membershipSize, expTime, dynamicMembership,
autoMembership);
}
@Override
Modified:
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncExternalUsersTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncExternalUsersTest.java?rev=1756792&r1=1743674&r2=1756792&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncExternalUsersTest.java
(original)
+++
jackrabbit/oak/branches/1.4/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authentication/external/SyncExternalUsersTest.java
Thu Aug 18 14:22:59 2016
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.oak.benchmark.authentication.external;
+import java.util.List;
+import javax.annotation.Nonnull;
import javax.security.auth.login.Configuration;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
@@ -33,9 +35,10 @@ public class SyncExternalUsersTest exten
private final int batchSize;
private SynchronizationMBean bean;
- public SyncExternalUsersTest(int numberofUsers, int membershipSize, long
expTime,
- boolean dynamicMembership, int batchSize) {
- super(numberofUsers, membershipSize, expTime, dynamicMembership);
+ public SyncExternalUsersTest(int numberOfUsers, int membershipSize, long
expTime,
+ boolean dynamicMembership, @Nonnull
List<String> autoMembership,
+ int batchSize) {
+ super(numberOfUsers, membershipSize, expTime, dynamicMembership,
autoMembership);
this.batchSize = batchSize;
}