Repository: nifi
Updated Branches:
  refs/heads/master ad6af1d94 -> 6bc6f955c


http://git-wip-us.apache.org/repos/asf/nifi/blob/6bc6f955/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/tenants/TenantHolder.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/tenants/TenantHolder.java
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/tenants/TenantHolder.java
new file mode 100644
index 0000000..2c0680e
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/java/org/apache/nifi/ldap/tenants/TenantHolder.java
@@ -0,0 +1,165 @@
+/*
+ * 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.ldap.tenants;
+
+
+import org.apache.nifi.authorization.Group;
+import org.apache.nifi.authorization.User;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A holder to provide atomic access to user group data structures.
+ */
+public class TenantHolder {
+
+    private final Set<User> allUsers;
+    private final Map<String,User> usersById;
+    private final Map<String,User> usersByIdentity;
+
+    private final Set<Group> allGroups;
+    private final Map<String,Group> groupsById;
+    private final Map<String, Set<Group>> groupsByUserIdentity;
+
+    /**
+     * Creates a new holder and populates all convenience data structures.
+     */
+    public TenantHolder(final Set<User> allUsers, final Set<Group> allGroups) {
+        // create a convenience map to retrieve a user by id
+        final Map<String, User> userByIdMap = 
Collections.unmodifiableMap(createUserByIdMap(allUsers));
+
+        // create a convenience map to retrieve a user by identity
+        final Map<String, User> userByIdentityMap = 
Collections.unmodifiableMap(createUserByIdentityMap(allUsers));
+
+        // create a convenience map to retrieve a group by id
+        final Map<String, Group> groupByIdMap = 
Collections.unmodifiableMap(createGroupByIdMap(allGroups));
+
+        // create a convenience map to retrieve the groups for a user identity
+        final Map<String, Set<Group>> groupsByUserIdentityMap = 
Collections.unmodifiableMap(createGroupsByUserIdentityMap(allGroups, allUsers));
+
+        // set all the holders
+        this.allUsers = allUsers;
+        this.allGroups = allGroups;
+        this.usersById = userByIdMap;
+        this.usersByIdentity = userByIdentityMap;
+        this.groupsById = groupByIdMap;
+        this.groupsByUserIdentity = groupsByUserIdentityMap;
+    }
+
+    /**
+     * Creates a Map from user identifier to User.
+     *
+     * @param users the set of all users
+     * @return the Map from user identifier to User
+     */
+    private Map<String,User> createUserByIdMap(final Set<User> users) {
+        Map<String,User> usersMap = new HashMap<>();
+        for (User user : users) {
+            usersMap.put(user.getIdentifier(), user);
+        }
+        return usersMap;
+    }
+
+    /**
+     * Creates a Map from user identity to User.
+     *
+     * @param users the set of all users
+     * @return the Map from user identity to User
+     */
+    private Map<String,User> createUserByIdentityMap(final Set<User> users) {
+        Map<String,User> usersMap = new HashMap<>();
+        for (User user : users) {
+            usersMap.put(user.getIdentity(), user);
+        }
+        return usersMap;
+    }
+
+    /**
+     * Creates a Map from group identifier to Group.
+     *
+     * @param groups the set of all groups
+     * @return the Map from group identifier to Group
+     */
+    private Map<String,Group> createGroupByIdMap(final Set<Group> groups) {
+        Map<String,Group> groupsMap = new HashMap<>();
+        for (Group group : groups) {
+            groupsMap.put(group.getIdentifier(), group);
+        }
+        return groupsMap;
+    }
+
+    /**
+     * Creates a Map from user identity to the set of Groups for that identity.
+     *
+     * @param groups all groups
+     * @param users all users
+     * @return a Map from User identity to the set of Groups for that identity
+     */
+    private Map<String, Set<Group>> createGroupsByUserIdentityMap(final 
Set<Group> groups, final Set<User> users) {
+        Map<String, Set<Group>> groupsByUserIdentity = new HashMap<>();
+
+        for (User user : users) {
+            Set<Group> userGroups = new HashSet<>();
+            for (Group group : groups) {
+                for (String groupUser : group.getUsers()) {
+                    if (groupUser.equals(user.getIdentifier())) {
+                        userGroups.add(group);
+                    }
+                }
+            }
+
+            groupsByUserIdentity.put(user.getIdentity(), userGroups);
+        }
+
+        return groupsByUserIdentity;
+    }
+
+    public Set<User> getAllUsers() {
+        return allUsers;
+    }
+
+    public Map<String, User> getUsersById() {
+        return usersById;
+    }
+
+    public Set<Group> getAllGroups() {
+        return allGroups;
+    }
+
+    public Map<String, Group> getGroupsById() {
+        return groupsById;
+    }
+
+    public User getUser(String identity) {
+        if (identity == null) {
+            throw new IllegalArgumentException("Identity cannot be null");
+        }
+        return usersByIdentity.get(identity);
+    }
+
+    public Set<Group> getGroups(String userIdentity) {
+        if (userIdentity == null) {
+            throw new IllegalArgumentException("User Identity cannot be null");
+        }
+        return groupsByUserIdentity.get(userIdentity);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/6bc6f955/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authorization.UserGroupProvider
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authorization.UserGroupProvider
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authorization.UserGroupProvider
new file mode 100755
index 0000000..1e80cc2
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/main/resources/META-INF/services/org.apache.nifi.authorization.UserGroupProvider
@@ -0,0 +1,15 @@
+# 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.
+org.apache.nifi.ldap.tenants.LdapUserGroupProvider

http://git-wip-us.apache.org/repos/asf/nifi/blob/6bc6f955/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/java/org/apache/nifi/ldap/tenants/LdapUserGroupProviderTest.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/java/org/apache/nifi/ldap/tenants/LdapUserGroupProviderTest.java
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/java/org/apache/nifi/ldap/tenants/LdapUserGroupProviderTest.java
new file mode 100644
index 0000000..f2cc28e
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/java/org/apache/nifi/ldap/tenants/LdapUserGroupProviderTest.java
@@ -0,0 +1,552 @@
+/*
+ * 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.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.attribute.expression.language.StandardPropertyValue;
+import org.apache.nifi.authorization.AuthorizerConfigurationContext;
+import org.apache.nifi.authorization.Group;
+import org.apache.nifi.authorization.UserAndGroups;
+import org.apache.nifi.authorization.UserGroupProviderInitializationContext;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.ldap.LdapAuthenticationStrategy;
+import org.apache.nifi.ldap.ReferralStrategy;
+import org.apache.nifi.util.NiFiProperties;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.Properties;
+import java.util.Set;
+
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_AUTHENTICATION_STRATEGY;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_CONNECT_TIMEOUT;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_MEMBER_ATTRIBUTE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_NAME_ATTRIBUTE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_OBJECT_CLASS;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_SEARCH_BASE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_SEARCH_FILTER;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_GROUP_SEARCH_SCOPE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_MANAGER_DN;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_MANAGER_PASSWORD;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_PAGE_SIZE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_READ_TIMEOUT;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_REFERRAL_STRATEGY;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_SYNC_INTERVAL;
+import static org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_URL;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_USER_GROUP_ATTRIBUTE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_USER_IDENTITY_ATTRIBUTE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_USER_OBJECT_CLASS;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_USER_SEARCH_BASE;
+import static 
org.apache.nifi.ldap.tenants.LdapUserGroupProvider.PROP_USER_SEARCH_FILTER;
+import static 
org.apache.nifi.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.Matchers.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 = AuthorizerCreationException.class)
+    public void testNoSearchBasesSpecified() throws Exception {
+        final AuthorizerConfigurationContext configurationContext = 
getBaseConfiguration(null, null);
+        ldapUserGroupProvider.onConfigured(configurationContext);
+    }
+
+    @Test(expected = AuthorizerCreationException.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, null));
+        ldapUserGroupProvider.onConfigured(configurationContext);
+    }
+
+    @Test(expected = AuthorizerCreationException.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, null));
+        ldapUserGroupProvider.onConfigured(configurationContext);
+    }
+
+    @Test(expected = AuthorizerCreationException.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", null));
+        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", null));
+        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", null));
+        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(), null));
+        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(), null));
+        ldapUserGroupProvider.onConfigured(configurationContext);
+
+        assertEquals(8, 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", null));
+        
when(configurationContext.getProperty(PROP_USER_SEARCH_FILTER)).thenReturn(new 
StandardPropertyValue("(uid=user1)", null));
+        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", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("description", null)); // 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", null));
+        
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("description", null)); // using description in lieu of 
memberof
+        
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("cn", null));
+        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 = AuthorizerCreationException.class)
+    public void testSearchGroupsWithoutMemberAttribute() throws Exception {
+        final AuthorizerConfigurationContext configurationContext = 
getBaseConfiguration(null, GROUP_SEARCH_BASE);
+        ldapUserGroupProvider.onConfigured(configurationContext);
+    }
+
+    @Test(expected = AuthorizerCreationException.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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new 
StandardPropertyValue(null, null));
+        ldapUserGroupProvider.onConfigured(configurationContext);
+    }
+
+    @Test(expected = AuthorizerCreationException.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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new 
StandardPropertyValue(null, null));
+        ldapUserGroupProvider.onConfigured(configurationContext);
+    }
+
+    @Test(expected = AuthorizerCreationException.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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new 
StandardPropertyValue("not-valid", null));
+        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", null));
+        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", null));
+        when(configurationContext.getProperty(PROP_PAGE_SIZE)).thenReturn(new 
StandardPropertyValue("1", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new 
StandardPropertyValue(SearchScope.OBJECT.name(), null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new 
StandardPropertyValue(SearchScope.SUBTREE.name(), null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("cn", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("uid", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("cn", null));
+        
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("cn", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_FILTER)).thenReturn(new 
StandardPropertyValue("(cn=admins)", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("description", null)); // using description in lieu of 
memberof
+        
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("cn", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("member", null));
+        
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("cn", null));
+        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", null));
+        
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("description", null)); // using description in lieu of 
memberof
+        
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("member", null));
+        
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue("cn", null));
+        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.security.identity.mapping.pattern.dn1", 
"^cn=(.*?),o=(.*?)$");
+        props.setProperty("nifi.security.identity.mapping.value.dn1", "$1");
+
+        final NiFiProperties 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)", null));
+        ldapUserGroupProvider.onConfigured(configurationContext);
+
+        assertEquals(1, ldapUserGroupProvider.getUsers().size());
+        assertNotNull(ldapUserGroupProvider.getUserByIdentity("User 
1,ou=users"));
+    }
+
+    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(), null));
+        
when(configurationContext.getProperty(PROP_CONNECT_TIMEOUT)).thenReturn(new 
StandardPropertyValue("30 secs", null));
+        
when(configurationContext.getProperty(PROP_READ_TIMEOUT)).thenReturn(new 
StandardPropertyValue("30 secs", null));
+        
when(configurationContext.getProperty(PROP_REFERRAL_STRATEGY)).thenReturn(new 
StandardPropertyValue(ReferralStrategy.FOLLOW.name(), null));
+        when(configurationContext.getProperty(PROP_PAGE_SIZE)).thenReturn(new 
StandardPropertyValue(null, null));
+        
when(configurationContext.getProperty(PROP_SYNC_INTERVAL)).thenReturn(new 
StandardPropertyValue("30 mins", null));
+
+        
when(configurationContext.getProperty(PROP_AUTHENTICATION_STRATEGY)).thenReturn(new
 StandardPropertyValue(LdapAuthenticationStrategy.SIMPLE.name(), null));
+        when(configurationContext.getProperty(PROP_MANAGER_DN)).thenReturn(new 
StandardPropertyValue("uid=admin,ou=system", null));
+        
when(configurationContext.getProperty(PROP_MANAGER_PASSWORD)).thenReturn(new 
StandardPropertyValue("secret", null));
+
+        
when(configurationContext.getProperty(PROP_USER_SEARCH_BASE)).thenReturn(new 
StandardPropertyValue(userSearchBase, null));
+        
when(configurationContext.getProperty(PROP_USER_OBJECT_CLASS)).thenReturn(new 
StandardPropertyValue("person", null));
+        
when(configurationContext.getProperty(PROP_USER_SEARCH_SCOPE)).thenReturn(new 
StandardPropertyValue(SearchScope.ONE_LEVEL.name(), null));
+        
when(configurationContext.getProperty(PROP_USER_SEARCH_FILTER)).thenReturn(new 
StandardPropertyValue(null, null));
+        
when(configurationContext.getProperty(PROP_USER_IDENTITY_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue(null, null));
+        
when(configurationContext.getProperty(PROP_USER_GROUP_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue(null, null));
+
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_BASE)).thenReturn(new 
StandardPropertyValue(groupSearchBase, null));
+        
when(configurationContext.getProperty(PROP_GROUP_OBJECT_CLASS)).thenReturn(new 
StandardPropertyValue("groupOfNames", null));
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_SCOPE)).thenReturn(new 
StandardPropertyValue(SearchScope.ONE_LEVEL.name(), null));
+        
when(configurationContext.getProperty(PROP_GROUP_SEARCH_FILTER)).thenReturn(new 
StandardPropertyValue(null, null));
+        
when(configurationContext.getProperty(PROP_GROUP_NAME_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue(null, null));
+        
when(configurationContext.getProperty(PROP_GROUP_MEMBER_ATTRIBUTE)).thenReturn(new
 StandardPropertyValue(null, null));
+
+        return configurationContext;
+    }
+
+    private NiFiProperties getNiFiProperties(final Properties properties) {
+        final NiFiProperties nifiProperties = 
Mockito.mock(NiFiProperties.class);
+        
when(nifiProperties.getPropertyKeys()).thenReturn(properties.stringPropertyNames());
+
+        when(nifiProperties.getProperty(anyString())).then(new 
Answer<String>() {
+            @Override
+            public String answer(InvocationOnMock invocationOnMock) throws 
Throwable {
+                return 
properties.getProperty((String)invocationOnMock.getArguments()[0]);
+            }
+        });
+        return nifiProperties;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/6bc6f955/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/resources/nifi-example.ldif
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/resources/nifi-example.ldif
 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/resources/nifi-example.ldif
new file mode 100644
index 0000000..2b5bdac
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-ldap-iaa-providers-bundle/nifi-ldap-iaa-providers/src/test/resources/nifi-example.ldif
@@ -0,0 +1,136 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+version: 1
+
+dn: o=nifi
+objectclass: extensibleObject
+objectclass: top
+objectclass: domain
+dc: nifi
+o: nifi
+
+dn: ou=users,o=nifi
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: cn=User 1,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 1
+sn: User1
+uid: user1
+
+dn: cn=User 2,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 2
+sn: User2
+uid: user2
+
+dn: cn=User 3,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 3
+sn: User3
+uid: user3
+
+dn: cn=User 4,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 4
+sn: User4
+description: cn=team1,ou=groups,o=nifi
+uid: user4
+
+dn: cn=User 5,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 5
+sn: User5
+description: cn=team1,ou=groups,o=nifi
+uid: user5
+
+dn: cn=User 6,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 6
+sn: User6
+description: cn=team2,ou=groups,o=nifi
+uid: user6
+
+dn: cn=User 7,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 7
+sn: User7
+description: cn=team2,ou=groups,o=nifi
+uid: user7
+
+dn: cn=User 8,ou=users,o=nifi
+objectClass: organizationalPerson
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: top
+cn: User 8
+sn: User8
+uid: user8
+
+dn: ou=groups,o=nifi
+objectClass: organizationalUnit
+objectClass: top
+ou: groups
+
+dn: cn=admins,ou=groups,o=nifi
+objectClass: groupOfNames
+objectClass: top
+cn: admins
+member: cn=User 1,ou=users,o=nifi
+member: cn=User 3,ou=users,o=nifi
+
+dn: cn=read-only,ou=groups,o=nifi
+objectClass: groupOfNames
+objectClass: top
+cn: read-only
+member: cn=User 2,ou=users,o=nifi
+
+dn: cn=team1,ou=groups,o=nifi
+objectClass: groupOfNames
+objectClass: top
+cn: team1
+member: cn=User 1,ou=users,o=nifi
+
+dn: cn=team2,ou=groups,o=nifi
+objectClass: groupOfNames
+objectClass: top
+cn: team2
+member: cn=User 1,ou=users,o=nifi

Reply via email to