NIFI-1916 Updating FileAuthorizer to extend AbstractPolicyBasedAuthorizer and 
adding intial loading of data users, groups, and policies
- Implementing CRUD operations and unit tests for Users
- Implementing CRUD operations and unit tests for Groups
- Implementing CRUD operations and unit tests for AccessPolicies
- Adding support for seeding with an initial admin user
- Fixing delete for user and group so it removes references from policies
- Adding example to authorizations.xml
- Adding back the old users schema in preparation for auto-converting to the 
new format, and providing the AuthorizationConfigurationContext with access to 
the root process group id
- Refactoring some of the FileAuthorizer to ensure thread safety
- Adding /groups to policies created for initial admin
- This closes #473


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/8d8a9cba
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/8d8a9cba
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/8d8a9cba

Branch: refs/heads/master
Commit: 8d8a9cba794fbea0d6a940f9aa0f286b5a076784
Parents: 806f4d5
Author: Bryan Bende <[email protected]>
Authored: Wed May 25 13:22:05 2016 -0400
Committer: Matt Gilman <[email protected]>
Committed: Fri Jun 3 17:26:22 2016 -0400

----------------------------------------------------------------------
 .../AbstractPolicyBasedAuthorizer.java          |  13 +-
 .../apache/nifi/authorization/AccessPolicy.java |  50 +-
 .../AuthorizerConfigurationContext.java         |   5 +
 .../org/apache/nifi/authorization/Group.java    |  25 +-
 .../org/apache/nifi/authorization/User.java     |  22 +-
 .../authorization/UsersAndAccessPolicies.java   |  43 ++
 .../TestAbstractPolicyBasedAuthorizer.java      |  41 +-
 .../nifi/authorization/TestAccessPolicy.java    |  62 +-
 .../apache/nifi/authorization/TestGroup.java    |  18 +-
 .../org/apache/nifi/authorization/TestUser.java |  18 +-
 .../nifi-framework-nar/pom.xml                  |   4 +
 .../nifi-framework/nifi-authorizer/pom.xml      |  74 ++
 .../authorization/AuthorizerFactoryBean.java    | 347 ++++++++++
 .../main/resources/nifi-authorizer-context.xml  |  27 +
 .../src/main/xsd/authorizers.xsd                |  49 ++
 .../nifi-framework/nifi-file-authorizer/pom.xml |  18 +-
 .../authorization/AuthorizationsHolder.java     | 355 ++++++++++
 .../nifi/authorization/FileAuthorizer.java      | 645 +++++++++++++----
 .../src/main/xsd/authorizations.xsd             | 120 +++-
 .../nifi-file-authorizer/src/main/xsd/users.xsd |  64 ++
 .../nifi/authorization/FileAuthorizerTest.java  | 687 ++++++++++++++++++-
 .../nifi-framework-authorization/pom.xml        |  47 +-
 .../authorization/AuthorizerFactoryBean.java    | 341 ---------
 .../StandardAuthorizerConfigurationContext.java |   9 +-
 .../nifi-framework-authorization-context.xml    |  26 -
 .../src/main/xsd/authorizers.xsd                |  49 --
 .../src/main/resources/conf/authorizations.xml  |  19 +-
 .../src/main/resources/conf/authorizers.xml     |   2 +-
 .../nifi/web/NiFiWebApiConfiguration.java       |   2 +-
 .../nifi-framework/pom.xml                      |   1 +
 nifi-nar-bundles/nifi-framework-bundle/pom.xml  |   5 +
 31 files changed, 2415 insertions(+), 773 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
 
