blob: 94d2031c0d88e5dac5460f9909b5397c8bb2c0b2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.registry.security.ldap.tenants;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.annotations.CreatePartition;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.apache.nifi.registry.properties.NiFiRegistryProperties;
import org.apache.nifi.registry.security.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.registry.security.authorization.Group;
import org.apache.nifi.registry.security.authorization.UserAndGroups;
import org.apache.nifi.registry.security.authorization.UserGroupProviderInitializationContext;
import org.apache.nifi.registry.security.exception.SecurityProviderCreationException;
import org.apache.nifi.registry.security.ldap.LdapAuthenticationStrategy;
import org.apache.nifi.registry.security.ldap.ReferralStrategy;
import org.apache.nifi.registry.util.StandardPropertyValue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import java.util.Properties;
import java.util.Set;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_AUTHENTICATION_STRATEGY;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_CONNECT_TIMEOUT;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_MEMBER_ATTRIBUTE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_MEMBER_REFERENCED_USER_ATTRIBUTE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_NAME_ATTRIBUTE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_OBJECT_CLASS;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_SEARCH_BASE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_SEARCH_FILTER;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_SEARCH_SCOPE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_MANAGER_DN;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_MANAGER_PASSWORD;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_PAGE_SIZE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_READ_TIMEOUT;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_REFERRAL_STRATEGY;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_SYNC_INTERVAL;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_URL;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_USER_GROUP_ATTRIBUTE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_USER_GROUP_REFERENCED_GROUP_ATTRIBUTE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_USER_IDENTITY_ATTRIBUTE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_USER_OBJECT_CLASS;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_USER_SEARCH_BASE;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_USER_SEARCH_FILTER;
import static org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider.PROP_USER_SEARCH_SCOPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(FrameworkRunner.class)
@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")})
@CreateDS(name = "nifi-example", partitions = {@CreatePartition(name = "example", suffix = "o=nifi")})
@ApplyLdifFiles("nifi-example.ldif")
public class LdapUserGroupProviderTest extends AbstractLdapTestUnit {
private static final String USER_SEARCH_BASE = "ou=users,o=nifi";
private static final String GROUP_SEARCH_BASE = "ou=groups,o=nifi";
private LdapUserGroupProvider ldapUserGroupProvider;
@Before
public void setup() {
final UserGroupProviderInitializationContext initializationContext = mock(UserGroupProviderInitializationContext.class);
when(initializationContext.getIdentifier()).thenReturn("identifier");
ldapUserGroupProvider = new LdapUserGroupProvider();
ldapUserGroupProvider.setNiFiProperties(getNiFiProperties(new Properties()));
ldapUserGroupProvider.initialize(initializationContext);
}
@Test(expected = SecurityProviderCreationException.class)
public void testNoSearchBasesSpecified() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, null);
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = SecurityProviderCreationException.class)
public void testUserSearchBaseSpecifiedButNoUserObjectClass() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_OBJECT_CLASS)).thenReturn(new StandardPropertyValue(null));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = SecurityProviderCreationException.class)
public void testUserSearchBaseSpecifiedButNoUserSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(null));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = SecurityProviderCreationException.class)
public void testInvalidUserSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue("not-valid"));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test
public void testSearchUsersWithNoIdentityAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
assertNotNull(ldapUserGroupProvider.getUserByIdentity("cn=User 1,ou=users,o=nifi"));
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchUsersWithUidIdentityAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
assertNotNull(ldapUserGroupProvider.getUserByIdentity("user1"));
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchUsersWithCnIdentityAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
assertNotNull(ldapUserGroupProvider.getUserByIdentity("User 1"));
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchUsersObjectSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.OBJECT.name()));
ldapUserGroupProvider.onConfigured(configurationContext);
assertTrue(ldapUserGroupProvider.getUsers().isEmpty());
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchUsersSubtreeSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration("o=nifi", null);
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.SUBTREE.name()));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(9, ldapUserGroupProvider.getUsers().size());
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchUsersWithFilter() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
when(configurationContext.getProperty(PROP_USER_SEARCH_FILTER)).thenReturn(new StandardPropertyValue("(uid=user1)"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(1, ldapUserGroupProvider.getUsers().size());
assertNotNull(ldapUserGroupProvider.getUserByIdentity("user1"));
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchUsersWithPaging() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_PAGE_SIZE)).thenReturn(new StandardPropertyValue("1"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchUsersWithGroupingNoGroupName() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of memberof
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
assertEquals(2, ldapUserGroupProvider.getGroups().size());
final UserAndGroups userAndGroups = ldapUserGroupProvider.getUserAndGroups("user4");
assertNotNull(userAndGroups.getUser());
assertEquals(1, userAndGroups.getGroups().size());
assertEquals("cn=team1,ou=groups,o=nifi", userAndGroups.getGroups().iterator().next().getName());
}
@Test
public void testSearchUsersWithGroupingAndGroupName() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, null);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of memberof
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
assertEquals(2, ldapUserGroupProvider.getGroups().size());
final UserAndGroups userAndGroups = ldapUserGroupProvider.getUserAndGroups("user4");
assertNotNull(userAndGroups.getUser());
assertEquals(1, userAndGroups.getGroups().size());
assertEquals("team1", userAndGroups.getGroups().iterator().next().getName());
}
@Test(expected = SecurityProviderCreationException.class)
public void testSearchGroupsWithoutMemberAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = SecurityProviderCreationException.class)
public void testGroupSearchBaseSpecifiedButNoGroupObjectClass() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue(null));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = SecurityProviderCreationException.class)
public void testUserSearchBaseSpecifiedButNoGroupSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(null));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test(expected = SecurityProviderCreationException.class)
public void testInvalidGroupSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue("not-valid"));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test
public void testSearchGroupsWithNoNameAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
assertEquals(1, groups.stream().filter(group -> "cn=admins,ou=groups,o=nifi".equals(group.getName())).count());
}
@Test
public void testSearchGroupsWithPaging() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_PAGE_SIZE)).thenReturn(new StandardPropertyValue("1"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(4, ldapUserGroupProvider.getGroups().size());
}
@Test
public void testSearchGroupsObjectSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.OBJECT.name()));
ldapUserGroupProvider.onConfigured(configurationContext);
assertTrue(ldapUserGroupProvider.getUsers().isEmpty());
assertTrue(ldapUserGroupProvider.getGroups().isEmpty());
}
@Test
public void testSearchGroupsSubtreeSearchScope() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, "o=nifi");
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.SUBTREE.name()));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(4, ldapUserGroupProvider.getGroups().size());
}
@Test
public void testSearchGroupsWithNameAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
final Group admins = groups.stream().filter(group -> "admins".equals(group.getName())).findFirst().orElse(null);
assertNotNull(admins);
assertFalse(admins.getUsers().isEmpty());
assertEquals(1, admins.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "cn=User 1,ou=users,o=nifi".equals(user.getIdentity())).count());
}
@Test
public void testSearchGroupsWithNoNameAndUserIdentityUidAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
final Group admins = groups.stream().filter(group -> "cn=admins,ou=groups,o=nifi".equals(group.getName())).findFirst().orElse(null);
assertNotNull(admins);
assertFalse(admins.getUsers().isEmpty());
assertEquals(1, admins.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user1".equals(user.getIdentity())).count());
}
@Test
public void testSearchGroupsWithNameAndUserIdentityCnAttribute() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
final Group admins = groups.stream().filter(group -> "admins".equals(group.getName())).findFirst().orElse(null);
assertNotNull(admins);
assertFalse(admins.getUsers().isEmpty());
assertEquals(1, admins.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "User 1".equals(user.getIdentity())).count());
}
@Test
public void testSearchGroupsWithFilter() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_FILTER)).thenReturn(new StandardPropertyValue("(cn=admins)"));
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(1, groups.size());
assertEquals(1, groups.stream().filter(group -> "cn=admins,ou=groups,o=nifi".equals(group.getName())).count());
}
@Test
public void testSearchUsersAndGroupsNoMembership() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
groups.forEach(group -> assertTrue(group.getUsers().isEmpty()));
}
@Test
public void testSearchUsersAndGroupsMembershipThroughUsers() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of memberof
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
final Group team1 = groups.stream().filter(group -> "team1".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team1);
assertEquals(2, team1.getUsers().size());
assertEquals(2, team1.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user4".equals(user.getIdentity()) || "user5".equals(user.getIdentity())).count());
final Group team2 = groups.stream().filter(group -> "team2".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team2);
assertEquals(2, team2.getUsers().size());
assertEquals(2, team2.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user6".equals(user.getIdentity()) || "user7".equals(user.getIdentity())).count());
}
@Test
public void testSearchUsersAndGroupsMembershipThroughGroups() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
final Group admins = groups.stream().filter(group -> "admins".equals(group.getName())).findFirst().orElse(null);
assertNotNull(admins);
assertEquals(2, admins.getUsers().size());
assertEquals(2, admins.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user1".equals(user.getIdentity()) || "user3".equals(user.getIdentity())).count());
final Group readOnly = groups.stream().filter(group -> "read-only".equals(group.getName())).findFirst().orElse(null);
assertNotNull(readOnly);
assertEquals(1, readOnly.getUsers().size());
assertEquals(1, readOnly.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user2".equals(user.getIdentity())).count());
final Group team1 = groups.stream().filter(group -> "team1".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team1);
assertEquals(1, team1.getUsers().size());
assertEquals(1, team1.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user1".equals(user.getIdentity())).count());
final Group team2 = groups.stream().filter(group -> "team2".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team2);
assertEquals(1, team2.getUsers().size());
assertEquals(1, team2.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user1".equals(user.getIdentity())).count());
}
@Test
public void testSearchUsersAndGroupsMembershipThroughUsersAndGroups() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(USER_SEARCH_BASE, GROUP_SEARCH_BASE);
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of memberof
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("member"));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
assertEquals(8, ldapUserGroupProvider.getUsers().size());
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(4, groups.size());
final Group admins = groups.stream().filter(group -> "admins".equals(group.getName())).findFirst().orElse(null);
assertNotNull(admins);
assertEquals(2, admins.getUsers().size());
assertEquals(2, admins.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user1".equals(user.getIdentity()) || "user3".equals(user.getIdentity())).count());
final Group readOnly = groups.stream().filter(group -> "read-only".equals(group.getName())).findFirst().orElse(null);
assertNotNull(readOnly);
assertEquals(1, readOnly.getUsers().size());
assertEquals(1, readOnly.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user2".equals(user.getIdentity())).count());
final Group team1 = groups.stream().filter(group -> "team1".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team1);
assertEquals(3, team1.getUsers().size());
assertEquals(3, team1.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user1".equals(user.getIdentity()) || "user4".equals(user.getIdentity()) || "user5".equals(user.getIdentity())).count());
final Group team2 = groups.stream().filter(group -> "team2".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team2);
assertEquals(3, team2.getUsers().size());
assertEquals(3, team2.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user1".equals(user.getIdentity()) || "user6".equals(user.getIdentity()) || "user7".equals(user.getIdentity())).count());
}
@Test
public void testUserIdentityMapping() throws Exception {
final Properties props = new Properties();
props.setProperty("nifi.registry.security.identity.mapping.pattern.dn1", "^cn=(.*?),o=(.*?)$");
props.setProperty("nifi.registry.security.identity.mapping.value.dn1", "$1");
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,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);
when(configurationContext.getProperty(PROP_USER_GROUP_REFERENCED_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test
public void testReferencedGroupWithoutDefiningReferencedAttribute() throws Exception {
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"));
when(configurationContext.getProperty(PROP_USER_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room")); // using room due to reqs of groupOfNames
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of member
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room")); // using room due to reqs of groupOfNames
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(1, groups.size());
final Group team3 = groups.stream().filter(group -> "team3".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team3);
assertTrue(team3.getUsers().isEmpty());
}
@Test
public void testReferencedGroupUsingReferencedAttribute() throws Exception {
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"));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of member
when(configurationContext.getProperty(PROP_USER_GROUP_REFERENCED_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room")); // using room because groupOfNames requires a member
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(1, groups.size());
final Group team3 = groups.stream().filter(group -> "team3".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team3);
assertEquals(1, team3.getUsers().size());
assertEquals(1, team3.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "user9".equals(user.getIdentity())).count());
}
@Test(expected = SecurityProviderCreationException.class)
public void testReferencedUserWithoutUserSearchBase() throws Exception {
final AuthorizerConfigurationContext configurationContext = getBaseConfiguration(null, "ou=groups-2,o=nifi");
when(configurationContext.getProperty(PROP_GROUP_MEMBER_REFERENCED_USER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid"));
ldapUserGroupProvider.onConfigured(configurationContext);
}
@Test
public void testReferencedUserWithoutDefiningReferencedAttribute() throws Exception {
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"));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room")); // using room due to reqs of groupOfNames
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of member
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(1, groups.size());
final Group team3 = groups.stream().filter(group -> "team3".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team3);
assertTrue(team3.getUsers().isEmpty());
}
@Test
public void testReferencedUserUsingReferencedAttribute() throws Exception {
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"));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("room")); // using room due to reqs of groupOfNames
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("description")); // using description in lieu of member
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue("cn"));
when(configurationContext.getProperty(PROP_GROUP_MEMBER_REFERENCED_USER_ATTRIBUTE)).thenReturn(new StandardPropertyValue("uid")); // does not need to be the same as user id attr
ldapUserGroupProvider.onConfigured(configurationContext);
final Set<Group> groups = ldapUserGroupProvider.getGroups();
assertEquals(1, groups.size());
final Group team3 = groups.stream().filter(group -> "team3".equals(group.getName())).findFirst().orElse(null);
assertNotNull(team3);
assertEquals(1, team3.getUsers().size());
assertEquals(1, team3.getUsers().stream().map(
userIdentifier -> ldapUserGroupProvider.getUser(userIdentifier)).filter(
user -> "User9".equals(user.getIdentity())).count());
}
private AuthorizerConfigurationContext getBaseConfiguration(final String userSearchBase, final String groupSearchBase) {
final AuthorizerConfigurationContext configurationContext = mock(AuthorizerConfigurationContext.class);
when(configurationContext.getProperty(PROP_URL)).thenReturn(new StandardPropertyValue("ldap://127.0.0.1:" + getLdapServer().getPort()));
when(configurationContext.getProperty(PROP_CONNECT_TIMEOUT)).thenReturn(new StandardPropertyValue("30 secs"));
when(configurationContext.getProperty(PROP_READ_TIMEOUT)).thenReturn(new StandardPropertyValue("30 secs"));
when(configurationContext.getProperty(PROP_REFERRAL_STRATEGY)).thenReturn(new StandardPropertyValue(ReferralStrategy.FOLLOW.name()));
when(configurationContext.getProperty(PROP_PAGE_SIZE)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_SYNC_INTERVAL)).thenReturn(new StandardPropertyValue("30 mins"));
when(configurationContext.getProperty(PROP_AUTHENTICATION_STRATEGY)).thenReturn(new StandardPropertyValue(LdapAuthenticationStrategy.SIMPLE.name()));
when(configurationContext.getProperty(PROP_MANAGER_DN)).thenReturn(new StandardPropertyValue("uid=admin,ou=system"));
when(configurationContext.getProperty(PROP_MANAGER_PASSWORD)).thenReturn(new StandardPropertyValue("secret"));
when(configurationContext.getProperty(PROP_USER_SEARCH_BASE)).thenReturn(new StandardPropertyValue(userSearchBase));
when(configurationContext.getProperty(PROP_USER_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("person"));
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.ONE_LEVEL.name()));
when(configurationContext.getProperty(PROP_USER_SEARCH_FILTER)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_USER_GROUP_REFERENCED_GROUP_ATTRIBUTE)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_BASE)).thenReturn(new StandardPropertyValue(groupSearchBase));
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new StandardPropertyValue("groupOfNames"));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new StandardPropertyValue(SearchScope.ONE_LEVEL.name()));
when(configurationContext.getProperty(PROP_GROUP_SEARCH_FILTER)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new StandardPropertyValue(null));
when(configurationContext.getProperty(PROP_GROUP_MEMBER_REFERENCED_USER_ATTRIBUTE)).thenReturn(new StandardPropertyValue(null));
return configurationContext;
}
private NiFiRegistryProperties getNiFiProperties(final Properties properties) {
final NiFiRegistryProperties registryProperties = Mockito.mock(NiFiRegistryProperties.class);
when(registryProperties.getPropertyKeys()).thenReturn(properties.stringPropertyNames());
when(registryProperties.getProperty(anyString())).then(invocationOnMock -> properties.getProperty((String) invocationOnMock.getArguments()[0]));
return registryProperties;
}
}