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 dj...@apache.org on 2016/09/28 14:22:53 UTC
svn commit: r1762669 - in /jackrabbit/oak/branches/1.4: ./
oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/
oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/extern...
Author: dj
Date: Wed Sep 28 14:22:53 2016
New Revision: 1762669
URL: http://svn.apache.org/viewvc?rev=1762669&view=rev
Log:
OAK-4860 : Backport OAK-4301 and OAK-4845
- backport of OAK-4301 (depends on OAK-4048 and OAK-4257)
Added:
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ValidatorNoProtectionTest.java
- copied unchanged from r1755191, jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ValidatorNoProtectionTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ValidatorNotDynamicTest.java
- copied unchanged from r1755191, jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ValidatorNotDynamicTest.java
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/DefaultSyncHandler.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIdentityConstants.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynchronizationMBean.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializer.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorProvider.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/basic/RepExternalIdTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandlerTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializerTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorTest.java
jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java
jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationContext.java
jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java
jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java
jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md
Propchange: jackrabbit/oak/branches/1.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 28 14:22:53 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,1738234,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,1744589,1744670,1744672,1744959,1745038,1745127,1745197,1745336,1745368,1746086,1746117,1746342,1746345,1746408,1746696,1746981,1747198,1747200,1747341-1747342,1747380,1747387,1747406,1747492,1747512,1747654,1748505,1748553,1748722,1748870,1749275,1749350,1749424,1749443,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,1752259,1752273-1752274,1752283,1752292,1752438,1752447-1752448,1752508,1752596,1752616,1752659,1752672,1753262,1753331-1753332,1753335-1753336,1753355,1753444,1754117,1754239,1755157,1756520,1756580,1757119,1757166,1759433,1760340,1760373,1760387,1760661-1760662,1761412,1761444,1761571,1761762,1761787,1761876,1762635
+/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,1738234,1738252,1738775,1738795,1738833,1738950,1738957,1738963,1739712,1739760,1739867,1739894,1739959-1739960,1740114,1740116,1740250,1740333,1740349,1740360,1740625-1740626,1740774,1740837,1740879,1740971,1741016,1741032,1741339,1741343,1742077,1742117,1742125,1742363,1742520,1742888,1742916,1743097,1743172,1743343,1743674,1744265,1744292,1744589,1744670,1744672,1744959,1745038,1745127,1745197,1745336,1745368,1746086,1746117,1746342,1746345,1746408,1746696,1746981,1747198,1747200,1747341-1747342,1747380,1747387,1747406,1747492,1747512,1747654,1748505,1748553,1748722,1748870,1749275,1749350,1749424,1749443,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,1752259,1752273-1752274,1752283,1752292,1752438,1752447-1752448,1752508,1752596,1752616,1752659,1752672,1753262,1753331-1753332,1753335-1753336,1753355,1753444,1754117,1754239,1755157,1755191,1756520,1756580,1757119,1757166,1759433,1760340,1760373,1760387,1760661-1760662,1761412,1761444,1761571,1761762,1761787,1761876,1762635
/jackrabbit/trunk:1345480
Modified: jackrabbit/oak/branches/1.4/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/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandler.java Wed Sep 28 14:22:53 2016
@@ -148,7 +148,7 @@ public class DefaultSyncHandler implemen
while (iter.hasNext()) {
try {
SyncedIdentity id = DefaultSyncContext.createSyncedIdentity(iter.next());
- if (id != null) {
+ if (id != null && id.getExternalIdRef() != null) {
return id;
}
} catch (RepositoryException e) {
Modified: jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIdentityConstants.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/ExternalIdentityConstants.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIdentityConstants.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalIdentityConstants.java Wed Sep 28 14:22:53 2016
@@ -67,4 +67,15 @@ public interface ExternalIdentityConstan
*/
Set<String> RESERVED_PROPERTY_NAMES = ImmutableSet.of(REP_EXTERNAL_ID, REP_EXTERNAL_PRINCIPAL_NAMES);
+ /**
+ * Configuration parameter to enable special protection of external IDs
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/OAK-4301">OAK-4301</a>
+ */
+ String PARAM_PROTECT_EXTERNAL_IDS = "protectExternalId";
+
+ /**
+ * Default value for {@link #PARAM_PROTECT_EXTERNAL_IDS}.
+ */
+ boolean DEFAULT_PROTECT_EXTERNAL_IDS = true;
}
\ 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/jmx/SynchronizationMBean.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/jmx/SynchronizationMBean.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynchronizationMBean.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynchronizationMBean.java Wed Sep 28 14:22:53 2016
@@ -110,7 +110,7 @@ public interface SynchronizationMBean {
/**
* Purges all orphaned users. this is similar to invoke {@link #syncUsers(String[], boolean)} with the list of
- * orphaned users. Note tha this can eb an expensive operation since all potential users need to be examined.
+ * orphaned users. Note tha this can be an expensive operation since all potential users need to be examined.
*
* @return result messages.
*/
Modified: jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializer.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/ExternalIdentityRepositoryInitializer.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializer.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializer.java Wed Sep 28 14:22:53 2016
@@ -60,7 +60,10 @@ class ExternalIdentityRepositoryInitiali
private static final Logger log = LoggerFactory.getLogger(ExternalIdentityRepositoryInitializer.class);
- ExternalIdentityRepositoryInitializer() {
+ private final boolean enforceUniqueIds;
+
+ ExternalIdentityRepositoryInitializer(boolean enforceUniqueIds) {
+ this.enforceUniqueIds = enforceUniqueIds;
}
@Override
@@ -79,6 +82,12 @@ class ExternalIdentityRepositoryInitiali
NodeUtil rootTree = checkNotNull(new NodeUtil(root.getTree("/")));
NodeUtil index = rootTree.getOrAddChild(IndexConstants.INDEX_DEFINITIONS_NAME, JcrConstants.NT_UNSTRUCTURED);
+ if (enforceUniqueIds && !index.hasChild("externalId")) {
+ NodeUtil definition = IndexUtils.createIndexDefinition(index, "externalId", true,
+ new String[]{ExternalIdentityConstants.REP_EXTERNAL_ID}, null);
+ definition.setString("info", "Oak index assuring uniqueness of rep:externalId properties.");
+ }
+
if (!index.hasChild("externalPrincipalNames")) {
NodeUtil definition = IndexUtils.createIndexDefinition(index, "externalPrincipalNames", false,
new String[]{ExternalIdentityConstants.REP_EXTERNAL_PRINCIPAL_NAMES}, null);
Modified: jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorProvider.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/ExternalIdentityValidatorProvider.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorProvider.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorProvider.java Wed Sep 28 14:22:53 2016
@@ -17,9 +17,11 @@
package org.apache.jackrabbit.oak.spi.security.authentication.external.impl.principal;
import java.security.Principal;
+import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
+import com.google.common.collect.ImmutableMap;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
@@ -40,35 +42,60 @@ import org.apache.jackrabbit.oak.spi.sta
*/
class ExternalIdentityValidatorProvider extends ValidatorProvider implements ExternalIdentityConstants {
+ private static final Map<Integer, String> ERROR_MSGS = ImmutableMap.<Integer, String>builder()
+ .put(70, "Attempt to create, modify or remove the system property 'rep:externalPrincipalNames'")
+ .put(71, "Property 'rep:externalPrincipalNames' must be multi-valued of type STRING.")
+ .put(72, "Property 'rep:externalPrincipalNames' requires 'rep:externalId' to be present on the Node.")
+ .put(73, "Property 'rep:externalId' cannot be removed as long as 'rep:externalPrincipalNames' is present.")
+ .put(74, "Attempt to add, modify or remove the system maintained property 'rep:externalId'.")
+ .put(75, "Property 'rep:externalId' may only have a single value of type STRING.").build();
+
private final boolean isSystem;
+ private final boolean protectedExternalIds;
- ExternalIdentityValidatorProvider(@Nonnull Set<Principal> principals) {
+ ExternalIdentityValidatorProvider(@Nonnull Set<Principal> principals, boolean protectExternalIds) {
isSystem = principals.contains(SystemPrincipal.INSTANCE);
+ this.protectedExternalIds = protectExternalIds;
}
- private void checkAddModifyProperties(@Nonnull NodeState parent, @Nonnull String name, @Nonnull PropertyState propertyState) throws CommitFailedException {
- if (REP_EXTERNAL_PRINCIPAL_NAMES.equals(name)) {
- if (!isSystem) {
- throw new CommitFailedException(CommitFailedException.CONSTRAINT, 70, "Attempt to create, modify or remove the system property " + name);
- }
+ private void checkAddModifyProperties(@Nonnull NodeState parent, @Nonnull String name, @Nonnull PropertyState propertyState, boolean isModify) throws CommitFailedException {
+ if (RESERVED_PROPERTY_NAMES.contains(name)) {
Type<?> type = propertyState.getType();
- if (!Type.STRINGS.equals(type) || !propertyState.isArray()) {
- throw new CommitFailedException(CommitFailedException.CONSTRAINT, 71, "Property rep:externalPrincipalNames must be multi-valued of type STRING.");
+ if (REP_EXTERNAL_PRINCIPAL_NAMES.equals(name)) {
+ if (!isSystem) {
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 70, ERROR_MSGS.get(70));
+ }
+ if (!Type.STRINGS.equals(type) || !propertyState.isArray()) {
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 71, ERROR_MSGS.get(71));
+ }
+ if (!parent.hasProperty(REP_EXTERNAL_ID)) {
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 72, ERROR_MSGS.get(72));
+ }
}
- if (!parent.hasProperty(REP_EXTERNAL_ID)) {
- throw new CommitFailedException(CommitFailedException.CONSTRAINT, 72, "Property rep:externalPrincipalNames requires rep:externalId to be present on the Node.");
+ if (REP_EXTERNAL_ID.equals(name) && protectedExternalIds) {
+ if (isModify && !isSystem) {
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 74, ERROR_MSGS.get(74));
+ }
+ if (!Type.STRING.equals(type) || propertyState.isArray()) {
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 75, ERROR_MSGS.get(75));
+ }
}
}
}
private void checkRemoveProperties(@Nonnull NodeState parent, @Nonnull String name) throws CommitFailedException {
if (RESERVED_PROPERTY_NAMES.contains(name)) {
- if (REP_EXTERNAL_ID.equals(name) && parent.hasProperty(REP_EXTERNAL_PRINCIPAL_NAMES)) {
- throw new CommitFailedException(CommitFailedException.CONSTRAINT, 73, "Property rep:externalId cannot be removed as long as rep:externalPrincipalNames is present.");
+ if (REP_EXTERNAL_ID.equals(name)) {
+ if (parent.hasProperty(REP_EXTERNAL_PRINCIPAL_NAMES)) {
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 73, ERROR_MSGS.get(73));
+ }
+ if (protectedExternalIds && !isSystem) {
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 74, ERROR_MSGS.get(74));
+ }
}
if (REP_EXTERNAL_PRINCIPAL_NAMES.equals(name) && !isSystem) {
- throw new CommitFailedException(CommitFailedException.CONSTRAINT, 70, "Attempt to create, modify or remove the system property " + name);
+ throw new CommitFailedException(CommitFailedException.CONSTRAINT, 70, ERROR_MSGS.get(70));
}
}
}
@@ -76,25 +103,27 @@ class ExternalIdentityValidatorProvider
@Override
protected Validator getRootValidator(@Nonnull NodeState before, @Nonnull NodeState after,
@Nonnull CommitInfo info) {
- return new ExternalIdentityValidator(after);
+ return new ExternalIdentityValidator(after, true);
}
private final class ExternalIdentityValidator extends DefaultValidator {
private final NodeState parent;
+ private final boolean modifiedParent;
- private ExternalIdentityValidator(@Nonnull NodeState parent) {
+ private ExternalIdentityValidator(@Nonnull NodeState parent, boolean modifiedParent) {
this.parent = parent;
+ this.modifiedParent = modifiedParent;
}
@Override
public void propertyAdded(PropertyState after) throws CommitFailedException {
- checkAddModifyProperties(parent, after.getName(), after);
+ checkAddModifyProperties(parent, after.getName(), after, modifiedParent);
}
@Override
public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
- checkAddModifyProperties(parent, before.getName(), after);
+ checkAddModifyProperties(parent, before.getName(), after, modifiedParent);
}
@Override
@@ -103,17 +132,17 @@ class ExternalIdentityValidatorProvider
}
@Override
- public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
- return new ExternalIdentityValidator(after);
+ public Validator childNodeAdded(String name, NodeState after) {
+ return new ExternalIdentityValidator(after, false);
}
@Override
- public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
- return new ExternalIdentityValidator(after);
+ public Validator childNodeChanged(String name, NodeState before, NodeState after) {
+ return new ExternalIdentityValidator(after, true);
}
@Override
- public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
+ public Validator childNodeDeleted(String name, NodeState before) {
// removal of the parent node containing a reserved property must be possible
return null;
}
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=1762669&r1=1762668&r2=1762669&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 Wed Sep 28 14:22:53 2016
@@ -37,6 +37,8 @@ import com.google.common.collect.Iterato
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.oak.api.Root;
@@ -51,6 +53,7 @@ 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.ExternalIdentityConstants;
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;
@@ -80,6 +83,12 @@ import org.slf4j.LoggerFactory;
immediate = true
)
@Service({PrincipalConfiguration.class, SecurityConfiguration.class})
+@Properties({
+ @Property(name = ExternalIdentityConstants.PARAM_PROTECT_EXTERNAL_IDS,
+ label = "External Identity Protection",
+ description = "If disabled rep:externalId properties won't be properly protected (backwards compatible behavior). NOTE: for security reasons it is strongly recommend to keep the protection enabled!",
+ boolValue = ExternalIdentityConstants.DEFAULT_PROTECT_EXTERNAL_IDS)
+})
public class ExternalPrincipalConfiguration extends ConfigurationBase implements PrincipalConfiguration {
private static final Logger log = LoggerFactory.getLogger(ExternalPrincipalConfiguration.class);
@@ -124,13 +133,13 @@ public class ExternalPrincipalConfigurat
@Nonnull
@Override
public RepositoryInitializer getRepositoryInitializer() {
- return new ExternalIdentityRepositoryInitializer();
+ return new ExternalIdentityRepositoryInitializer(protectedExternalIds());
}
@Nonnull
@Override
public List<? extends ValidatorProvider> getValidators(@Nonnull String workspaceName, @Nonnull Set<Principal> principals, @Nonnull MoveTracker moveTracker) {
- return ImmutableList.of(new ExternalIdentityValidatorProvider(principals));
+ return ImmutableList.of(new ExternalIdentityValidatorProvider(principals, protectedExternalIds()));
}
@Nonnull
@@ -170,6 +179,10 @@ public class ExternalPrincipalConfigurat
return syncConfigTracker != null && syncConfigTracker.isEnabled;
}
+ private boolean protectedExternalIds() {
+ return getParameters().getConfigValue(ExternalIdentityConstants.PARAM_PROTECT_EXTERNAL_IDS, ExternalIdentityConstants.DEFAULT_PROTECT_EXTERNAL_IDS);
+ }
+
/**
* Implementation of the {@code PrincipalProvider} interface that never
* returns any principals.
Modified: jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/RepExternalIdTest.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/basic/RepExternalIdTest.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/RepExternalIdTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/RepExternalIdTest.java Wed Sep 28 14:22:53 2016
@@ -19,7 +19,10 @@ package org.apache.jackrabbit.oak.spi.se
import javax.annotation.Nonnull;
import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.authentication.external.AbstractExternalAuthTest;
@@ -34,16 +37,21 @@ import static org.junit.Assert.assertFal
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
public class RepExternalIdTest extends AbstractExternalAuthTest {
+ private Root r;
+ private UserManager userManager;
private DefaultSyncContext syncCtx;
@Before
public void before() throws Exception {
super.before();
- syncCtx = new DefaultSyncContext(syncConfig, idp, getUserManager(root), getValueFactory());
+ r = getSystemRoot();
+ userManager = getUserManager(r);
+ syncCtx = new DefaultSyncContext(syncConfig, idp, getUserManager(r), getValueFactory(r));
}
@Override
@@ -61,10 +69,10 @@ public class RepExternalIdTest extends A
assertNotNull(si);
- Authorizable authorizable = getUserManager(root).getAuthorizable(si.getId());
+ Authorizable authorizable = userManager.getAuthorizable(si.getId());
assertNotNull(authorizable);
- Tree userTree = root.getTree(authorizable.getPath());
+ Tree userTree = r.getTree(authorizable.getPath());
assertTrue(userTree.hasProperty(DefaultSyncContext.REP_EXTERNAL_ID));
PropertyState ps = userTree.getProperty(DefaultSyncContext.REP_EXTERNAL_ID);
@@ -87,4 +95,59 @@ public class RepExternalIdTest extends A
assertRepExternalId(res);
}
+
+ @Test
+ public void testUniqueConstraint() throws Exception {
+ SyncResult res = syncCtx.sync(idp.getUser(USER_ID));
+
+ try {
+ Tree t = r.getTree(getTestUser().getPath());
+ t.setProperty(DefaultSyncContext.REP_EXTERNAL_ID, res.getIdentity().getExternalIdRef().getString());
+ r.commit();
+ fail("Duplicate value for rep:externalId must be detected in the default setup.");
+ } catch (CommitFailedException e) {
+ // success: verify nature of the exception
+ assertTrue(e.isConstraintViolation());
+ assertEquals(30, e.getCode());
+ } finally {
+ r.refresh();
+ }
+ }
+
+ @Test
+ public void testUniqueConstraintSubsequentCommit() throws Exception {
+ SyncResult res = syncCtx.sync(idp.getUser(USER_ID));
+ r.commit();
+
+ try {
+ Tree t = r.getTree(getTestUser().getPath());
+ t.setProperty(DefaultSyncContext.REP_EXTERNAL_ID, res.getIdentity().getExternalIdRef().getString());
+ r.commit();
+ fail("Duplicate value for rep:externalId must be detected in the default setup.");
+ } catch (CommitFailedException e) {
+ // success: verify nature of the exception
+ assertTrue(e.isConstraintViolation());
+ assertEquals(30, e.getCode());
+ } finally {
+ r.refresh();
+ }
+ }
+
+ @Test
+ public void testUniqueConstraintNonUserNode() throws Exception {
+ try {
+ SyncResult res = syncCtx.sync(idp.getUser(USER_ID));
+ Tree nonUserTree = r.getTree("/");
+ nonUserTree.setProperty(DefaultSyncContext.REP_EXTERNAL_ID, res.getIdentity().getExternalIdRef().getString());
+ r.commit();
+
+ fail("Duplicate value for rep:externalId must be detected in the default setup.");
+ } catch (CommitFailedException e) {
+ // success: verify nature of the exception
+ assertTrue(e.isConstraintViolation());
+ assertEquals(30, e.getCode());
+ } finally {
+ r.refresh();
+ }
+ }
}
\ 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/impl/DefaultSyncHandlerTest.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/DefaultSyncHandlerTest.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandlerTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncHandlerTest.java Wed Sep 28 14:22:53 2016
@@ -26,8 +26,7 @@ import javax.jcr.Value;
import com.google.common.collect.Sets;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.oak.namepath.NamePathMapper;
-import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
+import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProvider;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityRef;
@@ -50,6 +49,7 @@ import static org.junit.Assert.assertNot
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* DefaultSyncHandlerTest
@@ -87,6 +87,8 @@ public class DefaultSyncHandlerTest exte
private void sync(@Nonnull String id, boolean isGroup) throws Exception {
SyncContext ctx = syncHandler.createContext(idp, userManager, getValueFactory());
ExternalIdentity exIdentity = (isGroup) ? idp.getGroup(id) : idp.getUser(id);
+ assertNotNull(exIdentity);
+
SyncResult res = ctx.sync(exIdentity);
assertSame(SyncResult.Status.ADD, res.getStatus());
root.commit();
@@ -99,7 +101,7 @@ public class DefaultSyncHandlerTest exte
@Test
public void testCreateContext() throws Exception {
- SyncContext ctx = syncHandler.createContext(idp, userManager, new ValueFactoryImpl(root, NamePathMapper.DEFAULT));
+ SyncContext ctx = syncHandler.createContext(idp, userManager, getValueFactory());
assertTrue(ctx instanceof DefaultSyncContext);
}
@@ -123,7 +125,9 @@ public class DefaultSyncHandlerTest exte
SyncedIdentity id = syncHandler.findIdentity(userManager, USER_ID);
assertNotNull("known authorizable should exist", id);
- assertEquals("external user should have correct external ref.idp", idp.getName(), id.getExternalIdRef().getProviderName());
+ ExternalIdentityRef ref = id.getExternalIdRef();
+ assertNotNull(ref);
+ assertEquals("external user should have correct external ref.idp", idp.getName(), ref.getProviderName());
assertEquals("external user should have correct external ref.id", USER_ID, id.getExternalIdRef().getId());
}
@@ -144,12 +148,15 @@ public class DefaultSyncHandlerTest exte
public void testFindIdentityWithRemovedExternalId() throws Exception {
sync(USER_ID, false);
- // NOTE: this is only possible as long the rep:externalId property is not protected
+ // NOTE: use system-root to remove the protected rep:externalId property (since Oak 1.5.8)
Authorizable authorizable = userManager.getAuthorizable(USER_ID);
- authorizable.removeProperty(DefaultSyncContext.REP_EXTERNAL_ID);
- root.commit();
+ Root systemRoot = getSystemRoot();
+ systemRoot.getTree(authorizable.getPath()).removeProperty(DefaultSyncContext.REP_EXTERNAL_ID);
+ systemRoot.commit();
+ root.refresh();
SyncedIdentity si = syncHandler.findIdentity(userManager, USER_ID);
+ assertNotNull(si);
assertNull(si.getExternalIdRef());
}
@@ -219,9 +226,9 @@ public class DefaultSyncHandlerTest exte
@Test
public void testListIdentitiesBeforeSync() throws Exception {
Iterator<SyncedIdentity> identities = syncHandler.listIdentities(userManager);
- while (identities.hasNext()) {
+ if (identities.hasNext()) {
SyncedIdentity si = identities.next();
- assertNull(si.getExternalIdRef());
+ fail("Sync handler returned unexpected identity: " + si);
}
}
@@ -242,7 +249,7 @@ public class DefaultSyncHandlerTest exte
expected.remove(si.getId());
assertNotNull(si.getExternalIdRef());
} else {
- assertNull(si.getExternalIdRef());
+ fail("Sync handler returned unexpected identity: " + si);
}
}
assertTrue(expected.isEmpty());
Modified: jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializerTest.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/ExternalIdentityRepositoryInitializerTest.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializerTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityRepositoryInitializerTest.java Wed Sep 28 14:22:53 2016
@@ -32,7 +32,16 @@ import static org.junit.Assert.assertTru
public class ExternalIdentityRepositoryInitializerTest extends AbstractExternalAuthTest {
@Test
- public void testIndexDefinitions() throws Exception {
+ public void testExternalIdIndexDefinition() throws Exception {
+ Tree oakIndex = root.getTree('/' + IndexConstants.INDEX_DEFINITIONS_NAME);
+ assertTrue(oakIndex.exists());
+
+ Tree externalIdIndex = oakIndex.getChild("externalId");
+ assertIndexDefinition(externalIdIndex, ExternalIdentityConstants.REP_EXTERNAL_ID, true);
+ }
+
+ @Test
+ public void testPrincipalNamesIndexDefinition() throws Exception {
Tree oakIndex = root.getTree('/' + IndexConstants.INDEX_DEFINITIONS_NAME);
assertTrue(oakIndex.exists());
Modified: jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorTest.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/ExternalIdentityValidatorTest.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalIdentityValidatorTest.java Wed Sep 28 14:22:53 2016
@@ -22,11 +22,13 @@ import com.google.common.collect.Immutab
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalLoginModuleTestBase;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.TestIdentityProvider;
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.util.NodeUtil;
@@ -54,32 +56,19 @@ public class ExternalIdentityValidatorTe
Authorizable a = getUserManager(root).getAuthorizable(USER_ID);
assertNotNull(a);
- assertTrue(a.hasProperty(ExternalIdentityConstants.REP_EXTERNAL_PRINCIPAL_NAMES));
+ assertEquals(isDynamic(), a.hasProperty(ExternalIdentityConstants.REP_EXTERNAL_PRINCIPAL_NAMES));
externalUserPath = a.getPath();
}
@Override
protected DefaultSyncConfig createSyncConfig() {
DefaultSyncConfig config = super.createSyncConfig();
- config.user().setDynamicMembership(true);
+ config.user().setDynamicMembership(isDynamic());
return config;
}
- @Test
- public void testRemoveRepExternalIdAsSystem() throws Exception {
- Root systemRoot = getSystemRoot();
- try {
- NodeUtil n = new NodeUtil(systemRoot.getTree(externalUserPath));
-
- n.removeProperty(ExternalIdentityConstants.REP_EXTERNAL_ID);
- systemRoot.commit();
- fail("Removing rep:externalId is not allowed if rep:externalPrincipalNames is present.");
- } catch (CommitFailedException e) {
- // success
- assertEquals(73, e.getCode());
- } finally {
- systemRoot.refresh();
- }
+ protected boolean isDynamic() {
+ return true;
}
@Test
@@ -213,4 +202,174 @@ public class ExternalIdentityValidatorTe
systemRoot.refresh();
}
}
+
+ @Test
+ public void testRepExternalIdMultiple() throws Exception {
+ Root systemRoot = getSystemRoot();
+ try {
+ NodeUtil n = new NodeUtil(systemRoot.getTree(testUserPath));
+ n.setStrings(ExternalIdentityConstants.REP_EXTERNAL_ID, "id", "id2");
+ systemRoot.commit();
+ fail("Creating rep:externalId as multiple STRING property must be detected.");
+ } catch (CommitFailedException e) {
+ // success
+ assertEquals(75, e.getCode());
+ } finally {
+ systemRoot.refresh();
+ }
+ }
+
+ @Test
+ public void testRepExternalIdType() throws Exception {
+ Root systemRoot = getSystemRoot();
+ Tree userTree = systemRoot.getTree(testUserPath);
+
+ java.util.Map<Type, Object> valMap = ImmutableMap.<Type, Object>of(
+ Type.BOOLEAN, Boolean.TRUE,
+ Type.LONG, new Long(1234),
+ Type.NAME, "id"
+ );
+ for (Type t : valMap.keySet()) {
+ Object val = valMap.get(t);
+ try {
+ userTree.setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, val, t);
+ systemRoot.commit();
+ fail("Creating rep:externalId with type "+t+" must be detected.");
+ } catch (CommitFailedException e) {
+ // success
+ assertEquals(75, e.getCode());
+ } finally {
+ systemRoot.refresh();
+ }
+ }
+ }
+
+ @Test
+ public void testCreateUserWithRepExternalId() throws Exception {
+ User u = getUserManager(root).createUser(TestIdentityProvider.ID_SECOND_USER, null);
+ root.getTree(u.getPath()).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, TestIdentityProvider.ID_SECOND_USER);
+ root.commit();
+ }
+
+ @Test
+ public void testCreateUserWithRepExternalIdAsSystem() throws Exception {
+ Root systemRoot = getSystemRoot();
+ User u = getUserManager(systemRoot).createUser(TestIdentityProvider.ID_SECOND_USER, null);
+ systemRoot.getTree(u.getPath()).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, TestIdentityProvider.ID_SECOND_USER);
+ systemRoot.commit();
+ }
+
+ @Test
+ public void testAddRepExternalId() throws Exception {
+ try {
+ root.getTree(testUserPath).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, "id");
+ root.commit();
+ fail("Adding rep:externalId must be detected in the default setup.");
+ } catch (CommitFailedException e) {
+ // success: verify nature of the exception
+ assertTrue(e.isConstraintViolation());
+ assertEquals(74, e.getCode());
+ }
+
+ }
+
+ @Test
+ public void testAddRepExternalIdAsSystem() throws Exception {
+ Root systemRoot = getSystemRoot();
+ systemRoot.getTree(testUserPath).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, "id");
+ systemRoot.commit();
+ }
+
+ @Test
+ public void testModifyRepExternalId() throws Exception {
+ try {
+ root.getTree(externalUserPath).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, "anotherValue");
+ root.commit();
+
+ fail("Modification of rep:externalId must be detected in the default setup.");
+ } catch (CommitFailedException e) {
+ // success: verify nature of the exception
+ assertTrue(e.isConstraintViolation());
+ assertEquals(74, e.getCode());
+ }
+ }
+
+ @Test
+ public void testModifyRepExternalIdAsSystem() throws Exception {
+ Root systemRoot = getSystemRoot();
+ systemRoot.getTree(externalUserPath).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, "anotherValue");
+ systemRoot.commit();
+ }
+
+ @Test
+ public void testRemoveRepExternalId() throws Exception {
+ try {
+ root.getTree(externalUserPath).removeProperty(ExternalIdentityConstants.REP_EXTERNAL_ID);
+ root.commit();
+
+ fail("Removal of rep:externalId must be detected in the default setup.");
+ } catch (CommitFailedException e) {
+ // success: verify nature of the exception
+ assertTrue(e.isConstraintViolation());
+ assertEquals(73, e.getCode());
+ }
+ }
+
+ @Test
+ public void testRemoveRepExternalIdAsSystem() throws Exception {
+ Root systemRoot = getSystemRoot();
+ try {
+ NodeUtil n = new NodeUtil(systemRoot.getTree(externalUserPath));
+
+ n.removeProperty(ExternalIdentityConstants.REP_EXTERNAL_ID);
+ systemRoot.commit();
+ fail("Removing rep:externalId is not allowed if rep:externalPrincipalNames is present.");
+ } catch (CommitFailedException e) {
+ // success
+ assertEquals(73, e.getCode());
+ } finally {
+ systemRoot.refresh();
+ }
+ }
+
+ @Test
+ public void testRemoveRepExternalIdWithoutPrincipalNames() throws Exception {
+ Root systemRoot = getSystemRoot();
+ systemRoot.getTree(testUserPath).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, "id");
+ systemRoot.commit();
+ root.refresh();
+
+ try {
+ root.getTree(testUserPath).removeProperty(ExternalIdentityConstants.REP_EXTERNAL_ID);
+ root.commit();
+
+ fail("Removal of rep:externalId must be detected in the default setup.");
+ } catch (CommitFailedException e) {
+ // success: verify nature of the exception
+ assertTrue(e.isConstraintViolation());
+ assertEquals(74, e.getCode());
+ }
+ }
+
+ @Test
+ public void testRemoveRepExternalIdWithoutPrincipalNamesAsSystem() throws Exception {
+ Root systemRoot = getSystemRoot();
+ systemRoot.getTree(testUserPath).setProperty(ExternalIdentityConstants.REP_EXTERNAL_ID, "id");
+ systemRoot.commit();
+
+ systemRoot.getTree(testUserPath).removeProperty(ExternalIdentityConstants.REP_EXTERNAL_ID);
+ systemRoot.commit();
+ }
+
+ @Test
+ public void testRemoveExternalUser() throws Exception {
+ getUserManager(root).getAuthorizable(USER_ID).remove();
+ root.commit();
+ }
+
+ @Test
+ public void testRemoveExternalUserTree() throws Exception {
+ root.getTree(externalUserPath).remove();
+ root.commit();
+ }
}
\ 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/impl/principal/ExternalPrincipalConfigurationTest.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/ExternalPrincipalConfigurationTest.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfigurationTest.java Wed Sep 28 14:22:53 2016
@@ -34,6 +34,7 @@ import org.apache.jackrabbit.oak.namepat
import org.apache.jackrabbit.oak.spi.commit.MoveTracker;
import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
import org.apache.jackrabbit.oak.spi.security.Context;
import org.apache.jackrabbit.oak.spi.security.authentication.external.AbstractExternalAuthTest;
import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProvider;
@@ -45,6 +46,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncContext;
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.ExternalIdentityConstants;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
@@ -157,6 +159,24 @@ public class ExternalPrincipalConfigurat
assertFalse(validatorProviders.isEmpty());
assertEquals(1, validatorProviders.size());
assertTrue(validatorProviders.get(0) instanceof ExternalIdentityValidatorProvider);
+
+ enable();
+
+ validatorProviders = principalConfiguration.getValidators(cs.getWorkspaceName(), cs.getAuthInfo().getPrincipals(), new MoveTracker());
+ assertFalse(validatorProviders.isEmpty());
+ assertEquals(1, validatorProviders.size());
+ assertTrue(validatorProviders.get(0) instanceof ExternalIdentityValidatorProvider);
+ }
+
+ @Test
+ public void testGetValidatorsOmitIdProtection() throws Exception {
+ principalConfiguration.setParameters(ConfigurationParameters.of(ExternalIdentityConstants.PARAM_PROTECT_EXTERNAL_IDS, false));
+ ContentSession cs = root.getContentSession();
+
+ List<? extends ValidatorProvider> validatorProviders = principalConfiguration.getValidators(cs.getWorkspaceName(), cs.getAuthInfo().getPrincipals(), new MoveTracker());
+ assertFalse(validatorProviders.isEmpty());
+ assertEquals(1, validatorProviders.size());
+ assertTrue(validatorProviders.get(0) instanceof ExternalIdentityValidatorProvider);
enable();
Modified: jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationContext.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationContext.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationContext.java Wed Sep 28 14:22:53 2016
@@ -61,7 +61,7 @@ final class AuthorizationContext impleme
@Override
public boolean definesTree(@Nonnull Tree tree) {
String ntName = TreeUtil.getPrimaryTypeName(tree);
- return isNtName(ntName);
+ return ntName != null && isNtName(ntName);
}
@Override
Modified: jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java Wed Sep 28 14:22:53 2016
@@ -115,8 +115,9 @@ public class CompositeAuthorizationConfi
default:
List<RestrictionProvider> rps = new ArrayList<RestrictionProvider>(configurations.size());
for (AuthorizationConfiguration c : configurations) {
- if (RestrictionProvider.EMPTY != c) {
- rps.add(c.getRestrictionProvider());
+ RestrictionProvider rp = c.getRestrictionProvider();
+ if (RestrictionProvider.EMPTY != rp) {
+ rps.add(rp);
}
}
return CompositeRestrictionProvider.newInstance(rps);
Modified: jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java Wed Sep 28 14:22:53 2016
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.securi
import java.security.Principal;
import java.util.Collections;
+import javax.annotation.Nonnull;
import javax.jcr.RepositoryException;
import javax.jcr.security.AccessControlManager;
@@ -34,6 +35,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.junit.Test;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -79,7 +81,7 @@ public class CompositeAuthorizationConfi
}
@Test
- public void testSlingRestrictionProvider() {
+ public void testSingleRestrictionProvider() {
CompositeAuthorizationConfiguration cc = getCompositeConfiguration(new AuthorizationConfigurationImpl(getSecurityProvider()));
RestrictionProvider rp = cc.getRestrictionProvider();
@@ -136,4 +138,37 @@ public class CompositeAuthorizationConfi
RestrictionProvider rp = cc.getRestrictionProvider();
assertTrue(rp instanceof CompositeRestrictionProvider);
}
+
+ @Test
+ public void testMultipleWithEmptyRestrictionProvider() {
+ CompositeAuthorizationConfiguration cc = getCompositeConfiguration(
+ new AuthorizationConfigurationImpl(getSecurityProvider()),
+ new OpenAuthorizationConfiguration() {
+ @Nonnull
+ @Override
+ public RestrictionProvider getRestrictionProvider() {
+ return RestrictionProvider.EMPTY;
+ }
+ });
+
+ RestrictionProvider rp = cc.getRestrictionProvider();
+ assertFalse(rp instanceof CompositeRestrictionProvider);
+ assertNotSame(RestrictionProvider.EMPTY, rp);
+ }
+
+ @Test
+ public void testOnlyEmptyRestrictionProvider() {
+ AuthorizationConfiguration ac = new OpenAuthorizationConfiguration() {
+ @Nonnull
+ @Override
+ public RestrictionProvider getRestrictionProvider() {
+ return RestrictionProvider.EMPTY;
+ }
+ };
+ CompositeAuthorizationConfiguration cc = getCompositeConfiguration(ac, ac);
+
+ RestrictionProvider rp = cc.getRestrictionProvider();
+ assertFalse(rp instanceof CompositeRestrictionProvider);
+ assertSame(RestrictionProvider.EMPTY, rp);
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md?rev=1762669&r1=1762668&r2=1762669&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md (original)
+++ jackrabbit/oak/branches/1.4/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md Wed Sep 28 14:22:53 2016
@@ -50,6 +50,12 @@ the authorizables can later on be identi
- `rep:externalId` : This allows to identify the external users, know the associated IDP and distinguish them from others.
- `rep:lastSynced` : Sync timestamp to mark the external user/group valid for the configurable time (to reduce expensive syncing). Once expired, they will be validated against the 3rd party system again.
+NOTE: Since Oak 1.5.8 the system-maintained property `rep:externalId` is
+protected and can not be altered using regular JCR and Jackrabbit
+API, irrespective of the permission setup of the editing session. For
+backwards compatibility this protection can be turned off. See [OAK-4301]
+for further details.
+
The [DefaultSyncContext] is exported as part of the 'basic' package space and
may be used to provide custom implementations.
@@ -106,6 +112,8 @@ will re-create the `rep:externalPrincipa
<a name="validation"/>
#### Validation
+##### rep:externalPrincipalNames
+
As of Oak 1.5.3 a dedicated `Validator` implementation asserts that the protected,
system-maintained property `rep:externalPrincipalNames` is only written by the
internal system session.
@@ -119,10 +127,21 @@ with external user/group accounts.
| Code | Message |
|-------------------|----------------------------------------------------------|
-| 0070 | Attempt to create, modify or remove the system property rep:externalPrincipalNames |
-| 0071 | Attempt to write rep:externalPrincipalNames with a type other than Type.STRINGS |
-| 0072 | Property rep:externalPrincipalNames requires rep:externalId to be present on the Node. |
-| 0073 | Property rep:externalId cannot be removed if rep:externalPrincipalNames is present. |
+| 0070 | Attempt to create, modify or remove the system property 'rep:externalPrincipalNames' |
+| 0071 | Attempt to write 'rep:externalPrincipalNames' with a type other than Type.STRINGS |
+| 0072 | Property 'rep:externalPrincipalNames' requires 'rep:externalId' to be present on the Node. |
+| 0073 | Property 'rep:externalId' cannot be removed if 'rep:externalPrincipalNames' is present. |
+
+##### rep:externalId
+
+If protection of the `rep:externalId` property is enabled (since Oak 1.5.8) the
+validator performs the following checks:
+
+| Code | Message |
+|-------------------|----------------------------------------------------------|
+| 0074 | Attempt to add, modify or remove the system maintained property 'rep:externalId'. |
+| 0075 | Property 'rep:externalId' may only have a single value of type STRING. |
+
<a name="configuration"/>
### Configuration
@@ -160,6 +179,13 @@ as additional value to the `requiredServ
See section [Introduction to Oak Security](../introduction.html) for further details on the `SecurityProviderRegistration`.
+The `ExternalPrincipalConfiguration` defines the following configuration options:
+
+| Name | Property | Description |
+|------------------------------|-------------------------------|------------------------------------------|
+| External Identity Protection | `protectExternalId` | Enables protection of the system maintained `rep:externalId` properties |
+| | | |
+
<!-- references -->
[SyncContext]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncContext.html
[DefaultSyncContext]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContext.html
@@ -171,4 +197,5 @@ See section [Introduction to Oak Securit
[ExternalPrincipalConfiguration]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/ExternalPrincipalConfiguration.html
[DynamicSyncContext]: /oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/principal/DynamicSyncContext.html
[OAK-4101]: https://issues.apache.org/jira/browse/OAK-4101
-[OAK-2687]: https://issues.apache.org/jira/browse/OAK-2687
\ No newline at end of file
+[OAK-2687]: https://issues.apache.org/jira/browse/OAK-2687
+[OAK-4301]: https://issues.apache.org/jira/browse/OAK-4301
\ No newline at end of file