NIFI-10408 Added build user method to LdapUserGroupProvider

- Introduced blank user identity checking with improved error reporting for misconfigured mapping
- Simplified LDAP ThreadFactory configuration
- Replaced String.format() with placeholders for debug logging
- Replaced deprecated FormatUtils.getTimeDuration with getPreciseTimeDuration

Signed-off-by: Nathan Gough <thenatog@gmail.com>

This closes #6351.
This commit is contained in:
exceptionfactory 2022-08-29 17:17:49 -05:00 committed by Nathan Gough
parent 28fc030ef5
commit 3a6d724b44
2 changed files with 161 additions and 132 deletions

View File

@ -17,6 +17,7 @@
package org.apache.nifi.ldap.tenants;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.nifi.authentication.exception.ProviderCreationException;
import org.apache.nifi.authentication.exception.ProviderDestructionException;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
@ -147,16 +148,12 @@ public class LdapUserGroupProvider implements UserGroupProvider {
@Override
public void initialize(final UserGroupProviderInitializationContext initializationContext) throws AuthorizerCreationException {
ldapSync = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
final ThreadFactory factory = Executors.defaultThreadFactory();
@Override
public Thread newThread(Runnable r) {
final Thread thread = factory.newThread(r);
thread.setName(String.format("%s (%s) - background sync thread", getClass().getSimpleName(), initializationContext.getIdentifier()));
return thread;
}
});
final String namingPattern = String.format("%s (%s) - background sync thread", getClass().getSimpleName(), initializationContext.getIdentifier());
final ThreadFactory threadFactory = new BasicThreadFactory.Builder()
.daemon(true)
.namingPattern(namingPattern)
.build();
ldapSync = Executors.newSingleThreadScheduledExecutor(threadFactory);
}
@Override
@ -179,56 +176,53 @@ public class LdapUserGroupProvider implements UserGroupProvider {
rawAuthenticationStrategy.getValue(), StringUtils.join(LdapAuthenticationStrategy.values(), ", ")));
}
switch (authenticationStrategy) {
case ANONYMOUS:
context.setAnonymousReadOnly(true);
break;
default:
final String userDn = configurationContext.getProperty(PROP_MANAGER_DN).getValue();
final String password = configurationContext.getProperty(PROP_MANAGER_PASSWORD).getValue();
if (authenticationStrategy == LdapAuthenticationStrategy.ANONYMOUS) {
context.setAnonymousReadOnly(true);
} else {
final String userDn = configurationContext.getProperty(PROP_MANAGER_DN).getValue();
final String password = configurationContext.getProperty(PROP_MANAGER_PASSWORD).getValue();
context.setUserDn(userDn);
context.setPassword(password);
context.setUserDn(userDn);
context.setPassword(password);
switch (authenticationStrategy) {
case SIMPLE:
context.setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy());
break;
case LDAPS:
context.setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy());
switch (authenticationStrategy) {
case SIMPLE:
context.setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy());
break;
case LDAPS:
context.setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy());
// indicate a secure connection
baseEnvironment.put(Context.SECURITY_PROTOCOL, "ssl");
// indicate a secure connection
baseEnvironment.put(Context.SECURITY_PROTOCOL, "ssl");
// get the configured ssl context
final SSLContext ldapsSslContext = getConfiguredSslContext(configurationContext);
if (ldapsSslContext != null) {
// initialize the ldaps socket factory prior to use
LdapsSocketFactory.initialize(ldapsSslContext.getSocketFactory());
baseEnvironment.put("java.naming.ldap.factory.socket", LdapsSocketFactory.class.getName());
}
break;
case START_TLS:
final AbstractTlsDirContextAuthenticationStrategy tlsAuthenticationStrategy = new DefaultTlsDirContextAuthenticationStrategy();
// get the configured ssl context
final SSLContext ldapSslContext = getConfiguredSslContext(configurationContext);
if (ldapSslContext != null) {
// initialize the LDAP socket factory prior to use
LdapsSocketFactory.initialize(ldapSslContext.getSocketFactory());
baseEnvironment.put("java.naming.ldap.factory.socket", LdapsSocketFactory.class.getName());
}
break;
case START_TLS:
final AbstractTlsDirContextAuthenticationStrategy tlsAuthenticationStrategy = new DefaultTlsDirContextAuthenticationStrategy();
// shutdown gracefully
final String rawShutdownGracefully = configurationContext.getProperty("TLS - Shutdown Gracefully").getValue();
if (StringUtils.isNotBlank(rawShutdownGracefully)) {
final boolean shutdownGracefully = Boolean.TRUE.toString().equalsIgnoreCase(rawShutdownGracefully);
tlsAuthenticationStrategy.setShutdownTlsGracefully(shutdownGracefully);
}
// shutdown gracefully
final String rawShutdownGracefully = configurationContext.getProperty("TLS - Shutdown Gracefully").getValue();
if (StringUtils.isNotBlank(rawShutdownGracefully)) {
final boolean shutdownGracefully = Boolean.TRUE.toString().equalsIgnoreCase(rawShutdownGracefully);
tlsAuthenticationStrategy.setShutdownTlsGracefully(shutdownGracefully);
}
// get the configured ssl context
final SSLContext startTlsSslContext = getConfiguredSslContext(configurationContext);
if (startTlsSslContext != null) {
tlsAuthenticationStrategy.setSslSocketFactory(startTlsSslContext.getSocketFactory());
}
// get the configured ssl context
final SSLContext startTlsSslContext = getConfiguredSslContext(configurationContext);
if (startTlsSslContext != null) {
tlsAuthenticationStrategy.setSslSocketFactory(startTlsSslContext.getSocketFactory());
}
// set the authentication strategy
context.setAuthenticationStrategy(tlsAuthenticationStrategy);
break;
}
break;
// set the authentication strategy
context.setAuthenticationStrategy(tlsAuthenticationStrategy);
break;
}
}
// referrals
@ -349,7 +343,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
pageSize = rawPageSize.asInteger();
}
// get whether group membership should be case sensitive
// get whether group membership should be case-sensitive
final String rawGroupMembershipEnforceCaseSensitivity = configurationContext.getProperty(PROP_GROUP_MEMBERSHIP_ENFORCE_CASE_SENSITIVITY).getValue();
groupMembershipEnforceCaseSensitivity = Boolean.parseBoolean(rawGroupMembershipEnforceCaseSensitivity);
@ -373,7 +367,8 @@ public class LdapUserGroupProvider implements UserGroupProvider {
final long syncInterval;
if (rawSyncInterval.isSet()) {
try {
syncInterval = FormatUtils.getTimeDuration(rawSyncInterval.getValue(), TimeUnit.MILLISECONDS);
final double interval = FormatUtils.getPreciseTimeDuration(rawSyncInterval.getValue(), TimeUnit.MILLISECONDS);
syncInterval = Math.round(interval);
} catch (final IllegalArgumentException iae) {
throw new AuthorizerCreationException(String.format("The %s '%s' is not a valid time duration", PROP_SYNC_INTERVAL, rawSyncInterval.getValue()));
}
@ -400,7 +395,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
try {
load(context);
} catch (final Throwable t) {
logger.error("Failed to sync User/Groups from LDAP due to {}. Will try again in {} millis.", new Object[] {t.toString(), syncInterval});
logger.error("Failed to sync User/Groups from LDAP due to {}. Will try again in {} millis.", t, syncInterval);
if (logger.isDebugEnabled()) {
logger.error("", t);
}
@ -502,11 +497,8 @@ public class LdapUserGroupProvider implements UserGroupProvider {
userList.addAll(ldapTemplate.search(userSearchBase, userFilter.encode(), userControls, new AbstractContextMapper<User>() {
@Override
protected User doMapFromContext(DirContextOperations ctx) {
// get the user identity
final String identity = getUserIdentity(ctx);
// build the user
final User user = new User.Builder().identifierGenerateFromSeed(identity).identity(identity).build();
// get the user
final User user = buildUser(ctx);
// store the user for group member later
userLookup.put(getReferencedUserValue(ctx), user);
@ -515,13 +507,16 @@ public class LdapUserGroupProvider implements UserGroupProvider {
final Attribute attributeGroups = ctx.getAttributes().get(userGroupNameAttribute);
if (attributeGroups == null) {
logger.debug(String.format("User group name attribute [%s] does not exist for %s. This may be due to "
+ "misconfiguration or the user may just not belong to any groups. Ignoring group membership.", userGroupNameAttribute, identity));
logger.debug("User group name attribute [{}] does not exist for [{}]. This may be due to "
+ "misconfiguration or the user may not belong to any groups. Ignoring group membership.",
userGroupNameAttribute,
user.getIdentity()
);
} else {
try {
final NamingEnumeration<String> groupValues = (NamingEnumeration<String>) attributeGroups.getAll();
final NamingEnumeration<?> groupValues = attributeGroups.getAll();
while (groupValues.hasMoreElements()) {
final String groupValue = groupValues.next();
final String groupValue = groupValues.next().toString();
// if we are performing a group search, then we need to normalize the group value so that each
// user associating with it can be matched. if we are not performing a group search then these
@ -575,8 +570,6 @@ public class LdapUserGroupProvider implements UserGroupProvider {
groupList.addAll(ldapTemplate.search(groupSearchBase, groupFilter.encode(), groupControls, new AbstractContextMapper<Group>() {
@Override
protected Group doMapFromContext(DirContextOperations ctx) {
final String dn = ctx.getDn().toString();
// get the group identity
final String name = getGroupName(ctx);
@ -586,16 +579,19 @@ public class LdapUserGroupProvider implements UserGroupProvider {
if (!StringUtils.isBlank(groupMemberAttribute)) {
Attribute attributeUsers = ctx.getAttributes().get(groupMemberAttribute);
if (attributeUsers == null) {
logger.debug(String.format("Group member attribute [%s] does not exist for %s. This may be due to "
+ "misconfiguration or the group may not have any members. Ignoring group membership.", groupMemberAttribute, name));
logger.debug("Group member attribute [{}] does not exist for [{}]. This may be due to "
+ "misconfiguration or the group may not have any members. Ignoring group membership.",
groupMemberAttribute,
name
);
} else {
try {
final NamingEnumeration<String> userValues = (NamingEnumeration<String>) attributeUsers.getAll();
final NamingEnumeration<?> userValues = attributeUsers.getAll();
while (userValues.hasMoreElements()) {
final String userValue = userValues.next();
final String userValue = userValues.next().toString();
if (performUserSearch) {
// find the user by it's referenced attribute and add the identifier to this group.
// find the user by referenced attribute and add the identifier to this group.
// need to normalize here based on the desired case sensitivity. if case sensitivity
// is disabled, the user reference value will be lowercased when adding to userLookup
final String userValueNormalized = groupMembershipEnforceCaseSensitivity ? userValue : userValue.toLowerCase();
@ -611,22 +607,19 @@ public class LdapUserGroupProvider implements UserGroupProvider {
} else {
// since performUserSearch is false, then the referenced group attribute must be blank... the user value must be the dn.
// no need to normalize here since group membership is driven solely through this group (not through the userLookup
// populated above). we are either going to use this value directly as the user identity or we are going to query
// populated above). we are either going to use this value directly as the user identity, or we are going to query
// the directory server again which should handle the case sensitivity accordingly.
final String userDn = userValue;
final User user;
final String userIdentity;
if (useDnForUserIdentity) {
// use the user value to avoid the unnecessary look up
userIdentity = IdentityMappingUtil.mapIdentity(userDn, identityMappings);
// use the user value to avoid the unnecessary search
final String userIdentity = IdentityMappingUtil.mapIdentity(userValue, identityMappings);
user = buildUser(userIdentity, userValue);
} else {
// lookup the user to extract the user identity
userIdentity = getUserIdentity((DirContextAdapter) ldapTemplate.lookup(userDn));
user = buildUser((DirContextAdapter) ldapTemplate.lookup(userValue));
}
// build the user
final User user = new User.Builder().identifierGenerateFromSeed(userIdentity).identity(userIdentity).build();
// add this user
userList.add(user);
groupToUserIdentifierMappings.computeIfAbsent(referencedGroupValue, g -> new HashSet<>()).add(user.getIdentifier());
@ -643,7 +636,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
// add all users that were associated with this referenced group attribute
if (groupToUserIdentifierMappings.containsKey(referencedGroupValue)) {
groupToUserIdentifierMappings.remove(referencedGroupValue).forEach(userIdentifier -> groupBuilder.addUser(userIdentifier));
groupToUserIdentifierMappings.remove(referencedGroupValue).forEach(groupBuilder::addUser);
}
return groupBuilder.build();
@ -651,11 +644,15 @@ public class LdapUserGroupProvider implements UserGroupProvider {
}, groupProcessor));
} while (hasMorePages(groupProcessor));
// any remaining groupDn's were referenced by a user but not found while searching groups
groupToUserIdentifierMappings.forEach((referencedGroupValue, userIdentifiers) -> {
logger.debug(String.format("[%s] are members of %s but that group was not found while searching groups. This may be due to a misconfiguration "
+ "or it's possible the group is not a NiFi group. Ignoring group membership.", StringUtils.join(userIdentifiers, ", "), referencedGroupValue));
});
// any remaining groupDns were referenced by a user but not found while searching groups
if (logger.isDebugEnabled()) {
groupToUserIdentifierMappings.forEach((referencedGroupValue, userIdentifiers) ->
logger.debug("{} are members of [{}] but that group was not found while searching groups. This may be due to a misconfiguration "
+ "or it's possible the group is not a NiFi group. Ignoring group membership.",
userIdentifiers,
referencedGroupValue
));
}
} else {
// since performGroupSearch is false, then the referenced user attribute must be blank... the group value must be the dn
@ -663,7 +660,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
groupToUserIdentifierMappings.forEach((groupDn, userIdentifiers) -> {
final String groupName;
if (useDnForGroupName) {
// use the dn to avoid the unnecessary look up
// use the dn to avoid the unnecessary search
groupName = IdentityMappingUtil.mapIdentity(groupDn, groupMappings);
} else {
groupName = getGroupName((DirContextAdapter) ldapTemplate.lookup(groupDn));
@ -673,7 +670,7 @@ public class LdapUserGroupProvider implements UserGroupProvider {
final Group.Builder groupBuilder = new Group.Builder().identifierGenerateFromSeed(groupName).name(groupName);
// add each user
userIdentifiers.forEach(userIdentifier -> groupBuilder.addUser(userIdentifier));
userIdentifiers.forEach(groupBuilder::addUser);
// build the group
groupList.add(groupBuilder.build());
@ -701,6 +698,19 @@ public class LdapUserGroupProvider implements UserGroupProvider {
return processor instanceof PagedResultsDirContextProcessor && ((PagedResultsDirContextProcessor) processor).hasMore();
}
private User buildUser(final DirContextOperations dirContextOperations) {
final String userIdentity = getUserIdentity(dirContextOperations);
return buildUser(userIdentity, dirContextOperations);
}
private User buildUser(final String userIdentity, final Object reference) {
if (StringUtils.isBlank(userIdentity)) {
throw new IllegalArgumentException(String.format("User Identity not found for Directory Reference: %s", reference));
}
return new User.Builder().identifierGenerateFromSeed(userIdentity).identity(userIdentity).build();
}
private String getUserIdentity(final DirContextOperations ctx) {
final String identity;
@ -811,8 +821,8 @@ public class LdapUserGroupProvider implements UserGroupProvider {
final PropertyValue rawTimeout = configurationContext.getProperty(configurationProperty);
if (rawTimeout.isSet()) {
try {
final Long timeout = FormatUtils.getTimeDuration(rawTimeout.getValue(), TimeUnit.MILLISECONDS);
baseEnvironment.put(environmentKey, timeout.toString());
final double timeout = FormatUtils.getPreciseTimeDuration(rawTimeout.getValue(), TimeUnit.MILLISECONDS);
baseEnvironment.put(environmentKey, Long.toString(Math.round(timeout)));
} catch (final IllegalArgumentException iae) {
throw new AuthorizerCreationException(String.format("The %s '%s' is not a valid time duration", configurationProperty, rawTimeout));
}

View File

@ -68,6 +68,7 @@ import static org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_USER_SEARC
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
@ -95,34 +96,34 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test(expected = AuthorizerCreationException.class)
public void testNoSearchBasesSpecified() throws Exception {
public void testNoSearchBasesSpecified() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, null);
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testUserSearchBaseSpecifiedButNoUserObjectClass() throws Exception {
public void testUserSearchBaseSpecifiedButNoUserObjectClass() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_OBJECT_CLASS)).thenReturn(new StandardPropertyValue(null, null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testUserSearchBaseSpecifiedButNoUserSearchScope() throws Exception {
public void testUserSearchBaseSpecifiedButNoUserSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(null, null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testInvalidUserSearchScope() throws Exception {
public void testInvalidUserSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue("not-valid", null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test
public void testSearchUsersWithNoIdentityAttribute() throws Exception {
public void testSearchUsersWithNoIdentityAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
ldapUserGroupProvider.onConfigured(configurationContext);
@ -132,7 +133,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersWithUidIdentityAttribute() throws Exception {
public void testSearchUsersWithUidIdentityAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
@ -143,7 +144,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersWithCnIdentityAttribute() throws Exception {
public void testSearchUsersWithCnIdentityAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn", null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
@ -154,7 +155,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersObjectSearchScope() throws Exception {
public void testSearchUsersObjectSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.OBJECT.name(), null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
@ -164,7 +165,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersSubtreeSearchScope() throws Exception {
public void testSearchUsersSubtreeSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("o=nifi", null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.SUBTREE.name(), null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
@ -174,7 +175,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersWithFilter() throws Exception {
public void testSearchUsersWithFilter() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_SEARCH_FILTER)).thenReturn(new StandardPropertyValue("(uid=user1)", null, ParameterLookup.EMPTY));
@ -186,7 +187,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersWithPaging() throws Exception {
public void testSearchUsersWithPaging() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_PAGE_SIZE)).thenReturn(new StandardPropertyValue("1", null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
@ -196,7 +197,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersWithGroupingNoGroupName() throws Exception {
public void testSearchUsersWithGroupingNoGroupName() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description", null, ParameterLookup.EMPTY)); // using description in lieu of memberof
@ -238,7 +239,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersWithGroupingAndGroupName() throws Exception {
public void testSearchUsersWithGroupingAndGroupName() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description", null, ParameterLookup.EMPTY)); // using description in lieu of memberof
@ -255,13 +256,13 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test(expected = AuthorizerCreationException.class)
public void testSearchGroupsWithoutMemberAttribute() throws Exception {
public void testSearchGroupsWithoutMemberAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testGroupSearchBaseSpecifiedButNoGroupObjectClass() throws Exception {
public void testGroupSearchBaseSpecifiedButNoGroupObjectClass() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue(null, null, ParameterLookup.EMPTY));
@ -269,7 +270,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test(expected = AuthorizerCreationException.class)
public void testUserSearchBaseSpecifiedButNoGroupSearchScope() throws Exception {
public void testUserSearchBaseSpecifiedButNoGroupSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(null, null, ParameterLookup.EMPTY));
@ -277,7 +278,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test(expected = AuthorizerCreationException.class)
public void testInvalidGroupSearchScope() throws Exception {
public void testInvalidGroupSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue("not-valid", null, ParameterLookup.EMPTY));
@ -285,7 +286,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsWithNoNameAttribute() throws Exception {
public void testSearchGroupsWithNoNameAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
@ -296,7 +297,25 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsWithPaging() throws Exception {
public void testSearchGroupsWithNoNameAttributeCaptureGroupBlank() {
final Properties props = new Properties();
props.setProperty("nifi.security.identity.mapping.pattern.dn1", "^cn=User( )\\d,ou=.*?,o=.*?$");
props.setProperty("nifi.security.identity.mapping.value.dn1", "$1");
props.setProperty("nifi.security.identity.mapping.transform.dn1", "UPPER");
final NiFiProperties properties = getNiFiProperties(props);
ldapUserGroupProvider.setNiFiProperties(properties);
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
final IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> ldapUserGroupProvider.onConfigured(configurationContext));
final String message = exception.getMessage();
assertTrue("Distinguished Name not found", message.contains("o=nifi"));
}
@Test
public void testSearchGroupsWithPaging() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_PAGE_SIZE)).thenReturn(new StandardPropertyValue("1", null, ParameterLookup.EMPTY));
@ -306,7 +325,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsObjectSearchScope() throws Exception {
public void testSearchGroupsObjectSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.OBJECT.name(), null, ParameterLookup.EMPTY));
@ -317,7 +336,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsSubtreeSearchScope() throws Exception {
public void testSearchGroupsSubtreeSearchScope() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, "o=nifi");
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.SUBTREE.name(), null, ParameterLookup.EMPTY));
@ -327,7 +346,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsWithNameAttribute() throws Exception {
public void testSearchGroupsWithNameAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn", null, ParameterLookup.EMPTY));
@ -345,7 +364,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsWithNoNameAndUserIdentityUidAttribute() throws Exception {
public void testSearchGroupsWithNoNameAndUserIdentityUidAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
@ -363,7 +382,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsWithNameAndUserIdentityCnAttribute() throws Exception {
public void testSearchGroupsWithNameAndUserIdentityCnAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn", null, ParameterLookup.EMPTY));
@ -382,7 +401,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchGroupsWithFilter() throws Exception {
public void testSearchGroupsWithFilter() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_FILTER)).thenReturn(new StandardPropertyValue("(cn=admins)", null, ParameterLookup.EMPTY));
@ -394,7 +413,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersAndGroupsNoMembership() throws Exception {
public void testSearchUsersAndGroupsNoMembership() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
ldapUserGroupProvider.onConfigured(configurationContext);
@ -406,7 +425,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersAndGroupsMembershipThroughUsers() throws Exception {
public void testSearchUsersAndGroupsMembershipThroughUsers() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description", null, ParameterLookup.EMPTY)); // using description in lieu of memberof
@ -434,7 +453,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersAndGroupsMembershipThroughGroups() throws Exception {
public void testSearchUsersAndGroupsMembershipThroughGroups() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
@ -476,7 +495,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersAndGroupsMembershipThroughUsersAndGroups() throws Exception {
public void testSearchUsersAndGroupsMembershipThroughUsersAndGroups() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description", null, ParameterLookup.EMPTY)); // using description in lieu of memberof
@ -519,7 +538,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testUserIdentityMapping() throws Exception {
public void testUserIdentityMapping() {
final Properties props = new Properties();
props.setProperty("nifi.security.identity.mapping.pattern.dn1", "^cn=(.*?),o=(.*?)$");
props.setProperty("nifi.security.identity.mapping.value.dn1", "$1");
@ -536,7 +555,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testUserIdentityMappingWithTransforms() throws Exception {
public void testUserIdentityMappingWithTransforms() {
final Properties props = new Properties();
props.setProperty("nifi.security.identity.mapping.pattern.dn1", "^cn=(.*?),ou=(.*?),o=(.*?)$");
props.setProperty("nifi.security.identity.mapping.value.dn1", "$1");
@ -554,7 +573,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testUserIdentityAndGroupMappingWithTransforms() throws Exception {
public void testUserIdentityAndGroupMappingWithTransforms() {
final Properties props = new Properties();
props.setProperty("nifi.security.identity.mapping.pattern.dn1", "^cn=(.*?),ou=(.*?),o=(.*?)$");
props.setProperty("nifi.security.identity.mapping.value.dn1", "$1");
@ -579,14 +598,14 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test(expected = AuthorizerCreationException.class)
public void testReferencedGroupAttributeWithoutGroupSearchBase() throws Exception {
public void testReferencedGroupAttributeWithoutGroupSearchBase() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("ou=users-2,o=nifi", null);
when(configurationContext.getProperty(PROP_USER_GROUP_REFERENCED_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn", null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test
public void testReferencedGroupWithoutDefiningReferencedAttribute() throws Exception {
public void testReferencedGroupWithoutDefiningReferencedAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("ou=users-2,o=nifi", "ou=groups-2,o=nifi");
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room", null, ParameterLookup.EMPTY)); // using room due to reqs of groupOfNames
@ -604,7 +623,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testReferencedGroupUsingReferencedAttribute() throws Exception {
public void testReferencedGroupUsingReferencedAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("ou=users-2,o=nifi", "ou=groups-2,o=nifi");
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description", null, ParameterLookup.EMPTY)); // using description in lieu of member
@ -625,14 +644,14 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test(expected = AuthorizerCreationException.class)
public void testReferencedUserWithoutUserSearchBase() throws Exception {
public void testReferencedUserWithoutUserSearchBase() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, "ou=groups-2,o=nifi");
when(configurationContext.getProperty(PROP_GROUP_MEMBER_REFERENCED_USER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test
public void testReferencedUserWithoutDefiningReferencedAttribute() throws Exception {
public void testReferencedUserWithoutDefiningReferencedAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("ou=users-2,o=nifi", "ou=groups-2,o=nifi");
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room", null, ParameterLookup.EMPTY)); // using room due to reqs of groupOfNames
@ -649,7 +668,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testReferencedUserUsingReferencedAttribute() throws Exception {
public void testReferencedUserUsingReferencedAttribute() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("ou=users-2,o=nifi", "ou=groups-2,o=nifi");
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("sn", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room", null, ParameterLookup.EMPTY)); // using room due to reqs of groupOfNames
@ -671,7 +690,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersAndGroupsMembershipThroughGroupsCaseInsensitive() throws Exception {
public void testSearchUsersAndGroupsMembershipThroughGroupsCaseInsensitive() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
@ -696,7 +715,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersAndGroupsMembershipThroughGroupsCaseSensitive() throws Exception {
public void testSearchUsersAndGroupsMembershipThroughGroupsCaseSensitive() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member", null, ParameterLookup.EMPTY));
@ -717,7 +736,7 @@ public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
}
@Test
public void testSearchUsersAndGroupsMembershipThroughUsersCaseInsensitive() throws Exception {
public void testSearchUsersAndGroupsMembershipThroughUsersCaseInsensitive() {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid", null, ParameterLookup.EMPTY));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description", null, ParameterLookup.EMPTY)); // using description in lieu of memberof