You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by kd...@apache.org on 2019/02/12 18:43:42 UTC
[nifi-registry] branch master updated: NIFIREG-217 Adding identity
and group transforms
This is an automated email from the ASF dual-hosted git repository.
kdoran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git
The following commit(s) were added to refs/heads/master by this push:
new ecce44e NIFIREG-217 Adding identity and group transforms
ecce44e is described below
commit ecce44e587dc9e2b2fa2cbaf4b13702623577fa3
Author: Bryan Bende <bb...@apache.org>
AuthorDate: Thu Feb 7 14:32:08 2019 -0500
NIFIREG-217 Adding identity and group transforms
This closses #154.
Signed-off-by: Kevin Doran <kd...@apache.org>
---
.../ldap/tenants/LdapUserGroupProvider.java | 4 +-
.../ldap/tenants/LdapUserGroupProviderTest.java | 43 +++++++++++
.../properties/NiFiRegistryProperties.java | 4 ++
.../registry/properties/util/IdentityMapping.java | 17 +++++
.../properties/util/IdentityMappingUtil.java | 83 +++++++++++++++++++---
.../main/resources/conf/nifi-registry.properties | 12 ++++
6 files changed, 153 insertions(+), 10 deletions(-)
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java
index 984c890..5a892be 100644
--- a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java
@@ -117,6 +117,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
public static final String PROP_SYNC_INTERVAL = "Sync Interval";
private List<IdentityMapping> identityMappings;
+ private List<IdentityMapping> groupMappings;
private NiFiRegistryProperties properties;
private ScheduledExecutorService ldapSync;
@@ -350,6 +351,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
// extract the identity mappings from nifi-registry.properties if any are provided
identityMappings = Collections.unmodifiableList(IdentityMappingUtil.getIdentityMappings(properties));
+ groupMappings = Collections.unmodifiableList(IdentityMappingUtil.getGroupMappings(properties));
// set the base environment is necessary
if (!baseEnvironment.isEmpty()) {
@@ -704,7 +706,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
}
}
- return name;
+ return IdentityMappingUtil.mapIdentity(name, groupMappings);
}
private String getReferencedGroupValue(final DirContextOperations ctx) {
diff --git a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProviderTest.java b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProviderTest.java
index 9a408b2..94d2031 100644
--- a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProviderTest.java
+++ b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProviderTest.java
@@ -507,6 +507,49 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
assertNotNull(ldapUserGroupProvider.getUserByIdentity("User 1,ou=users"));
}
+ @Test
+ public void testUserIdentityMappingWithTransforms() throws Exception {
+ final Properties props = new Properties();
+ props.setProperty("nifi.registry.security.identity.mapping.pattern.dn1", "^cn=(.*?),ou=(.*?),o=(.*?)$");
+ props.setProperty("nifi.registry.security.identity.mapping.value.dn1", "$1");
+ props.setProperty("nifi.registry.security.identity.mapping.transform.dn1", "UPPER");
+
+ final NiFiRegistryProperties properties = getNiFiProperties(props);
+ ldapUserGroupProvider.setNiFiProperties(properties);
+
+ final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
+ when(configurationContext.getProperty(PROP_USER_SEARCH_FILTER)).thenReturn(new StandardPropertyValue("(uid=user1)"));
+ ldapUserGroupProvider.onConfigured(configurationContext);
+
+ assertEquals(1, ldapUserGroupProvider.getUsers().size());
+ assertNotNull(ldapUserGroupProvider.getUserByIdentity("USER 1"));
+ }
+
+ @Test
+ public void testUserIdentityAndGroupMappingWithTransforms() throws Exception {
+ final Properties props = new Properties();
+ props.setProperty("nifi.registry.security.identity.mapping.pattern.dn1", "^cn=(.*?),ou=(.*?),o=(.*?)$");
+ props.setProperty("nifi.registry.security.identity.mapping.value.dn1", "$1");
+ props.setProperty("nifi.registry.security.identity.mapping.transform.dn1", "UPPER");
+ props.setProperty("nifi.registry.security.group.mapping.pattern.dn1", "^cn=(.*?),ou=(.*?),o=(.*?)$");
+ props.setProperty("nifi.registry.security.group.mapping.value.dn1", "$1");
+ props.setProperty("nifi.registry.security.group.mapping.transform.dn1", "UPPER");
+
+ final NiFiRegistryProperties properties = getNiFiProperties(props);
+ ldapUserGroupProvider.setNiFiProperties(properties);
+
+ final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
+ when(configurationContext.getProperty(PROP_USER_SEARCH_FILTER)).thenReturn(new StandardPropertyValue("(uid=user1)"));
+ when(configurationContext.getProperty(PROP_GROUP_SEARCH_FILTER)).thenReturn(new StandardPropertyValue("(cn=admins)"));
+ ldapUserGroupProvider.onConfigured(configurationContext);
+
+ assertEquals(1, ldapUserGroupProvider.getUsers().size());
+ assertNotNull(ldapUserGroupProvider.getUserByIdentity("USER 1"));
+
+ assertEquals(1, ldapUserGroupProvider.getGroups().size());
+ assertEquals("ADMINS", ldapUserGroupProvider.getGroups().iterator().next().getName());
+ }
+
@Test(expected = SecurityProviderCreationException.class)
public void testReferencedGroupAttributeWithoutGroupSearchBase() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("ou=users-2,o=nifi", null);
diff --git a/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java b/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
index 89a8e60..aa4d19e 100644
--- a/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
+++ b/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
@@ -53,6 +53,10 @@ public class NiFiRegistryProperties extends Properties {
public static final String SECURITY_IDENTITY_PROVIDER = "nifi.registry.security.identity.provider";
public static final String SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX = "nifi.registry.security.identity.mapping.pattern.";
public static final String SECURITY_IDENTITY_MAPPING_VALUE_PREFIX = "nifi.registry.security.identity.mapping.value.";
+ public static final String SECURITY_IDENTITY_MAPPING_TRANSFORM_PREFIX = "nifi.registry.security.identity.mapping.transform.";
+ public static final String SECURITY_GROUP_MAPPING_PATTERN_PREFIX = "nifi.registry.security.group.mapping.pattern.";
+ public static final String SECURITY_GROUP_MAPPING_VALUE_PREFIX = "nifi.registry.security.group.mapping.value.";
+ public static final String SECURITY_GROUP_MAPPING_TRANSFORM_PREFIX = "nifi.registry.security.group.mapping.transform.";
public static final String EXTENSION_DIR_PREFIX = "nifi.registry.extension.dir.";
diff --git a/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java b/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java
index df3bbe6..cedec8b 100644
--- a/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java
+++ b/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java
@@ -18,19 +18,33 @@ package org.apache.nifi.registry.properties.util;
import java.util.regex.Pattern;
+import static org.apache.nifi.registry.properties.util.IdentityMapping.Transform.NONE;
+
/**
* Holder to pass around the key, pattern, and replacement from an identity mapping in NiFiProperties.
*/
public class IdentityMapping {
+ public enum Transform {
+ NONE,
+ UPPER,
+ LOWER
+ }
+
private final String key;
private final Pattern pattern;
private final String replacementValue;
+ private final Transform transform;
public IdentityMapping(String key, Pattern pattern, String replacementValue) {
+ this(key, pattern, replacementValue, NONE);
+ }
+
+ public IdentityMapping(String key, Pattern pattern, String replacementValue, Transform transform) {
this.key = key;
this.pattern = pattern;
this.replacementValue = replacementValue;
+ this.transform = transform;
}
public String getKey() {
@@ -45,4 +59,7 @@ public class IdentityMapping {
return replacementValue;
}
+ public Transform getTransform() {
+ return transform;
+ }
}
diff --git a/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMappingUtil.java b/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMappingUtil.java
index 3c9208c..d7c2709 100644
--- a/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMappingUtil.java
+++ b/nifi-registry-core/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMappingUtil.java
@@ -17,6 +17,7 @@
package org.apache.nifi.registry.properties.util;
import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.registry.properties.util.IdentityMapping.Transform;
import org.apache.nifi.registry.properties.NiFiRegistryProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,9 +26,17 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static org.apache.nifi.registry.properties.NiFiRegistryProperties.SECURITY_GROUP_MAPPING_PATTERN_PREFIX;
+import static org.apache.nifi.registry.properties.NiFiRegistryProperties.SECURITY_GROUP_MAPPING_TRANSFORM_PREFIX;
+import static org.apache.nifi.registry.properties.NiFiRegistryProperties.SECURITY_GROUP_MAPPING_VALUE_PREFIX;
+import static org.apache.nifi.registry.properties.NiFiRegistryProperties.SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX;
+import static org.apache.nifi.registry.properties.NiFiRegistryProperties.SECURITY_IDENTITY_MAPPING_TRANSFORM_PREFIX;
+import static org.apache.nifi.registry.properties.NiFiRegistryProperties.SECURITY_IDENTITY_MAPPING_VALUE_PREFIX;
+
public class IdentityMappingUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(IdentityMappingUtil.class);
@@ -40,33 +49,81 @@ public class IdentityMappingUtil {
* @return a list of identity mappings
*/
public static List<IdentityMapping> getIdentityMappings(final NiFiRegistryProperties properties) {
+ return getMappings(
+ properties,
+ SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX,
+ SECURITY_IDENTITY_MAPPING_VALUE_PREFIX,
+ SECURITY_IDENTITY_MAPPING_TRANSFORM_PREFIX,
+ () -> "Identity");
+ }
+
+ /**
+ * Buils the group mappings from NiFiProperties.
+ *
+ * @param properties the NiFiProperties instance
+ * @return a list of group mappings
+ */
+ public static List<IdentityMapping> getGroupMappings(final NiFiRegistryProperties properties) {
+ return getMappings(
+ properties,
+ SECURITY_GROUP_MAPPING_PATTERN_PREFIX,
+ SECURITY_GROUP_MAPPING_VALUE_PREFIX,
+ SECURITY_GROUP_MAPPING_TRANSFORM_PREFIX,
+ () -> "Group");
+ }
+
+ /**
+ * Builds the identity mappings from NiFiRegistryProperties.
+ *
+ * @param properties the NiFiRegistryProperties instance
+ * @return a list of identity mappings
+ */
+ private static List<IdentityMapping> getMappings(final NiFiRegistryProperties properties, final String patternPrefix,
+ final String valuePrefix, final String transformPrefix, final Supplier<String> getSubject) {
final List<IdentityMapping> mappings = new ArrayList<>();
// go through each property
for (String propertyName : properties.getPropertyKeys()) {
- if (StringUtils.startsWith(propertyName, NiFiRegistryProperties.SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX)) {
- final String key = StringUtils.substringAfter(propertyName, NiFiRegistryProperties.SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX);
+ if (StringUtils.startsWith(propertyName, patternPrefix)) {
+ final String key = StringUtils.substringAfter(propertyName, patternPrefix);
final String identityPattern = properties.getProperty(propertyName);
if (StringUtils.isBlank(identityPattern)) {
- LOGGER.warn("Identity Mapping property {} was found, but was empty", new Object[]{propertyName});
+ LOGGER.warn("{} Mapping property {} was found, but was empty", new Object[] {getSubject.get(), propertyName});
continue;
}
- final String identityValueProperty = NiFiRegistryProperties.SECURITY_IDENTITY_MAPPING_VALUE_PREFIX + key;
+ final String identityValueProperty = valuePrefix + key;
final String identityValue = properties.getProperty(identityValueProperty);
if (StringUtils.isBlank(identityValue)) {
- LOGGER.warn("Identity Mapping property {} was found, but corresponding value {} was not found",
+ LOGGER.warn("{} Mapping property {} was found, but corresponding value {} was not found",
new Object[]{propertyName, identityValueProperty});
continue;
}
- final IdentityMapping identityMapping = new IdentityMapping(key, Pattern.compile(identityPattern), identityValue);
+ final String identityTransformProperty = transformPrefix + key;
+ String rawIdentityTransform = properties.getProperty(identityTransformProperty);
+
+ if (StringUtils.isBlank(rawIdentityTransform)) {
+ LOGGER.debug("{} Mapping property {} was found, but no transform was present. Using NONE.", new Object[] {getSubject.get(), propertyName});
+ rawIdentityTransform = IdentityMapping.Transform.NONE.name();
+ }
+
+ final Transform identityTransform;
+ try {
+ identityTransform = Transform.valueOf(rawIdentityTransform);
+ } catch (final IllegalArgumentException iae) {
+ LOGGER.warn("{} Mapping property {} was found, but corresponding transform {} was not valid. Allowed values {}",
+ new Object[] {getSubject.get(), propertyName, rawIdentityTransform, StringUtils.join(Transform.values(), ", ")});
+ continue;
+ }
+
+ final IdentityMapping identityMapping = new IdentityMapping(key, Pattern.compile(identityPattern), identityValue, identityTransform);
mappings.add(identityMapping);
- LOGGER.debug("Found Identity Mapping with key = {}, pattern = {}, value = {}",
- new Object[] {key, identityPattern, identityValue});
+ LOGGER.debug("Found {} Mapping with key = {}, pattern = {}, value = {}, transform = {}",
+ new Object[] {getSubject.get(), key, identityPattern, identityValue, rawIdentityTransform});
}
}
@@ -95,7 +152,15 @@ public class IdentityMappingUtil {
if (m.matches()) {
final String pattern = mapping.getPattern().pattern();
final String replacementValue = escapeLiteralBackReferences(mapping.getReplacementValue(), m.groupCount());
- return identity.replaceAll(pattern, replacementValue);
+ final String replacement = identity.replaceAll(pattern, replacementValue);
+
+ if (Transform.UPPER.equals(mapping.getTransform())) {
+ return replacement.toUpperCase();
+ } else if (Transform.LOWER.equals(mapping.getTransform())) {
+ return replacement.toLowerCase();
+ } else {
+ return replacement;
+ }
}
}
diff --git a/nifi-registry-core/nifi-registry-resources/src/main/resources/conf/nifi-registry.properties b/nifi-registry-core/nifi-registry-resources/src/main/resources/conf/nifi-registry.properties
index ce4377f..6d8771f 100644
--- a/nifi-registry-core/nifi-registry-resources/src/main/resources/conf/nifi-registry.properties
+++ b/nifi-registry-core/nifi-registry-resources/src/main/resources/conf/nifi-registry.properties
@@ -73,8 +73,20 @@ nifi.registry.db.sql.debug=${nifi.registry.db.sql.debug}
#
# nifi.registry.security.identity.mapping.pattern.dn=^CN=(.*?), OU=(.*?), O=(.*?), L=(.*?), ST=(.*?), C=(.*?)$
# nifi.registry.security.identity.mapping.value.dn=$1@$2
+# nifi.registry.security.identity.mapping.transform.dn=NONE
+
# nifi.registry.security.identity.mapping.pattern.kerb=^(.*?)/instance@(.*?)$
# nifi.registry.security.identity.mapping.value.kerb=$1@$2
+# nifi.registry.security.identity.mapping.transform.kerb=UPPER
+
+# Group Mapping Properties #
+# These properties allow normalizing group names coming from external sources like LDAP. The following example
+# lowercases any group name.
+#
+# nifi.registry.security.group.mapping.pattern.anygroup=^(.*)$
+# nifi.registry.security.group.mapping.value.anygroup=$1
+# nifi.registry.security.group.mapping.transform.anygroup=LOWER
+
# kerberos properties #
nifi.registry.kerberos.krb5.file=${nifi.registry.kerberos.krb5.file}