b/nifi-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
index 1200017..f67ac8b 100644
--- 
a/nifi-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
@@ -27,13 +27,15 @@ public abstract class AbstractPolicyBasedAuthorizer 
implements Authorizer {
 
     @Override
     public final AuthorizationResult authorize(AuthorizationRequest request) 
throws AuthorizationAccessException {
-        final Set<AccessPolicy> policies = 
getAccessPolicies(request.getResource());
+        final UsersAndAccessPolicies usersAndAccessPolicies = 
getUsersAndAccessPolicies();
+        final String resourceIdentifier = 
request.getResource().getIdentifier();
 
+        final Set<AccessPolicy> policies = 
usersAndAccessPolicies.getAccessPolicies(resourceIdentifier);
         if (policies == null || policies.isEmpty()) {
             return AuthorizationResult.resourceNotFound();
         }
 
-        final User user = getUserByIdentity(request.getIdentity());
+        final User user = 
usersAndAccessPolicies.getUser(request.getIdentity());
 
         if (user == null) {
             return AuthorizationResult.denied("Unknown user with identity " + 
request.getIdentity());
@@ -209,12 +211,11 @@ public abstract class AbstractPolicyBasedAuthorizer 
implements Authorizer {
     public abstract Set<AccessPolicy> getAccessPolicies() throws 
AuthorizationAccessException;
 
     /**
-     * Retrieves the access policies for the given Resource.
+     * Returns the UserAccessPolicies instance.
      *
-     * @param resource the resource to retrieve policies for
-     * @return a set of policies for the given resource, or an empty set if 
there are none
+     * @return the UserAccessPolicies instance
      * @throws AuthorizationAccessException if there was an unexpected error 
performing the operation
      */
-    public abstract Set<AccessPolicy> getAccessPolicies(Resource resource) 
throws AuthorizationAccessException;
+    public abstract UsersAndAccessPolicies getUsersAndAccessPolicies() throws 
AuthorizationAccessException;
 
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java 
b/nifi-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java
index f5c46e1..7ef40a3 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AccessPolicy.java
@@ -28,7 +28,7 @@ public class AccessPolicy {
 
     private final String identifier;
 
-    private final Resource resource;
+    private final String resource;
 
     private final Set<String> users;
 
@@ -36,7 +36,7 @@ public class AccessPolicy {
 
     private final Set<RequestAction> actions;
 
-    private AccessPolicy(final AccessPolicyBuilder builder) {
+    private AccessPolicy(final Builder builder) {
         this.identifier = builder.identifier;
         this.resource = builder.resource;
         this.users = Collections.unmodifiableSet(new HashSet<>(builder.users));
@@ -51,10 +51,6 @@ public class AccessPolicy {
             throw new IllegalArgumentException("Resource can not be null");
         }
 
-        if ((this.users == null || this.users.isEmpty()) && (this.groups == 
null || this.groups.isEmpty())) {
-            throw new IllegalArgumentException("Users & Groups can not both be 
null or empty");
-        }
-
         if (this.actions == null || this.actions.isEmpty()) {
             throw new IllegalArgumentException("Actions can not be null or 
empty");
         }
@@ -70,7 +66,7 @@ public class AccessPolicy {
     /**
      * @return the resource for this policy
      */
-    public Resource getResource() {
+    public String getResource() {
         return resource;
     }
 
@@ -116,16 +112,16 @@ public class AccessPolicy {
     @Override
     public String toString() {
         return String.format("identifier[%s], resource[%s], users[%s], 
groups[%s], action[%s]",
-                getIdentifier(), getResource().getIdentifier(), getUsers(), 
getGroups(), getActions());
+                getIdentifier(), getResource(), getUsers(), getGroups(), 
getActions());
     }
 
     /**
      * Builder for Access Policies.
      */
-    public static class AccessPolicyBuilder {
+    public static class Builder {
 
         private String identifier;
-        private Resource resource;
+        private String resource;
         private Set<String> users = new HashSet<>();
         private Set<String> groups = new HashSet<>();
         private Set<RequestAction> actions = new HashSet<>();
@@ -134,7 +130,7 @@ public class AccessPolicy {
         /**
          * Default constructor for building a new AccessPolicy.
          */
-        public AccessPolicyBuilder() {
+        public Builder() {
             this.fromPolicy = false;
         }
 
@@ -145,7 +141,7 @@ public class AccessPolicy {
          *
          * @param other the existing access policy to initialize from
          */
-        public AccessPolicyBuilder(final AccessPolicy other) {
+        public Builder(final AccessPolicy other) {
             if (other == null) {
                 throw new IllegalArgumentException("Can not initialize builder 
with a null access policy");
             }
@@ -168,7 +164,7 @@ public class AccessPolicy {
          * @return the builder
          * @throws IllegalStateException if this method is called when this 
builder was constructed from an existing Policy
          */
-        public AccessPolicyBuilder identifier(final String identifier) {
+        public Builder identifier(final String identifier) {
             if (fromPolicy) {
                 throw new IllegalStateException(
                         "Identifier can not be changed when initialized from 
an existing policy");
@@ -184,7 +180,7 @@ public class AccessPolicy {
          * @param resource the resource to set
          * @return the builder
          */
-        public AccessPolicyBuilder resource(final Resource resource) {
+        public Builder resource(final String resource) {
             this.resource = resource;
             return this;
         }
@@ -195,7 +191,7 @@ public class AccessPolicy {
          * @param users the users to add
          * @return the builder
          */
-        public AccessPolicyBuilder addUsers(final Set<String> users) {
+        public Builder addUsers(final Set<String> users) {
             if (users != null) {
                 this.users.addAll(users);
             }
@@ -208,7 +204,7 @@ public class AccessPolicy {
          * @param user the user to add
          * @return the builder
          */
-        public AccessPolicyBuilder addUser(final String user) {
+        public Builder addUser(final String user) {
             if (user != null) {
                 this.users.add(user);
             }
@@ -221,7 +217,7 @@ public class AccessPolicy {
          * @param users the users to remove
          * @return the builder
          */
-        public AccessPolicyBuilder removeUsers(final Set<String> users) {
+        public Builder removeUsers(final Set<String> users) {
             if (users != null) {
                 this.users.removeAll(users);
             }
@@ -234,7 +230,7 @@ public class AccessPolicy {
          * @param user the user to remove
          * @return the builder
          */
-        public AccessPolicyBuilder removeUser(final String user) {
+        public Builder removeUser(final String user) {
             if (user != null) {
                 this.users.remove(user);
             }
@@ -246,7 +242,7 @@ public class AccessPolicy {
          *
          * @return the builder
          */
-        public AccessPolicyBuilder clearUsers() {
+        public Builder clearUsers() {
             this.users.clear();
             return this;
         }
@@ -257,7 +253,7 @@ public class AccessPolicy {
          * @param groups the groups to add
          * @return the builder
          */
-        public AccessPolicyBuilder addGroups(final Set<String> groups) {
+        public Builder addGroups(final Set<String> groups) {
             if (groups != null) {
                 this.groups.addAll(groups);
             }
@@ -270,7 +266,7 @@ public class AccessPolicy {
          * @param group the group to add
          * @return the builder
          */
-        public AccessPolicyBuilder addGroup(final String group) {
+        public Builder addGroup(final String group) {
             if (group != null) {
                 this.groups.add(group);
             }
@@ -283,7 +279,7 @@ public class AccessPolicy {
          * @param groups the groups to remove
          * @return the builder
          */
-        public AccessPolicyBuilder removeGroups(final Set<String> groups) {
+        public Builder removeGroups(final Set<String> groups) {
             if (groups != null) {
                 this.groups.removeAll(groups);
             }
@@ -296,7 +292,7 @@ public class AccessPolicy {
          * @param group the group to remove
          * @return the builder
          */
-        public AccessPolicyBuilder removeGroup(final String group) {
+        public Builder removeGroup(final String group) {
             if (group != null) {
                 this.groups.remove(group);
             }
@@ -308,7 +304,7 @@ public class AccessPolicy {
          *
          * @return the builder
          */
-        public AccessPolicyBuilder clearGroups() {
+        public Builder clearGroups() {
             this.groups.clear();
             return this;
         }
@@ -319,7 +315,7 @@ public class AccessPolicy {
          * @param action the action to add
          * @return the builder
          */
-        public AccessPolicyBuilder addAction(final RequestAction action) {
+        public Builder addAction(final RequestAction action) {
             this.actions.add(action);
             return this;
         }
@@ -330,7 +326,7 @@ public class AccessPolicy {
          * @param action the action to remove
          * @return the builder
          */
-        public AccessPolicyBuilder removeAction(final RequestAction action) {
+        public Builder removeAction(final RequestAction action) {
             this.actions.remove(action);
             return this;
         }
@@ -340,7 +336,7 @@ public class AccessPolicy {
          *
          * @return the builder
          */
-        public AccessPolicyBuilder clearActions() {
+        public Builder clearActions() {
             this.actions.clear();
             return this;
         }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
 
b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
index 3721ab4..20cb69e 100644
--- 
a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
@@ -31,6 +31,11 @@ public interface AuthorizerConfigurationContext {
     String getIdentifier();
 
     /**
+     * @return the id of the root process group
+     */
+    String getRootGroupId();
+
+    /**
      * Retrieves all properties the component currently understands regardless
      * of whether a value has been set for them or not. If no value is present
      * then its value is null and thus any registered default for the property

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/main/java/org/apache/nifi/authorization/Group.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/Group.java 
b/nifi-api/src/main/java/org/apache/nifi/authorization/Group.java
index d7b0f2e..bb5c1e9 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/Group.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/Group.java
@@ -32,7 +32,7 @@ public class Group {
 
     private final Set<String> users;
 
-    private Group(final GroupBuilder builder) {
+    private Group(final Builder builder) {
         this.identifier = builder.identifier;
         this.name = builder.name;
         this.users = Collections.unmodifiableSet(new HashSet<>(builder.users));
@@ -61,6 +61,9 @@ public class Group {
     }
 
     /**
+     * NOTE: This set of users is populated when retrieving an existing group 
and  will be ignored when adding a new Group.
+     * To add a User to a group, it should be done by adding or updating a 
User with the appropriate Group id.
+     *
      * @return an unmodifiable set of user identifiers that belong to this 
group
      */
     public Set<String> getUsers() {
@@ -94,14 +97,14 @@ public class Group {
     /**
      * Builder for creating Groups.
      */
-    public static class GroupBuilder {
+    public static class Builder {
 
         private String identifier;
         private String name;
         private Set<String> users = new HashSet<>();
         private final boolean fromGroup;
 
-        public GroupBuilder() {
+        public Builder() {
             this.fromGroup = false;
         }
 
@@ -112,7 +115,7 @@ public class Group {
          *
          * @param other the existing access policy to initialize from
          */
-        public GroupBuilder(final Group other) {
+        public Builder(final Group other) {
             if (other == null) {
                 throw new IllegalArgumentException("Provided group can not be 
null");
             }
@@ -131,7 +134,7 @@ public class Group {
          * @return the builder
          * @throws IllegalStateException if this method is called when this 
builder was constructed from an existing Group
          */
-        public GroupBuilder identifier(final String identifier) {
+        public Builder identifier(final String identifier) {
             if (fromGroup) {
                 throw new IllegalStateException(
                         "Identifier can not be changed when initialized from 
an existing group");
@@ -147,7 +150,7 @@ public class Group {
          * @param name the name
          * @return the builder
          */
-        public GroupBuilder name(final String name) {
+        public Builder name(final String name) {
             this.name = name;
             return this;
         }
@@ -158,7 +161,7 @@ public class Group {
          * @param users a set of users to add
          * @return the builder
          */
-        public GroupBuilder addUsers(final Set<String> users) {
+        public Builder addUsers(final Set<String> users) {
             if (users != null) {
                 this.users.addAll(users);
             }
@@ -171,7 +174,7 @@ public class Group {
          * @param user the user to add
          * @return the builder
          */
-        public GroupBuilder addUser(final String user) {
+        public Builder addUser(final String user) {
             if (user != null) {
                 this.users.add(user);
             }
@@ -184,7 +187,7 @@ public class Group {
          * @param user the user to remove
          * @return the builder
          */
-        public GroupBuilder removeUser(final String user) {
+        public Builder removeUser(final String user) {
             if (user != null) {
                 this.users.remove(user);
             }
@@ -197,7 +200,7 @@ public class Group {
          * @param users the users to remove
          * @return the builder
          */
-        public GroupBuilder removeUsers(final Set<String> users) {
+        public Builder removeUsers(final Set<String> users) {
             if (users != null) {
                 this.users.removeAll(users);
             }
@@ -209,7 +212,7 @@ public class Group {
          *
          * @return the builder
          */
-        public GroupBuilder clearUsers() {
+        public Builder clearUsers() {
             this.users.clear();
             return this;
         }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/main/java/org/apache/nifi/authorization/User.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/User.java 
b/nifi-api/src/main/java/org/apache/nifi/authorization/User.java
index e068736..1e62d58 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/User.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/User.java
@@ -32,7 +32,7 @@ public class User {
 
     private final Set<String> groups;
 
-    private User(final UserBuilder builder) {
+    private User(final Builder builder) {
         this.identifier = builder.identifier;
         this.identity = builder.identity;
         this.groups = Collections.unmodifiableSet(new 
HashSet<>(builder.groups));
@@ -94,7 +94,7 @@ public class User {
     /**
      * Builder for Users.
      */
-    public static class UserBuilder {
+    public static class Builder {
 
         private String identifier;
         private String identity;
@@ -104,7 +104,7 @@ public class User {
         /**
          * Default constructor for building a new User.
          */
-        public UserBuilder() {
+        public Builder() {
             this.fromUser = false;
         }
 
@@ -115,7 +115,7 @@ public class User {
          *
          * @param other the existing user to initialize from
          */
-        public UserBuilder(final User other) {
+        public Builder(final User other) {
             if (other == null) {
                 throw new IllegalArgumentException("Provided user can not be 
null");
             }
@@ -134,7 +134,7 @@ public class User {
          * @return the builder
          * @throws IllegalStateException if this method is called when this 
builder was constructed from an existing User
          */
-        public UserBuilder identifier(final String identifier) {
+        public Builder identifier(final String identifier) {
             if (fromUser) {
                 throw new IllegalStateException(
                         "Identifier can not be changed when initialized from 
an existing user");
@@ -150,7 +150,7 @@ public class User {
          * @param identity the identity to set
          * @return the builder
          */
-        public UserBuilder identity(final String identity) {
+        public Builder identity(final String identity) {
             this.identity = identity;
             return this;
         }
@@ -161,7 +161,7 @@ public class User {
          * @param groups the groups to add
          * @return the builder
          */
-        public UserBuilder addGroups(final Set<String> groups) {
+        public Builder addGroups(final Set<String> groups) {
             if (groups != null) {
                 this.groups.addAll(groups);
             }
@@ -174,7 +174,7 @@ public class User {
          * @param group the group to add
          * @return the builder
          */
-        public UserBuilder addGroup(final String group) {
+        public Builder addGroup(final String group) {
             if (group != null) {
                 this.groups.add(group);
             }
@@ -187,7 +187,7 @@ public class User {
          * @param groups the groups to remove
          * @return the builder
          */
-        public UserBuilder removeGroups(final Set<String> groups) {
+        public Builder removeGroups(final Set<String> groups) {
             if (groups != null) {
                 this.groups.removeAll(groups);
             }
@@ -200,7 +200,7 @@ public class User {
          * @param group the group to remove
          * @return the builder
          */
-        public UserBuilder removeGroup(final String group) {
+        public Builder removeGroup(final String group) {
             if (group != null) {
                 this.groups.remove(group);
             }
@@ -212,7 +212,7 @@ public class User {
          *
          * @return the builder
          */
-        public UserBuilder clearGroups() {
+        public Builder clearGroups() {
             this.groups.clear();
             return this;
         }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java
 
b/nifi-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java
new file mode 100644
index 0000000..9a19977
--- /dev/null
+++ 
b/nifi-api/src/main/java/org/apache/nifi/authorization/UsersAndAccessPolicies.java
@@ -0,0 +1,43 @@
+/*
+ * 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.authorization;
+
+import java.util.Set;
+
+/**
+ * A holder object to provide atomic access to policies for a given resource 
and users by
+ * identity. Implementations must ensure consistent access to the data backing 
this instance.
+ */
+public interface UsersAndAccessPolicies {
+
+    /**
+     * Retrieves the set of access policies for a given resource.
+     *
+     * @param resourceIdentifier the resource identifier to retrieve policies 
for
+     * @return the set of access policies for the given resource
+     */
+    public Set<AccessPolicy> getAccessPolicies(final String 
resourceIdentifier);
+
+    /**
+     * Retrieves a user by an identity string.
+     *
+     * @param identity the identity of the user to retrieve
+     * @return the user with the given identity
+     */
+    public User getUser(final String identity);
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
 
b/nifi-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
index 8dbc781..3429a6d 100644
--- 
a/nifi-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
+++ 
b/nifi-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
@@ -42,26 +42,28 @@ public class TestAbstractPolicyBasedAuthorizer {
     @Test
     public void testApproveBasedOnUser() {
         AbstractPolicyBasedAuthorizer authorizer = 
Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+        UsersAndAccessPolicies usersAndAccessPolicies = 
Mockito.mock(UsersAndAccessPolicies.class);
+        
when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
 
         final String userIdentifier = "userIdentifier1";
         final String userIdentity = "userIdentity1";
 
         final Set<AccessPolicy> policiesForResource = new HashSet<>();
-        policiesForResource.add(new AccessPolicy.AccessPolicyBuilder()
+        policiesForResource.add(new AccessPolicy.Builder()
                 .identifier("1")
-                .resource(TEST_RESOURCE)
+                .resource(TEST_RESOURCE.getIdentifier())
                 .addUser(userIdentifier)
                 .addAction(RequestAction.READ)
                 .build());
 
-        
when(authorizer.getAccessPolicies(TEST_RESOURCE)).thenReturn(policiesForResource);
+        
when(usersAndAccessPolicies.getAccessPolicies(TEST_RESOURCE.getIdentifier())).thenReturn(policiesForResource);
 
-        final User user = new User.UserBuilder()
+        final User user = new User.Builder()
                 .identity(userIdentity)
                 .identifier(userIdentifier)
                 .build();
 
-        when(authorizer.getUserByIdentity(userIdentity)).thenReturn(user);
+        when(usersAndAccessPolicies.getUser(userIdentity)).thenReturn(user);
 
         final AuthorizationRequest request = new AuthorizationRequest.Builder()
                 .identity(userIdentity)
@@ -77,28 +79,30 @@ public class TestAbstractPolicyBasedAuthorizer {
     @Test
     public void testApprovedBasedOnGroup() {
         AbstractPolicyBasedAuthorizer authorizer = 
Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+        UsersAndAccessPolicies usersAndAccessPolicies = 
Mockito.mock(UsersAndAccessPolicies.class);
+        
when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
 
         final String userIdentifier = "userIdentifier1";
         final String userIdentity = "userIdentity1";
         final String groupIdentifier = "groupIdentifier1";
 
         final Set<AccessPolicy> policiesForResource = new HashSet<>();
-        policiesForResource.add(new AccessPolicy.AccessPolicyBuilder()
+        policiesForResource.add(new AccessPolicy.Builder()
                 .identifier("1")
-                .resource(TEST_RESOURCE)
+                .resource(TEST_RESOURCE.getIdentifier())
                 .addGroup(groupIdentifier)
                 .addAction(RequestAction.READ)
                 .build());
 
-        
when(authorizer.getAccessPolicies(TEST_RESOURCE)).thenReturn(policiesForResource);
+        
when(usersAndAccessPolicies.getAccessPolicies(TEST_RESOURCE.getIdentifier())).thenReturn(policiesForResource);
 
-        final User user = new User.UserBuilder()
+        final User user = new User.Builder()
                 .identity(userIdentity)
                 .identifier(userIdentifier)
                 .addGroup(groupIdentifier)
                 .build();
 
-        when(authorizer.getUserByIdentity(userIdentity)).thenReturn(user);
+        when(usersAndAccessPolicies.getUser(userIdentity)).thenReturn(user);
 
         final AuthorizationRequest request = new AuthorizationRequest.Builder()
                 .identity(userIdentity)
@@ -114,26 +118,28 @@ public class TestAbstractPolicyBasedAuthorizer {
     @Test
     public void testDeny() {
         AbstractPolicyBasedAuthorizer authorizer = 
Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+        UsersAndAccessPolicies usersAndAccessPolicies = 
Mockito.mock(UsersAndAccessPolicies.class);
+        
when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
 
         final String userIdentifier = "userIdentifier1";
         final String userIdentity = "userIdentity1";
 
         final Set<AccessPolicy> policiesForResource = new HashSet<>();
-        policiesForResource.add(new AccessPolicy.AccessPolicyBuilder()
+        policiesForResource.add(new AccessPolicy.Builder()
                 .identifier("1")
-                .resource(TEST_RESOURCE)
+                .resource(TEST_RESOURCE.getIdentifier())
                 .addUser("NOT_USER_1")
                 .addAction(RequestAction.READ)
                 .build());
 
-        
when(authorizer.getAccessPolicies(TEST_RESOURCE)).thenReturn(policiesForResource);
+        
when(usersAndAccessPolicies.getAccessPolicies(TEST_RESOURCE.getIdentifier())).thenReturn(policiesForResource);
 
-        final User user = new User.UserBuilder()
+        final User user = new User.Builder()
                 .identity(userIdentity)
                 .identifier(userIdentifier)
                 .build();
 
-        when(authorizer.getUserByIdentity(userIdentity)).thenReturn(user);
+        when(usersAndAccessPolicies.getUser(userIdentity)).thenReturn(user);
 
         final AuthorizationRequest request = new AuthorizationRequest.Builder()
                 .identity(userIdentity)
@@ -149,7 +155,10 @@ public class TestAbstractPolicyBasedAuthorizer {
     @Test
     public void testResourceNotFound() {
         AbstractPolicyBasedAuthorizer authorizer = 
Mockito.mock(AbstractPolicyBasedAuthorizer.class);
-        when(authorizer.getAccessPolicies(TEST_RESOURCE)).thenReturn(new 
HashSet<>());
+        UsersAndAccessPolicies usersAndAccessPolicies = 
Mockito.mock(UsersAndAccessPolicies.class);
+        
when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
+
+        
when(usersAndAccessPolicies.getAccessPolicies(TEST_RESOURCE.getIdentifier())).thenReturn(new
 HashSet<>());
 
         final AuthorizationRequest request = new AuthorizationRequest.Builder()
                 .identity("userIdentity")

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java 
b/nifi-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java
index 28c0b9f..35e1616 100644
--- a/nifi-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java
+++ b/nifi-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java
@@ -28,17 +28,7 @@ import static org.junit.Assert.fail;
 
 public class TestAccessPolicy {
 
-    static final Resource TEST_RESOURCE = new Resource() {
-        @Override
-        public String getIdentifier() {
-            return "1";
-        }
-
-        @Override
-        public String getName() {
-            return "resource1";
-        }
-    };
+    static final String TEST_RESOURCE = "1";
 
     @Test
     public void testSimpleCreation() {
@@ -47,7 +37,7 @@ public class TestAccessPolicy {
         final String user2 = "user2";
         final RequestAction action = RequestAction.READ;
 
-        final AccessPolicy policy = new AccessPolicy.AccessPolicyBuilder()
+        final AccessPolicy policy = new AccessPolicy.Builder()
                 .identifier(identifier)
                 .resource(TEST_RESOURCE)
                 .addUser(user1)
@@ -58,7 +48,7 @@ public class TestAccessPolicy {
         assertEquals(identifier, policy.getIdentifier());
 
         assertNotNull(policy.getResource());
-        assertEquals(TEST_RESOURCE.getIdentifier(), 
policy.getResource().getIdentifier());
+        assertEquals(TEST_RESOURCE, policy.getResource());
 
         assertNotNull(policy.getUsers());
         assertEquals(2, policy.getUsers().size());
@@ -72,7 +62,7 @@ public class TestAccessPolicy {
 
     @Test(expected = IllegalArgumentException.class)
     public void testMissingIdentifier() {
-        new AccessPolicy.AccessPolicyBuilder()
+        new AccessPolicy.Builder()
                 .resource(TEST_RESOURCE)
                 .addUser("user1")
                 .addAction(RequestAction.READ)
@@ -81,25 +71,27 @@ public class TestAccessPolicy {
 
     @Test(expected = IllegalArgumentException.class)
     public void testMissingResource() {
-        new AccessPolicy.AccessPolicyBuilder()
+        new AccessPolicy.Builder()
                 .identifier("1")
                 .addUser("user1")
                 .addAction(RequestAction.READ)
                 .build();
     }
 
-    @Test(expected = IllegalArgumentException.class)
+    @Test
     public void testMissingUsersAndGroups() {
-        new AccessPolicy.AccessPolicyBuilder()
+        final AccessPolicy policy = new AccessPolicy.Builder()
                 .identifier("1")
                 .resource(TEST_RESOURCE)
                 .addAction(RequestAction.READ)
                 .build();
+
+        assertNotNull(policy);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void testMissingActions() {
-        new AccessPolicy.AccessPolicyBuilder()
+        new AccessPolicy.Builder()
                 .identifier("1")
                 .resource(TEST_RESOURCE)
                 .addUser("user1")
@@ -115,7 +107,7 @@ public class TestAccessPolicy {
         final String group2 = "group2";
         final RequestAction action = RequestAction.READ;
 
-        final AccessPolicy policy = new AccessPolicy.AccessPolicyBuilder()
+        final AccessPolicy policy = new AccessPolicy.Builder()
                 .identifier(identifier)
                 .resource(TEST_RESOURCE)
                 .addUser(user1)
@@ -128,7 +120,7 @@ public class TestAccessPolicy {
         assertEquals(identifier, policy.getIdentifier());
 
         assertNotNull(policy.getResource());
-        assertEquals(TEST_RESOURCE.getIdentifier(), 
policy.getResource().getIdentifier());
+        assertEquals(TEST_RESOURCE, policy.getResource());
 
         assertNotNull(policy.getUsers());
         assertEquals(2, policy.getUsers().size());
@@ -144,28 +136,28 @@ public class TestAccessPolicy {
         assertEquals(1, policy.getActions().size());
         assertTrue(policy.getActions().contains(action));
 
-        final AccessPolicy policy2 = new 
AccessPolicy.AccessPolicyBuilder(policy).build();
+        final AccessPolicy policy2 = new AccessPolicy.Builder(policy).build();
         assertEquals(policy.getIdentifier(), policy2.getIdentifier());
-        assertEquals(policy.getResource().getIdentifier(), 
policy2.getResource().getIdentifier());
+        assertEquals(policy.getResource(), policy2.getResource());
         assertEquals(policy.getUsers(), policy2.getUsers());
         assertEquals(policy.getActions(), policy2.getActions());
     }
 
     @Test(expected = IllegalStateException.class)
     public void testFromPolicyAndChangeIdentifier() {
-        final AccessPolicy policy = new AccessPolicy.AccessPolicyBuilder()
+        final AccessPolicy policy = new AccessPolicy.Builder()
                 .identifier("1")
                 .resource(TEST_RESOURCE)
                 .addUser("user1")
                 .addAction(RequestAction.READ)
                 .build();
 
-        new AccessPolicy.AccessPolicyBuilder(policy).identifier("2").build();
+        new AccessPolicy.Builder(policy).identifier("2").build();
     }
 
     @Test
     public void testAddRemoveClearUsers() {
-        final AccessPolicy.AccessPolicyBuilder builder = new 
AccessPolicy.AccessPolicyBuilder()
+        final AccessPolicy.Builder builder = new AccessPolicy.Builder()
                 .identifier("1")
                 .resource(TEST_RESOURCE)
                 .addUser("user1")
@@ -201,17 +193,14 @@ public class TestAccessPolicy {
         assertEquals(1, policy4.getUsers().size());
         assertTrue(policy4.getUsers().contains("user2"));
 
-        try {
-            builder.clearUsers().build();
-            fail("should have thrown exception");
-        } catch (IllegalArgumentException e) {
 
-        }
+        final AccessPolicy policy5 = builder.clearUsers().build();
+        assertEquals(0, policy5.getUsers().size());
     }
 
     @Test
     public void testAddRemoveClearGroups() {
-        final AccessPolicy.AccessPolicyBuilder builder = new 
AccessPolicy.AccessPolicyBuilder()
+        final AccessPolicy.Builder builder = new AccessPolicy.Builder()
                 .identifier("1")
                 .resource(TEST_RESOURCE)
                 .addGroup("group1")
@@ -247,18 +236,13 @@ public class TestAccessPolicy {
         assertEquals(1, policy4.getGroups().size());
         assertTrue(policy4.getGroups().contains("group2"));
 
-        try {
-            builder.clearGroups().build();
-            fail("should have thrown exception");
-        } catch (IllegalArgumentException e) {
-
-        }
+        final AccessPolicy policy5 = builder.clearGroups().build();
+        assertEquals(0, policy5.getUsers().size());
     }
 
-
     @Test
     public void testAddRemoveClearActions() {
-        final AccessPolicy.AccessPolicyBuilder builder = new 
AccessPolicy.AccessPolicyBuilder()
+        final AccessPolicy.Builder builder = new AccessPolicy.Builder()
                 .identifier("1")
                 .resource(TEST_RESOURCE)
                 .addUser("user1")

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/test/java/org/apache/nifi/authorization/TestGroup.java
----------------------------------------------------------------------
diff --git 
a/nifi-api/src/test/java/org/apache/nifi/authorization/TestGroup.java 
b/nifi-api/src/test/java/org/apache/nifi/authorization/TestGroup.java
index 39dbab6..8ccdba5 100644
--- a/nifi-api/src/test/java/org/apache/nifi/authorization/TestGroup.java
+++ b/nifi-api/src/test/java/org/apache/nifi/authorization/TestGroup.java
@@ -34,7 +34,7 @@ public class TestGroup {
         final String user1 = "user1";
         final String user2 = "user2";
 
-        final Group group = new Group.GroupBuilder()
+        final Group group = new Group.Builder()
                 .identifier(id)
                 .name(name)
                 .addUser(user1)
@@ -52,7 +52,7 @@ public class TestGroup {
 
     @Test(expected = IllegalArgumentException.class)
     public void testMissingId() {
-        new Group.GroupBuilder()
+        new Group.Builder()
                 .name("group1")
                 .addUser("user1")
                 .addUser("user2")
@@ -61,7 +61,7 @@ public class TestGroup {
 
     @Test(expected = IllegalArgumentException.class)
     public void testMissingName() {
-        new Group.GroupBuilder()
+        new Group.Builder()
                 .identifier("1")
                 .addUser("user1")
                 .addUser("user2")
@@ -73,7 +73,7 @@ public class TestGroup {
         final String id = "1";
         final String name = "group1";
 
-        final Group group = new Group.GroupBuilder()
+        final Group group = new Group.Builder()
                 .identifier(id)
                 .name(name)
                 .build();
@@ -92,7 +92,7 @@ public class TestGroup {
         final String user1 = "user1";
         final String user2 = "user2";
 
-        final Group group1 = new Group.GroupBuilder()
+        final Group group1 = new Group.Builder()
                 .identifier(id)
                 .name(name)
                 .addUser(user1)
@@ -107,7 +107,7 @@ public class TestGroup {
         assertTrue(group1.getUsers().contains(user1));
         assertTrue(group1.getUsers().contains(user2));
 
-        final Group group2 = new Group.GroupBuilder(group1).build();
+        final Group group2 = new Group.Builder(group1).build();
         assertEquals(group1.getIdentifier(), group2.getIdentifier());
         assertEquals(group1.getName(), group2.getName());
         assertEquals(group1.getUsers(), group2.getUsers());
@@ -115,18 +115,18 @@ public class TestGroup {
 
     @Test(expected = IllegalStateException.class)
     public void testFromGroupAndChangeIdentifier() {
-        final Group group1 = new Group.GroupBuilder()
+        final Group group1 = new Group.Builder()
                 .identifier("1")
                 .name("group1")
                 .addUser("user1")
                 .build();
 
-        new Group.GroupBuilder(group1).identifier("2").build();
+        new Group.Builder(group1).identifier("2").build();
     }
 
     @Test
     public void testAddRemoveClearUsers() {
-        final Group.GroupBuilder builder = new Group.GroupBuilder()
+        final Group.Builder builder = new Group.Builder()
                 .identifier("1")
                 .name("group1")
                 .addUser("user1");

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-api/src/test/java/org/apache/nifi/authorization/TestUser.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/test/java/org/apache/nifi/authorization/TestUser.java 
b/nifi-api/src/test/java/org/apache/nifi/authorization/TestUser.java
index 8e6f9aa..483924a 100644
--- a/nifi-api/src/test/java/org/apache/nifi/authorization/TestUser.java
+++ b/nifi-api/src/test/java/org/apache/nifi/authorization/TestUser.java
@@ -34,7 +34,7 @@ public class TestUser {
         final String group1 = "group1";
         final String group2 = "group2";
 
-        final User user = new User.UserBuilder()
+        final User user = new User.Builder()
                 .identifier(identifier)
                 .identity(identity)
                 .addGroup(group1)
@@ -52,7 +52,7 @@ public class TestUser {
 
     @Test(expected = IllegalArgumentException.class)
     public void testMissingIdentifier() {
-        new User.UserBuilder()
+        new User.Builder()
                 .identity("user1")
                 .addGroup("group1")
                 .addGroup("group2")
@@ -61,7 +61,7 @@ public class TestUser {
 
     @Test(expected = IllegalArgumentException.class)
     public void testMissingIdentity() {
-        new User.UserBuilder()
+        new User.Builder()
                 .identifier("1")
                 .addGroup("group1")
                 .addGroup("group2")
@@ -73,7 +73,7 @@ public class TestUser {
         final String identifier = "1";
         final String identity = "user1";
 
-        final User user = new User.UserBuilder()
+        final User user = new User.Builder()
                 .identifier(identifier)
                 .identity(identity)
                 .build();
@@ -92,7 +92,7 @@ public class TestUser {
         final String group1 = "group1";
         final String group2 = "group2";
 
-        final User user = new User.UserBuilder()
+        final User user = new User.Builder()
                 .identifier(identifier)
                 .identity(identity)
                 .addGroup(group1)
@@ -107,7 +107,7 @@ public class TestUser {
         assertTrue(user.getGroups().contains(group1));
         assertTrue(user.getGroups().contains(group2));
 
-        final User user2 = new User.UserBuilder(user).build();
+        final User user2 = new User.Builder(user).build();
         assertEquals(user.getIdentifier(), user2.getIdentifier());
         assertEquals(user.getIdentity(), user2.getIdentity());
         assertEquals(user.getGroups(), user2.getGroups());
@@ -115,19 +115,19 @@ public class TestUser {
 
     @Test(expected = IllegalStateException.class)
     public void testFromUserAndChangeIdentifier() {
-        final User user = new User.UserBuilder()
+        final User user = new User.Builder()
                 .identifier("1")
                 .identity("user1")
                 .addGroup("group1")
                 .addGroup("group2")
                 .build();
 
-        new User.UserBuilder(user).identifier("2").build();
+        new User.Builder(user).identifier("2").build();
     }
 
     @Test
     public void testAddRemoveClearGroups() {
-        final User.UserBuilder builder = new User.UserBuilder()
+        final User.Builder builder = new User.Builder()
                 .identifier("1")
                 .identity("user1")
                 .addGroup("group1");

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
index 104aa10..6ddaf21 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/pom.xml
@@ -35,6 +35,10 @@
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-file-authorizer</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-authorizer</artifactId>
+        </dependency>
 
         <!-- mark these nifi artifacts as provided since it is included in the 
lib -->
         <dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
new file mode 100644
index 0000000..b8e1652
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>nifi-framework</artifactId>
+        <groupId>org.apache.nifi</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>nifi-authorizer</artifactId>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>src/main/xsd</directory>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>jaxb2-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>current</id>
+                        <goals>
+                            <goal>xjc</goal>
+                        </goals>
+                        <configuration>
+                            
<packageName>org.apache.nifi.authorization.generated</packageName>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <excludes>**/authorization/generated/*.java,</excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-framework-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-nar-utils</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
new file mode 100644
index 0000000..378c805
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
@@ -0,0 +1,347 @@
+/*
+ * 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.authorization;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.annotation.AuthorizerContext;
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.generated.Authorizers;
+import org.apache.nifi.authorization.generated.Property;
+import org.apache.nifi.controller.FlowController;
+import org.apache.nifi.nar.ExtensionManager;
+import org.apache.nifi.nar.NarCloseable;
+import org.apache.nifi.util.NiFiProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.xml.sax.SAXException;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Factory bean for loading the configured authorizer.
+ */
+public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, 
AuthorizerLookup {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(AuthorizerFactoryBean.class);
+    private static final String AUTHORIZERS_XSD = "/authorizers.xsd";
+    private static final String JAXB_GENERATED_PATH = 
"org.apache.nifi.authorization.generated";
+    private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
+
+    /**
+     * Load the JAXBContext.
+     */
+    private static JAXBContext initializeJaxbContext() {
+        try {
+            return JAXBContext.newInstance(JAXB_GENERATED_PATH, 
AuthorizerFactoryBean.class.getClassLoader());
+        } catch (JAXBException e) {
+            throw new RuntimeException("Unable to create JAXBContext.");
+        }
+    }
+
+    private Authorizer authorizer;
+    private NiFiProperties properties;
+    private FlowController flowController;
+    private final Map<String, Authorizer> authorizers = new HashMap<>();
+
+    public void setFlowController(FlowController flowController) {
+        this.flowController = flowController;
+    }
+
+    @Override
+    public Authorizer getAuthorizer(String identifier) {
+        return authorizers.get(identifier);
+    }
+
+    @Override
+    public Object getObject() throws Exception {
+        if (authorizer == null) {
+            if (properties.getSslPort() == null) {
+                // use a default authorizer... only allowable when running not 
securely
+                authorizer = createDefaultAuthorizer();
+            } else {
+                // look up the authorizer to use
+                final String authorizerIdentifier = 
properties.getProperty(NiFiProperties.SECURITY_USER_AUTHORIZER);
+
+                // ensure the authorizer class name was specified
+                if (StringUtils.isBlank(authorizerIdentifier)) {
+                    throw new Exception("When running securely, the authorizer 
identifier must be specified in the nifi properties file.");
+                } else {
+                    final Authorizers authorizerConfiguration = 
loadAuthorizersConfiguration();
+
+                    // create each authorizer
+                    for (final 
org.apache.nifi.authorization.generated.Authorizer authorizer : 
authorizerConfiguration.getAuthorizer()) {
+                        authorizers.put(authorizer.getIdentifier(), 
createAuthorizer(authorizer.getIdentifier(), authorizer.getClazz()));
+                    }
+
+                    // configure each authorizer
+                    for (final 
org.apache.nifi.authorization.generated.Authorizer provider : 
authorizerConfiguration.getAuthorizer()) {
+                        final Authorizer instance = 
authorizers.get(provider.getIdentifier());
+                        
instance.onConfigured(loadAuthorizerConfiguration(provider));
+                    }
+
+                    // get the authorizer instance
+                    authorizer = getAuthorizer(authorizerIdentifier);
+
+                    // ensure it was found
+                    if (authorizer == null) {
+                        throw new Exception(String.format("The specified 
authorizer '%s' could not be found.", authorizerIdentifier));
+                    }
+                }
+            }
+        }
+
+        return authorizer;
+    }
+
+    private Authorizers loadAuthorizersConfiguration() throws Exception {
+        final File authorizersConfigurationFile = 
properties.getAuthorizerConfiguraitonFile();
+
+        // load the authorizers from the specified file
+        if (authorizersConfigurationFile.exists()) {
+            try {
+                // find the schema
+                final SchemaFactory schemaFactory = 
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+                final Schema schema = 
schemaFactory.newSchema(Authorizers.class.getResource(AUTHORIZERS_XSD));
+
+                // attempt to unmarshal
+                final Unmarshaller unmarshaller = 
JAXB_CONTEXT.createUnmarshaller();
+                unmarshaller.setSchema(schema);
+                final JAXBElement<Authorizers> element = 
unmarshaller.unmarshal(new StreamSource(authorizersConfigurationFile), 
Authorizers.class);
+                return element.getValue();
+            } catch (SAXException | JAXBException e) {
+                throw new Exception("Unable to load the authorizer 
configuration file at: " + authorizersConfigurationFile.getAbsolutePath(), e);
+            }
+        } else {
+            throw new Exception("Unable to find the authorizer configuration 
file at " + authorizersConfigurationFile.getAbsolutePath());
+        }
+    }
+
+    private Authorizer createAuthorizer(final String identifier, final String 
authorizerClassName) throws Exception {
+        // get the classloader for the specified authorizer
+        final ClassLoader authorizerClassLoader = 
ExtensionManager.getClassLoader(authorizerClassName);
+        if (authorizerClassLoader == null) {
+            throw new Exception(String.format("The specified authorizer class 
'%s' is not known to this nifi.", authorizerClassName));
+        }
+
+        // get the current context classloader
+        final ClassLoader currentClassLoader = 
Thread.currentThread().getContextClassLoader();
+
+        final Authorizer instance;
+        try {
+            // set the appropriate class loader
+            
Thread.currentThread().setContextClassLoader(authorizerClassLoader);
+
+            // attempt to load the class
+            Class<?> rawAuthorizerClass = Class.forName(authorizerClassName, 
true, authorizerClassLoader);
+            Class<? extends Authorizer> authorizerClass = 
rawAuthorizerClass.asSubclass(Authorizer.class);
+
+            // otherwise create a new instance
+            Constructor constructor = authorizerClass.getConstructor();
+            instance = (Authorizer) constructor.newInstance();
+
+            // method injection
+            performMethodInjection(instance, authorizerClass);
+
+            // field injection
+            performFieldInjection(instance, authorizerClass);
+
+            // call post construction lifecycle event
+            instance.initialize(new 
StandardAuthorizerInitializationContext(identifier, this));
+        } finally {
+            if (currentClassLoader != null) {
+                
Thread.currentThread().setContextClassLoader(currentClassLoader);
+            }
+        }
+
+        return withNarLoader(instance);
+    }
+
+    private AuthorizerConfigurationContext loadAuthorizerConfiguration(final 
org.apache.nifi.authorization.generated.Authorizer authorizer) {
+        final Map<String, String> authorizerProperties = new HashMap<>();
+
+        for (final Property property : authorizer.getProperty()) {
+            authorizerProperties.put(property.getName(), property.getValue());
+        }
+
+        return new 
StandardAuthorizerConfigurationContext(authorizer.getIdentifier(), 
flowController.getRootGroupId(), authorizerProperties);
+    }
+
+    private void performMethodInjection(final Authorizer instance, final Class 
authorizerClass) throws IllegalAccessException, IllegalArgumentException, 
InvocationTargetException {
+        for (final Method method : authorizerClass.getMethods()) {
+            if (method.isAnnotationPresent(AuthorizerContext.class)) {
+                // make the method accessible
+                final boolean isAccessible = method.isAccessible();
+                method.setAccessible(true);
+
+                try {
+                    final Class<?>[] argumentTypes = 
method.getParameterTypes();
+
+                    // look for setters (single argument)
+                    if (argumentTypes.length == 1) {
+                        final Class<?> argumentType = argumentTypes[0];
+
+                        // look for well known types
+                        if 
(NiFiProperties.class.isAssignableFrom(argumentType)) {
+                            // nifi properties injection
+                            method.invoke(instance, properties);
+                        }
+                    }
+                } finally {
+                    method.setAccessible(isAccessible);
+                }
+            }
+        }
+
+        final Class parentClass = authorizerClass.getSuperclass();
+        if (parentClass != null && 
Authorizer.class.isAssignableFrom(parentClass)) {
+            performMethodInjection(instance, parentClass);
+        }
+    }
+
+    private void performFieldInjection(final Authorizer instance, final Class 
authorizerClass) throws IllegalArgumentException, IllegalAccessException {
+        for (final Field field : authorizerClass.getDeclaredFields()) {
+            if (field.isAnnotationPresent(AuthorizerContext.class)) {
+                // make the method accessible
+                final boolean isAccessible = field.isAccessible();
+                field.setAccessible(true);
+
+                try {
+                    // get the type
+                    final Class<?> fieldType = field.getType();
+
+                    // only consider this field if it isn't set yet
+                    if (field.get(instance) == null) {
+                        // look for well known types
+                        if (NiFiProperties.class.isAssignableFrom(fieldType)) {
+                            // nifi properties injection
+                            field.set(instance, properties);
+                        }
+                    }
+
+                } finally {
+                    field.setAccessible(isAccessible);
+                }
+            }
+        }
+
+        final Class parentClass = authorizerClass.getSuperclass();
+        if (parentClass != null && 
Authorizer.class.isAssignableFrom(parentClass)) {
+            performFieldInjection(instance, parentClass);
+        }
+    }
+
+    /**
+     * @return a default Authorizer to use when running unsecurely with no 
authorizer configured
+     */
+    private Authorizer createDefaultAuthorizer() {
+        return new Authorizer() {
+            @Override
+            public AuthorizationResult authorize(final AuthorizationRequest 
request) throws AuthorizationAccessException {
+                return AuthorizationResult.approved();
+            }
+
+            @Override
+            public void initialize(AuthorizerInitializationContext 
initializationContext) throws AuthorizerCreationException {
+            }
+
+            @Override
+            public void onConfigured(AuthorizerConfigurationContext 
configurationContext) throws AuthorizerCreationException {
+            }
+
+            @Override
+            public void preDestruction() throws AuthorizerDestructionException 
{
+            }
+        };
+    }
+
+    /**
+     * Decorates the base authorizer to ensure the nar context classloader is 
used when invoking the underlying methods.
+     *
+     * @param baseAuthorizer base authorizer
+     * @return authorizer
+     */
+    public Authorizer withNarLoader(final Authorizer baseAuthorizer) {
+        return new Authorizer() {
+            @Override
+            public AuthorizationResult authorize(final AuthorizationRequest 
request) throws AuthorizationAccessException {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    return baseAuthorizer.authorize(request);
+                }
+            }
+
+            @Override
+            public void initialize(AuthorizerInitializationContext 
initializationContext) throws AuthorizerCreationException {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    baseAuthorizer.initialize(initializationContext);
+                }
+            }
+
+            @Override
+            public void onConfigured(AuthorizerConfigurationContext 
configurationContext) throws AuthorizerCreationException {
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    baseAuthorizer.onConfigured(configurationContext);
+                }
+            }
+
+            @Override
+            public void preDestruction() throws AuthorizerDestructionException 
{
+                try (final NarCloseable narCloseable = 
NarCloseable.withNarLoader()) {
+                    baseAuthorizer.preDestruction();
+                }
+            }
+        };
+    }
+
+    @Override
+    public Class getObjectType() {
+        return Authorizer.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    @Override
+    public void destroy() throws Exception {
+        if (authorizer != null) {
+            authorizer.preDestruction();
+        }
+    }
+
+    public void setProperties(NiFiProperties properties) {
+        this.properties = properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
new file mode 100644
index 0000000..b95db11
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<beans default-lazy-init="true"
+       xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd";>
+
+    <!-- user/entity authorizer -->
+    <bean id="authorizer" 
class="org.apache.nifi.authorization.AuthorizerFactoryBean">
+        <property name="properties" ref="nifiProperties"/>
+        <property name="flowController" ref="flowController"/>
+    </bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/xsd/authorizers.xsd
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/xsd/authorizers.xsd
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/xsd/authorizers.xsd
new file mode 100644
index 0000000..4b68b00
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/xsd/authorizers.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";>
+    <!-- role -->
+    <xs:complexType name="Authorizer">
+        <xs:sequence>
+            <xs:element name="identifier" type="NonEmptyStringType"/>
+            <xs:element name="class" type="NonEmptyStringType"/>
+            <xs:element name="property" type="Property" minOccurs="0" 
maxOccurs="unbounded" />
+        </xs:sequence>
+    </xs:complexType>
+
+    <!-- Name/Value properties-->
+    <xs:complexType name="Property">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute name="name" 
type="NonEmptyStringType"></xs:attribute>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:simpleType name="NonEmptyStringType">
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <!-- users -->
+    <xs:element name="authorizers">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="authorizer" type="Authorizer" minOccurs="0" 
maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
index 0673b97..4f97220 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
@@ -36,14 +36,28 @@
                 <artifactId>jaxb2-maven-plugin</artifactId>
                 <executions>
                     <execution>
-                        <id>xjc</id>
+                        <id>authorizations</id>
                         <goals>
                             <goal>xjc</goal>
                         </goals>
                         <configuration>
+                            <schemaDirectory>src/main/xsd</schemaDirectory>
+                            <schemaFiles>authorizations.xsd</schemaFiles>
                             
<packageName>org.apache.nifi.authorization.file.generated</packageName>
                         </configuration>
                     </execution>
+                    <execution>
+                        <id>users</id>
+                        <goals>
+                            <goal>xjc</goal>
+                        </goals>
+                        <configuration>
+                            <schemaDirectory>src/main/xsd</schemaDirectory>
+                            <schemaFiles>users.xsd</schemaFiles>
+                            
<packageName>org.apache.nifi.user.generated</packageName>
+                            <clearOutputDir>false</clearOutputDir>
+                        </configuration>
+                    </execution>
                 </executions>
                 <configuration>
                     
<outputDirectory>${project.build.directory}/generated-sources/jaxb</outputDirectory>
@@ -53,7 +67,7 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
                 <configuration>
-                    <excludes>**/authorization/file/generated/*.java</excludes>
+                    
<excludes>**/authorization/file/generated/*.java,**/user/generated/*.java</excludes>
                 </configuration>
             </plugin>            
         </plugins>

http://git-wip-us.apache.org/repos/asf/nifi/blob/8d8a9cba/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizationsHolder.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizationsHolder.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizationsHolder.java
new file mode 100644
index 0000000..e98eed9
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizationsHolder.java
@@ -0,0 +1,355 @@
+/*
+ * 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.authorization;
+
+
+import org.apache.nifi.authorization.file.generated.Authorizations;
+import org.apache.nifi.authorization.file.generated.Groups;
+import org.apache.nifi.authorization.file.generated.Policies;
+import org.apache.nifi.authorization.file.generated.Users;
+
+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 data structures.
+ */
+public class AuthorizationsHolder implements UsersAndAccessPolicies {
+
+    private final Authorizations authorizations;
+
+    private final Set<AccessPolicy> allPolicies;
+    private final Map<String, Set<AccessPolicy>> policiesByResource;
+    private final Map<String, AccessPolicy> policiesById;
+
+    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;
+
+    /**
+     * Creates a new holder and populates all convenience data structures.
+     *
+     * @param authorizations the current authorizations instance
+     */
+    public AuthorizationsHolder(final Authorizations authorizations) {
+        this.authorizations = authorizations;
+
+        // load all users
+        final Users users = authorizations.getUsers();
+        final Set<User> allUsers = 
Collections.unmodifiableSet(createUsers(users));
+
+        // load all groups
+        final Groups groups = authorizations.getGroups();
+        final Set<Group> allGroups = 
Collections.unmodifiableSet(createGroups(groups, users));
+
+        // load all access policies
+        final Policies policies = authorizations.getPolicies();
+        final Set<AccessPolicy> allPolicies = 
Collections.unmodifiableSet(createAccessPolicies(policies));
+
+        // 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 from resource id to policies
+        final Map<String, Set<AccessPolicy>> policiesByResourceMap = 
Collections.unmodifiableMap(createResourcePolicyMap(allPolicies));
+
+        // create a convenience map from policy id to policy
+        final Map<String, AccessPolicy> policiesByIdMap = 
Collections.unmodifiableMap(createPoliciesByIdMap(allPolicies));
+
+        // set all the holders
+        this.allUsers = allUsers;
+        this.allGroups = allGroups;
+        this.allPolicies = allPolicies;
+        this.usersById = userByIdMap;
+        this.usersByIdentity = userByIdentityMap;
+        this.groupsById = groupByIdMap;
+        this.policiesByResource = policiesByResourceMap;
+        this.policiesById = policiesByIdMap;
+    }
+
+    /**
+     * Creates AccessPolicies from the JAXB Policies.
+     *
+     * @param policies the JAXB Policies element
+     * @return a set of AccessPolicies corresponding to the provided Resources
+     */
+    private Set<AccessPolicy> 
createAccessPolicies(org.apache.nifi.authorization.file.generated.Policies 
policies) {
+        Set<AccessPolicy> allPolicies = new HashSet<>();
+        if (policies == null || policies.getPolicy() == null) {
+            return allPolicies;
+        }
+
+        // load the new authorizations
+        for (final org.apache.nifi.authorization.file.generated.Policy policy 
: policies.getPolicy()) {
+            final String policyIdentifier = policy.getIdentifier();
+            final String resourceIdentifier = policy.getResource();
+
+            // start a new builder and set the policy and resource identifiers
+            final AccessPolicy.Builder builder = new AccessPolicy.Builder()
+                    .identifier(policyIdentifier)
+                    .resource(resourceIdentifier);
+
+            // add each user identifier
+            for (org.apache.nifi.authorization.file.generated.Policy.User user 
: policy.getUser()) {
+                builder.addUser(user.getIdentifier());
+            }
+
+            // add each group identifier
+            for (org.apache.nifi.authorization.file.generated.Policy.Group 
group : policy.getGroup()) {
+                builder.addGroup(group.getIdentifier());
+            }
+
+            // add the appropriate request actions
+            final String authorizationCode = policy.getAction();
+            if (authorizationCode.contains(FileAuthorizer.READ_CODE)) {
+                builder.addAction(RequestAction.READ);
+            }
+            if (authorizationCode.contains(FileAuthorizer.WRITE_CODE)) {
+                builder.addAction(RequestAction.WRITE);
+            }
+
+            // build the policy and add it to the map
+            allPolicies.add(builder.build());
+        }
+
+        return allPolicies;
+    }
+
+    /**
+     * Creates a set of Users from the JAXB Users.
+     *
+     * @param users the JAXB Users
+     * @return a set of API Users matching the provided JAXB Users
+     */
+    private Set<User> 
createUsers(org.apache.nifi.authorization.file.generated.Users users) {
+        Set<User> allUsers = new HashSet<>();
+        if (users == null || users.getUser() == null) {
+            return allUsers;
+        }
+
+        for (org.apache.nifi.authorization.file.generated.User user : 
users.getUser()) {
+            final User.Builder builder = new User.Builder()
+                    .identity(user.getIdentity())
+                    .identifier(user.getIdentifier());
+
+            if (user.getGroup() != null) {
+                for (org.apache.nifi.authorization.file.generated.User.Group 
group : user.getGroup()) {
+                    builder.addGroup(group.getIdentifier());
+                }
+            }
+
+            allUsers.add(builder.build());
+        }
+
+        return allUsers;
+    }
+
+    /**
+     * Creates a set of Groups from the JAXB Groups.
+     *
+     * @param groups the JAXB Groups
+     * @return a set of API Groups matching the provided JAXB Groups
+     */
+    private Set<Group> 
createGroups(org.apache.nifi.authorization.file.generated.Groups groups,
+                                    
org.apache.nifi.authorization.file.generated.Users users) {
+        Set<Group> allGroups = new HashSet<>();
+        if (groups == null || groups.getGroup() == null) {
+            return allGroups;
+        }
+
+        for (org.apache.nifi.authorization.file.generated.Group group : 
groups.getGroup()) {
+            final Group.Builder builder = new Group.Builder()
+                    .identifier(group.getIdentifier())
+                    .name(group.getName());
+
+            // need to figured out what users are in this group by going 
through the users list
+            final Set<String> groupUsers = getUsersForGroup(users, 
group.getIdentifier());
+            builder.addUsers(groupUsers);
+
+            allGroups.add(builder.build());
+        }
+
+        return allGroups;
+    }
+
+    /**
+     * Gets the set of user identifiers that are part of the given group.
+     *
+     * @param users the JAXB Users element
+     * @param groupId the group id to get the users for
+     * @return the user identifiers that belong to the group with the given 
identifier
+     */
+    private Set<String> 
getUsersForGroup(org.apache.nifi.authorization.file.generated.Users users, 
final String groupId) {
+        Set<String> groupUsers = new HashSet<>();
+
+        if (users != null && users.getUser()!= null) {
+            for (org.apache.nifi.authorization.file.generated.User user : 
users.getUser()) {
+                if (user.getGroup() != null) {
+                    for 
(org.apache.nifi.authorization.file.generated.User.Group group : 
user.getGroup()) {
+                        if (group.getIdentifier().equals(groupId)) {
+                            groupUsers.add(user.getIdentifier());
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        return groupUsers;
+    }
+
+    /**
+     * Creates a map from resource identifier to the set of policies for the 
given resource.
+     *
+     * @param allPolicies the set of all policies
+     * @return a map from resource identifier to policies
+     */
+    private Map<String, Set<AccessPolicy>> createResourcePolicyMap(final 
Set<AccessPolicy> allPolicies) {
+        Map<String, Set<AccessPolicy>> resourcePolicies = new HashMap<>();
+
+        for (AccessPolicy policy : allPolicies) {
+            Set<AccessPolicy> policies = 
resourcePolicies.get(policy.getResource());
+            if (policies == null) {
+                policies = new HashSet<>();
+                resourcePolicies.put(policy.getResource(), policies);
+            }
+            policies.add(policy);
+        }
+
+        return resourcePolicies;
+    }
+
+    /**
+     * 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 policy identifier to AccessPolicy.
+     *
+     * @param policies the set of all access policies
+     * @return the Map from policy identifier to AccessPolicy
+     */
+    private Map<String, AccessPolicy> createPoliciesByIdMap(final 
Set<AccessPolicy> policies) {
+        Map<String,AccessPolicy> policyMap = new HashMap<>();
+        for (AccessPolicy policy : policies) {
+            policyMap.put(policy.getIdentifier(), policy);
+        }
+        return policyMap;
+    }
+
+    public Authorizations getAuthorizations() {
+        return authorizations;
+    }
+
+    public Set<AccessPolicy> getAllPolicies() {
+        return allPolicies;
+    }
+
+    public Map<String, Set<AccessPolicy>> getPoliciesByResource() {
+        return policiesByResource;
+    }
+
+    public Map<String, AccessPolicy> getPoliciesById() {
+        return policiesById;
+    }
+
+    public Set<User> getAllUsers() {
+        return allUsers;
+    }
+
+    public Map<String, User> getUsersById() {
+        return usersById;
+    }
+
+    public Map<String, User> getUsersByIdentity() {
+        return usersByIdentity;
+    }
+
+    public Set<Group> getAllGroups() {
+        return allGroups;
+    }
+
+    public Map<String, Group> getGroupsById() {
+        return groupsById;
+    }
+
+    @Override
+    public Set<AccessPolicy> getAccessPolicies(String resourceIdentifier) {
+        if (resourceIdentifier == null) {
+            throw new IllegalArgumentException("Resource Identifier cannot be 
null");
+        }
+        return policiesByResource.get(resourceIdentifier);
+    }
+
+    @Override
+    public User getUser(String identity) {
+        if (identity == null) {
+            throw new IllegalArgumentException("Identity cannot be null");
+        }
+        return usersByIdentity.get(identity);
+    }
+
+}

Reply via email to