http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
new file mode 100644
index 0000000..ea7c1a1
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/dao/impl/StandardUserDAO.java
@@ -0,0 +1,634 @@
+/*
+ * 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.admin.dao.impl;
+
+import java.nio.charset.StandardCharsets;
+import java.sql.Connection;
+import org.apache.nifi.admin.dao.UserDAO;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import org.apache.nifi.admin.RepositoryUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.authorization.Authority;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUser;
+
+/**
+ * Responsible for loading and persisting NiFiUsers.
+ */
+public class StandardUserDAO implements UserDAO {
+
+    private static final String SELECT_PENDING_ACCOUNTS_COUNT = "SELECT "
+            + "COUNT(*) as PENDING_ACCOUNTS "
+            + "FROM USER U "
+            + "WHERE U.STATUS = 'PENDING'";
+
+    private static final String SELECT_USER_BY_DN = "SELECT "
+            + "U.ID, "
+            + "U.DN, "
+            + "U.USER_NAME, "
+            + "U.USER_GROUP, "
+            + "U.CREATION, "
+            + "U.LAST_ACCESSED, "
+            + "U.LAST_VERIFIED, "
+            + "U.JUSTIFICATION, "
+            + "U.STATUS, "
+            + "A.ROLE "
+            + "FROM USER U "
+            + "LEFT JOIN AUTHORITY A " // ensures that users without 
authorities are still matched
+            + "ON U.ID = A.USER_ID "
+            + "WHERE U.DN = ?";
+
+    private static final String SELECT_USER_BY_ID = "SELECT "
+            + "U.ID, "
+            + "U.DN, "
+            + "U.USER_NAME, "
+            + "U.USER_GROUP, "
+            + "U.CREATION, "
+            + "U.LAST_ACCESSED, "
+            + "U.LAST_VERIFIED, "
+            + "U.JUSTIFICATION, "
+            + "U.STATUS, "
+            + "A.ROLE "
+            + "FROM USER U "
+            + "LEFT JOIN AUTHORITY A " // ensures that users without 
authorities are still matched
+            + "ON U.ID = A.USER_ID "
+            + "WHERE U.ID = ?";
+
+    private static final String SELECT_USERS = "SELECT "
+            + "U.ID, "
+            + "U.DN, "
+            + "U.USER_NAME, "
+            + "U.USER_GROUP, "
+            + "U.CREATION, "
+            + "U.LAST_ACCESSED, "
+            + "U.LAST_VERIFIED, "
+            + "U.JUSTIFICATION, "
+            + "U.STATUS, "
+            + "A.ROLE "
+            + "FROM USER U "
+            + "LEFT JOIN AUTHORITY A " // ensures that users without 
authorities are still matched
+            + "ON U.ID = A.USER_ID "
+            + "WHERE U.DN <> ?";
+
+    private static final String SELECT_USER_GROUPS = "SELECT DISTINCT "
+            + "U.USER_GROUP "
+            + "FROM USER U";
+
+    private static final String SELECT_USER_GROUP = "SELECT "
+            + "U.ID, "
+            + "U.DN, "
+            + "U.USER_NAME, "
+            + "U.USER_GROUP, "
+            + "U.CREATION, "
+            + "U.LAST_ACCESSED, "
+            + "U.LAST_VERIFIED, "
+            + "U.JUSTIFICATION, "
+            + "U.STATUS, "
+            + "A.ROLE "
+            + "FROM USER U "
+            + "LEFT JOIN AUTHORITY A " // ensures that users without 
authorities are still matched
+            + "ON U.ID = A.USER_ID "
+            + "WHERE U.DN <> ? AND U.USER_GROUP = ?";
+
+    private static final String INSERT_USER = "INSERT INTO USER ("
+            + "ID, DN, USER_NAME, USER_GROUP, CREATION, LAST_VERIFIED, 
JUSTIFICATION, STATUS"
+            + ") VALUES ("
+            + "?, "
+            + "?, "
+            + "?, "
+            + "?, "
+            + "NOW(), "
+            + "?, "
+            + "?, "
+            + "?"
+            + ")";
+
+    private static final String UPDATE_USER = "UPDATE USER SET "
+            + "DN = ?, "
+            + "USER_NAME = ?, "
+            + "USER_GROUP = ?, "
+            + "LAST_ACCESSED = ?, "
+            + "LAST_VERIFIED = ?, "
+            + "JUSTIFICATION = ?, "
+            + "STATUS = ? "
+            + "WHERE ID = ?";
+
+    private static final String UPDATE_USER_GROUP_STATUS = "UPDATE USER SET "
+            + "STATUS = ?,"
+            + "USER_GROUP = NULL "
+            + "WHERE USER_GROUP = ?";
+
+    private static final String UPDATE_USER_GROUP_VERIFICATION = "UPDATE USER 
SET "
+            + "LAST_VERIFIED = ? "
+            + "WHERE USER_GROUP = ?";
+
+    private static final String UNGROUP_GROUP = "UPDATE USER SET "
+            + "USER_GROUP = NULL "
+            + "WHERE USER_GROUP = ?";
+
+    private static final String DELETE_USER = "DELETE FROM USER "
+            + "WHERE ID = ?";
+
+    private final Connection connection;
+
+    public StandardUserDAO(Connection connection) {
+        this.connection = connection;
+    }
+
+    @Override
+    public Boolean hasPendingUserAccounts() throws DataAccessException {
+        PreparedStatement statement = null;
+        ResultSet rs = null;
+        try {
+            // create the connection and obtain a statement
+            statement = 
connection.prepareStatement(SELECT_PENDING_ACCOUNTS_COUNT);
+
+            // execute the query
+            rs = statement.executeQuery();
+
+            // get the first row which will contain the number of pending 
accounts
+            if (rs.next()) {
+                int pendingAccounts = rs.getInt("PENDING_ACCOUNTS");
+                return pendingAccounts > 0;
+            }
+
+            // query returned no results?
+            return false;
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } finally {
+            RepositoryUtils.closeQuietly(rs);
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public Set<NiFiUser> findUsers() throws DataAccessException {
+        Set<NiFiUser> users = new HashSet<>();
+
+        PreparedStatement statement = null;
+        ResultSet rs = null;
+        try {
+            // create the connection and obtain a statement
+            statement = connection.prepareStatement(SELECT_USERS);
+            statement.setString(1, NiFiUser.ANONYMOUS_USER_DN);
+
+            // execute the query
+            rs = statement.executeQuery();
+
+            // create the user
+            NiFiUser user = null;
+
+            // go through the user and its roles
+            while (rs.next()) {
+                // get the user id for the current record
+                String userId = rs.getString("ID");
+
+                // create the user during the first iteration
+                if (user == null || !userId.equals(user.getId())) {
+                    user = new NiFiUser();
+                    user.setId(userId);
+                    user.setDn(rs.getString("DN"));
+                    user.setUserName(rs.getString("USER_NAME"));
+                    user.setUserGroup(rs.getString("USER_GROUP"));
+                    user.setJustification(rs.getString("JUSTIFICATION"));
+                    
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
+
+                    // set the creation date
+                    user.setCreation(new 
Date(rs.getTimestamp("CREATION").getTime()));
+
+                    // get the last accessed date
+                    if (rs.getTimestamp("LAST_ACCESSED") != null) {
+                        user.setLastAccessed(new 
Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
+                    }
+
+                    // get the last verified date
+                    if (rs.getTimestamp("LAST_VERIFIED") != null) {
+                        user.setLastVerified(new 
Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
+                    }
+
+                    // add the user
+                    users.add(user);
+                }
+
+                // the select statement performs a left join since the desired
+                // user may not have any authorities
+                String authority = rs.getString("ROLE");
+                if (StringUtils.isNotBlank(authority)) {
+                    
user.getAuthorities().add(Authority.valueOfAuthority(authority));
+                }
+            }
+
+            return users;
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } finally {
+            RepositoryUtils.closeQuietly(rs);
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public Set<String> findUserGroups() throws DataAccessException {
+        Set<String> userGroups = new HashSet<>();
+
+        PreparedStatement statement = null;
+        ResultSet rs = null;
+        try {
+            // create the connection and obtain a statement
+            statement = connection.prepareStatement(SELECT_USER_GROUPS);
+
+            // execute the query
+            rs = statement.executeQuery();
+
+            // get each user group
+            while (rs.next()) {
+                userGroups.add(rs.getString("USER_GROUP"));
+            }
+
+            return userGroups;
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } finally {
+            RepositoryUtils.closeQuietly(rs);
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public Set<NiFiUser> findUsersForGroup(String group) throws 
DataAccessException {
+        Set<NiFiUser> users = new HashSet<>();
+
+        PreparedStatement statement = null;
+        ResultSet rs = null;
+        try {
+            // create the connection and obtain a statement
+            statement = connection.prepareStatement(SELECT_USER_GROUP);
+            statement.setString(1, NiFiUser.ANONYMOUS_USER_DN);
+            statement.setString(2, group);
+
+            // execute the query
+            rs = statement.executeQuery();
+
+            // create the user
+            NiFiUser user = null;
+
+            // go through the user and its roles
+            while (rs.next()) {
+                // get the user id for the current record
+                String userId = rs.getString("ID");
+
+                // create the user during the first iteration
+                if (user == null || !userId.equals(user.getId())) {
+                    user = new NiFiUser();
+                    user.setId(userId);
+                    user.setDn(rs.getString("DN"));
+                    user.setUserName(rs.getString("USER_NAME"));
+                    user.setUserGroup(rs.getString("USER_GROUP"));
+                    user.setJustification(rs.getString("JUSTIFICATION"));
+                    
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
+
+                    // set the creation date
+                    user.setCreation(new 
Date(rs.getTimestamp("CREATION").getTime()));
+
+                    // get the last accessed date
+                    if (rs.getTimestamp("LAST_ACCESSED") != null) {
+                        user.setLastAccessed(new 
Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
+                    }
+
+                    // get the last verified date
+                    if (rs.getTimestamp("LAST_VERIFIED") != null) {
+                        user.setLastVerified(new 
Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
+                    }
+
+                    // add the user
+                    users.add(user);
+                }
+
+                // the select statement performs a left join since the desired
+                // user may not have any authorities
+                String authority = rs.getString("ROLE");
+                if (StringUtils.isNotBlank(authority)) {
+                    
user.getAuthorities().add(Authority.valueOfAuthority(authority));
+                }
+            }
+
+            return users;
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } finally {
+            RepositoryUtils.closeQuietly(rs);
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public NiFiUser findUserById(String id) throws DataAccessException {
+        PreparedStatement statement = null;
+        ResultSet rs = null;
+        try {
+            // create the connection and obtain a statement
+            statement = connection.prepareStatement(SELECT_USER_BY_ID);
+            statement.setString(1, id);
+
+            // execute the query
+            rs = statement.executeQuery();
+
+            // create the user
+            NiFiUser user = null;
+
+            // go through the user and its roles
+            while (rs.next()) {
+                // create the user during the first iteration
+                if (user == null) {
+                    user = new NiFiUser();
+                    user.setId(rs.getString("ID"));
+                    user.setDn(rs.getString("DN"));
+                    user.setUserName(rs.getString("USER_NAME"));
+                    user.setUserGroup(rs.getString("USER_GROUP"));
+                    user.setJustification(rs.getString("JUSTIFICATION"));
+                    
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
+
+                    // set the creation date
+                    user.setCreation(new 
Date(rs.getTimestamp("CREATION").getTime()));
+
+                    // get the last accessed date
+                    if (rs.getTimestamp("LAST_ACCESSED") != null) {
+                        user.setLastAccessed(new 
Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
+                    }
+
+                    // get the last verified date
+                    if (rs.getTimestamp("LAST_VERIFIED") != null) {
+                        user.setLastVerified(new 
Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
+                    }
+                }
+
+                // the select statement performs a left join since the desired
+                // user may not have any authorities
+                String authority = rs.getString("ROLE");
+                if (StringUtils.isNotBlank(authority)) {
+                    
user.getAuthorities().add(Authority.valueOfAuthority(authority));
+                }
+            }
+
+            return user;
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } finally {
+            RepositoryUtils.closeQuietly(rs);
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public NiFiUser findUserByDn(String dn) throws DataAccessException {
+        PreparedStatement statement = null;
+        ResultSet rs = null;
+        try {
+            // create the connection and obtain a statement
+            statement = connection.prepareStatement(SELECT_USER_BY_DN);
+            statement.setString(1, dn);
+
+            // execute the query
+            rs = statement.executeQuery();
+
+            // create the user
+            NiFiUser user = null;
+
+            // go through the user and its roles
+            while (rs.next()) {
+                // create the user during the first iteration
+                if (user == null) {
+                    user = new NiFiUser();
+                    user.setId(rs.getString("ID"));
+                    user.setDn(rs.getString("DN"));
+                    user.setUserName(rs.getString("USER_NAME"));
+                    user.setUserGroup(rs.getString("USER_GROUP"));
+                    user.setJustification(rs.getString("JUSTIFICATION"));
+                    
user.setStatus(AccountStatus.valueOfStatus(rs.getString("STATUS")));
+
+                    // set the creation date
+                    user.setCreation(new 
Date(rs.getTimestamp("CREATION").getTime()));
+
+                    // get the last accessed date
+                    if (rs.getTimestamp("LAST_ACCESSED") != null) {
+                        user.setLastAccessed(new 
Date(rs.getTimestamp("LAST_ACCESSED").getTime()));
+                    }
+
+                    // get the last verified date
+                    if (rs.getTimestamp("LAST_VERIFIED") != null) {
+                        user.setLastVerified(new 
Date(rs.getTimestamp("LAST_VERIFIED").getTime()));
+                    }
+                }
+
+                // the select statement performs a left join since the desired
+                // user may not have any authorities
+                String authority = rs.getString("ROLE");
+                if (StringUtils.isNotBlank(authority)) {
+                    
user.getAuthorities().add(Authority.valueOfAuthority(authority));
+                }
+            }
+
+            return user;
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } finally {
+            RepositoryUtils.closeQuietly(rs);
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public void createUser(NiFiUser user) throws DataAccessException {
+        if (user.getDn() == null) {
+            throw new IllegalArgumentException("User dn must be specified.");
+        }
+
+        PreparedStatement statement = null;
+        ResultSet rs = null;
+        try {
+            final String id = 
UUID.nameUUIDFromBytes(user.getDn().getBytes(StandardCharsets.UTF_8)).toString();
+
+            // create a statement
+            statement = connection.prepareStatement(INSERT_USER, 
Statement.RETURN_GENERATED_KEYS);
+            statement.setString(1, id);
+            statement.setString(2, StringUtils.left(user.getDn(), 255));
+            statement.setString(3, StringUtils.left(user.getUserName(), 100));
+            statement.setString(4, StringUtils.left(user.getUserGroup(), 100));
+            if (user.getLastVerified() != null) {
+                statement.setTimestamp(5, new 
java.sql.Timestamp(user.getLastVerified().getTime()));
+            } else {
+                statement.setTimestamp(5, null);
+            }
+            statement.setString(6, StringUtils.left(user.getJustification(), 
500));
+            statement.setString(7, user.getStatus().toString());
+
+            // insert the user
+            int updateCount = statement.executeUpdate();
+            if (updateCount == 1) {
+                user.setId(id);
+            } else {
+                throw new DataAccessException("Unable to insert user.");
+            }
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } catch (DataAccessException dae) {
+            throw dae;
+        } finally {
+            RepositoryUtils.closeQuietly(rs);
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public void deleteUser(String id) throws DataAccessException {
+        // ensure there are some authorities to create
+        PreparedStatement statement = null;
+        try {
+            // add each authority for the specified user
+            statement = connection.prepareStatement(DELETE_USER);
+            statement.setString(1, id);
+
+            // insert the authorities
+            statement.executeUpdate();
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } catch (DataAccessException dae) {
+            throw dae;
+        } finally {
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public void updateUser(NiFiUser user) throws DataAccessException {
+        PreparedStatement statement = null;
+        try {
+            // create a statement
+            statement = connection.prepareStatement(UPDATE_USER);
+            statement.setString(1, StringUtils.left(user.getDn(), 255));
+            statement.setString(2, StringUtils.left(user.getUserName(), 100));
+            statement.setString(3, StringUtils.left(user.getUserGroup(), 100));
+            statement.setString(6, StringUtils.left(user.getJustification(), 
500));
+            statement.setString(7, user.getStatus().toString());
+            statement.setString(8, user.getId());
+
+            // set the last accessed time accordingly
+            if (user.getLastAccessed() == null) {
+                statement.setNull(4, Types.TIMESTAMP);
+            } else {
+                statement.setTimestamp(4, new 
java.sql.Timestamp(user.getLastAccessed().getTime()));
+            }
+
+            // set the last verified time accordingly
+            if (user.getLastVerified() == null) {
+                statement.setNull(5, Types.TIMESTAMP);
+            } else {
+                statement.setTimestamp(5, new 
java.sql.Timestamp(user.getLastVerified().getTime()));
+            }
+
+            // perform the update
+            int updateCount = statement.executeUpdate();
+            if (updateCount != 1) {
+                throw new DataAccessException("Unable to update user.");
+            }
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } catch (DataAccessException dae) {
+            throw dae;
+        } finally {
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public void updateGroupStatus(String group, AccountStatus status) throws 
DataAccessException {
+        PreparedStatement statement = null;
+        try {
+            // create a statement
+            statement = connection.prepareStatement(UPDATE_USER_GROUP_STATUS);
+            statement.setString(1, status.toString());
+            statement.setString(2, group);
+
+            // perform the update
+            statement.executeUpdate();
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } catch (DataAccessException dae) {
+            throw dae;
+        } finally {
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public void updateGroupVerification(String group, Date lastVerified) 
throws DataAccessException {
+        PreparedStatement statement = null;
+        try {
+            // create a statement
+            statement = 
connection.prepareStatement(UPDATE_USER_GROUP_VERIFICATION);
+
+            // set the last verified time accordingly
+            if (lastVerified == null) {
+                statement.setNull(1, Types.TIMESTAMP);
+            } else {
+                statement.setTimestamp(1, new 
java.sql.Timestamp(lastVerified.getTime()));
+            }
+
+            // set the group
+            statement.setString(2, group);
+
+            // perform the update
+            statement.executeUpdate();
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } catch (DataAccessException dae) {
+            throw dae;
+        } finally {
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+    @Override
+    public void ungroup(String group) throws DataAccessException {
+        PreparedStatement statement = null;
+        try {
+            // create a statement
+            statement = connection.prepareStatement(UNGROUP_GROUP);
+            statement.setString(1, group);
+
+            // perform the update
+            statement.executeUpdate();
+        } catch (SQLException sqle) {
+            throw new DataAccessException(sqle);
+        } catch (DataAccessException dae) {
+            throw dae;
+        } finally {
+            RepositoryUtils.closeQuietly(statement);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountDisabledException.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountDisabledException.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountDisabledException.java
new file mode 100644
index 0000000..e8b3d10
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountDisabledException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.admin.service;
+
+/**
+ * Exception to indicate that the user account is disabled.
+ */
+public class AccountDisabledException extends RuntimeException {
+
+    public AccountDisabledException(String message, Throwable cause, boolean 
enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+    public AccountDisabledException(Throwable cause) {
+        super(cause);
+    }
+
+    public AccountDisabledException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AccountDisabledException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountNotFoundException.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountNotFoundException.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountNotFoundException.java
new file mode 100644
index 0000000..88287ce
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountNotFoundException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.admin.service;
+
+/**
+ * Exception to indicate that the user account is disabled.
+ */
+public class AccountNotFoundException extends RuntimeException {
+
+    public AccountNotFoundException(String message, Throwable cause, boolean 
enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+    public AccountNotFoundException(Throwable cause) {
+        super(cause);
+    }
+
+    public AccountNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AccountNotFoundException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountPendingException.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountPendingException.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountPendingException.java
new file mode 100644
index 0000000..dacc483
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AccountPendingException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.admin.service;
+
+/**
+ * Exception to indicate that the user has already submitting an account 
request
+ * and that request is still pending.
+ */
+public class AccountPendingException extends RuntimeException {
+
+    public AccountPendingException(String message, Throwable cause, boolean 
enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+    public AccountPendingException(Throwable cause) {
+        super(cause);
+    }
+
+    public AccountPendingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AccountPendingException(String message) {
+        super(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AdministrationException.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AdministrationException.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AdministrationException.java
new file mode 100644
index 0000000..c0e8ac1
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AdministrationException.java
@@ -0,0 +1,39 @@
+/*
+ * 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.admin.service;
+
+/**
+ *
+ */
+public class AdministrationException extends RuntimeException {
+
+    public AdministrationException(Throwable cause) {
+        super(cause);
+    }
+
+    public AdministrationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AdministrationException(String message) {
+        super(message);
+    }
+
+    public AdministrationException() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AuditService.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AuditService.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AuditService.java
new file mode 100644
index 0000000..680173f
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/AuditService.java
@@ -0,0 +1,74 @@
+/*
+ * 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.admin.service;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.apache.nifi.action.Action;
+import org.apache.nifi.history.HistoryQuery;
+import org.apache.nifi.history.History;
+import org.apache.nifi.history.PreviousValue;
+
+/**
+ * Allows NiFi actions to be audited.
+ */
+public interface AuditService {
+
+    /**
+     * Adds the specified actions.
+     *
+     * @param actions to add
+     * @throws AdministrationException if failed to add
+     */
+    void addActions(Collection<Action> actions);
+
+    /**
+     * @param componentId identifier of the component
+     * @return Finds the previous values for the specified property in the
+     * specified component. Returns null if there are none
+     */
+    Map<String, List<PreviousValue>> getPreviousValues(String componentId);
+
+    /**
+     * Get the actions within the given date range.
+     *
+     * @param actionQuery query
+     * @return history of actions
+     * @throws AdministrationException ae
+     */
+    History getActions(HistoryQuery actionQuery);
+
+    /**
+     * Get the details for the specified action id. If the action cannot be
+     * found, null is returned.
+     *
+     * @param actionId identifier of action
+     * @return the action
+     */
+    Action getAction(Integer actionId);
+
+    /**
+     * Purges all action's that occurred before the specified end date.
+     *
+     * @param end the stopper for event purging
+     * @param purgeAction the action
+     * @throws AdministrationException ae
+     */
+    void purgeActions(Date end, Action purgeAction);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/UserService.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/UserService.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/UserService.java
new file mode 100644
index 0000000..b02f192
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/UserService.java
@@ -0,0 +1,157 @@
+/*
+ * 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.admin.service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.nifi.authorization.Authority;
+import org.apache.nifi.authorization.DownloadAuthorization;
+import org.apache.nifi.user.NiFiUser;
+import org.apache.nifi.user.NiFiUserGroup;
+
+/**
+ * Manages NiFi user accounts.
+ */
+public interface UserService {
+
+    /**
+     * Creates a new user account using the specified dn and justification.
+     *
+     * @param dn user dn
+     * @param justification why the account is necessary
+     * @return the created NiFiUser
+     */
+    NiFiUser createPendingUserAccount(String dn, String justification);
+
+    /**
+     * @return Determines if there are any PENDING user accounts present
+     */
+    Boolean hasPendingUserAccount();
+
+    /**
+     * @param dnChain user dn chain
+     * @param attributes attributes for authorization request
+     * @return Determines if the users in the dnChain are authorized to 
download
+     * content with the specified attributes
+     */
+    DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, 
String> attributes);
+
+    /**
+     * Updates a user group using the specified group comprised of the 
specified
+     * users. Returns all the users that are currently in the specified group.
+     *
+     * @param group group
+     * @param userIds users
+     * @param authorities auths
+     * @return a user group
+     */
+    NiFiUserGroup updateGroup(String group, Set<String> userIds, 
Set<Authority> authorities);
+
+    /**
+     * Authorizes the user specified.
+     *
+     * @param dn user dn
+     * @return the user for the given dn if found
+     */
+    NiFiUser checkAuthorization(String dn);
+
+    /**
+     * Deletes the user with the specified id.
+     *
+     * @param id user identifier
+     */
+    void deleteUser(String id);
+
+    /**
+     * Disables the specified users account.
+     *
+     * @param id user identifier
+     * @return user for the given identifier
+     */
+    NiFiUser disable(String id);
+
+    /**
+     * Disables the specified user group.
+     *
+     * @param group to disable
+     * @return user group
+     */
+    NiFiUserGroup disableGroup(String group);
+
+    /**
+     * Updates the specified user with the specified authorities.
+     *
+     * @param id identifier of user
+     * @param authorities auths to set
+     * @return the updated user
+     */
+    NiFiUser update(String id, Set<Authority> authorities);
+
+    /**
+     * Invalidates the specified user account.
+     *
+     * @param id identifier of user account to invalidate
+     */
+    void invalidateUserAccount(String id);
+
+    /**
+     * Invalidates the user accounts associated with the specified user group.
+     *
+     * @param group to invalidate user accounts on
+     */
+    void invalidateUserGroupAccount(String group);
+
+    /**
+     * Ungroups the specified group.
+     *
+     * @param group to split up
+     */
+    void ungroup(String group);
+
+    /**
+     * Ungroups the specified user.
+     *
+     * @param id user to ungroup
+     */
+    void ungroupUser(String id);
+
+    /**
+     * Returns a collection of all NiFiUsers.
+     *
+     * @return Collection of users
+     */
+    Collection<NiFiUser> getUsers();
+
+    /**
+     * Finds the specified user by id.
+     *
+     * @param id of the user
+     * @return the user object
+     */
+    NiFiUser getUserById(String id);
+
+    /**
+     * Finds the specified user by dn.
+     *
+     * @param dn the user dn
+     * @return the newly created user
+     * @throws AdministrationException ae
+     */
+    NiFiUser getUserByDn(String dn);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AbstractUserAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AbstractUserAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AbstractUserAction.java
new file mode 100644
index 0000000..b970dc1
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AbstractUserAction.java
@@ -0,0 +1,97 @@
+/*
+ * 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.admin.service.action;
+
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.Set;
+import org.apache.nifi.authorization.Authority;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUser;
+
+/**
+ *
+ * @param <T> type of user action
+ */
+public abstract class AbstractUserAction<T> implements AdministrationAction<T> 
{
+
+    /**
+     * Determines the authorities that need to be added to the specified user.
+     *
+     * @param user user
+     * @param authorities auths
+     * @return authorities to add
+     */
+    protected Set<Authority> determineAuthoritiesToAdd(NiFiUser user, 
Set<Authority> authorities) {
+        // not using copyOf since authorities may be empty and copyOf can 
throw an IllegalArgumentException when empty
+        Set<Authority> authoritiesToAdd = EnumSet.noneOf(Authority.class);
+        authoritiesToAdd.addAll(authorities);
+
+        // identify the authorities that need to be inserted
+        authoritiesToAdd.removeAll(user.getAuthorities());
+
+        // return the desired authorities
+        return authoritiesToAdd;
+    }
+
+    /**
+     * Determines the authorities that need to be removed from the specified
+     * user.
+     *
+     * @param user user
+     * @param authorities auths
+     * @return auths to remove
+     */
+    protected Set<Authority> determineAuthoritiesToRemove(NiFiUser user, 
Set<Authority> authorities) {
+        Set<Authority> authoritiesToRemove = 
EnumSet.copyOf(user.getAuthorities());
+
+        // identify the authorities that need to be removed
+        authoritiesToRemove.removeAll(authorities);
+
+        // return the desired authorities
+        return authoritiesToRemove;
+    }
+
+    /**
+     * Verifies the specified users account. Includes obtaining the authorities
+     * and group according to the specified authority provider.
+     *
+     * @param authorityProvider provider
+     * @param user user to verify
+     */
+    protected void verifyAccount(AuthorityProvider authorityProvider, NiFiUser 
user) {
+        // load the roles for the user
+        Set<Authority> authorities = 
authorityProvider.getAuthorities(user.getDn());
+
+        // update the user's authorities
+        user.getAuthorities().clear();
+        user.getAuthorities().addAll(authorities);
+
+        // get the user group
+        user.setUserGroup(authorityProvider.getGroupForUser(user.getDn()));
+
+        // update the users status in case they were previously pending or 
disabled
+        user.setStatus(AccountStatus.ACTIVE);
+
+        // update the users last verified time - this timestampt shouldn't be 
record
+        // until the both the user's authorities and group have been synced
+        Date now = new Date();
+        user.setLastVerified(now);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AddActionsAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AddActionsAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AddActionsAction.java
new file mode 100644
index 0000000..5a2159f
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AddActionsAction.java
@@ -0,0 +1,48 @@
+/*
+ * 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.admin.service.action;
+
+import java.util.Collection;
+import org.apache.nifi.action.Action;
+import org.apache.nifi.admin.dao.ActionDAO;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.authorization.AuthorityProvider;
+
+/**
+ * Adds the specified actions.
+ */
+public class AddActionsAction implements AdministrationAction<Void> {
+
+    private final Collection<Action> actions;
+
+    public AddActionsAction(Collection<Action> actions) {
+        this.actions = actions;
+    }
+
+    @Override
+    public Void execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) {
+        ActionDAO actionDao = daoFactory.getActionDAO();
+
+        // add each action
+        for (Action action : actions) {
+            actionDao.createAction(action);
+        }
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AdministrationAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AdministrationAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AdministrationAction.java
new file mode 100644
index 0000000..f1795a9
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AdministrationAction.java
@@ -0,0 +1,38 @@
+/*
+ * 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.admin.service.action;
+
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.authorization.AuthorityProvider;
+
+/**
+ * Defines the administration action. Actions are provided a DAO factory and
+ * authority provider to perform a require action.
+ *
+ * @param <T> type
+ */
+public interface AdministrationAction<T> {
+
+    /**
+     * Performs an action using the specified DAOFactory and AuthorityProvider.
+     *
+     * @param daoFactory factory
+     * @param authorityProvider provider
+     * @return action result
+     */
+    T execute(DAOFactory daoFactory, AuthorityProvider authorityProvider);
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeDownloadAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeDownloadAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeDownloadAction.java
new file mode 100644
index 0000000..d1b994c
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeDownloadAction.java
@@ -0,0 +1,54 @@
+/*
+ * 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.admin.service.action;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.service.AccountNotFoundException;
+import org.apache.nifi.admin.service.AdministrationException;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.authorization.DownloadAuthorization;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+
+/**
+ * Attempts to obtain authorization to download the content with the specified
+ * attributes for the specified user.
+ */
+public class AuthorizeDownloadAction implements 
AdministrationAction<DownloadAuthorization> {
+
+    private final List<String> dnChain;
+    private final Map<String, String> attributes;
+
+    public AuthorizeDownloadAction(List<String> dnChain, Map<String, String> 
attributes) {
+        this.dnChain = dnChain;
+        this.attributes = attributes;
+    }
+
+    @Override
+    public DownloadAuthorization execute(DAOFactory daoFactory, 
AuthorityProvider authorityProvider) {
+        try {
+            return authorityProvider.authorizeDownload(dnChain, attributes);
+        } catch (UnknownIdentityException uie) {
+            throw new AccountNotFoundException(uie.getMessage(), uie);
+        } catch (AuthorityAccessException aae) {
+            throw new AdministrationException(aae.getMessage(), aae);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeUserAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeUserAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeUserAction.java
new file mode 100644
index 0000000..fe32772
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/AuthorizeUserAction.java
@@ -0,0 +1,173 @@
+/*
+ * 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.admin.service.action;
+
+import java.util.Calendar;
+import java.util.Date;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.admin.service.AccountDisabledException;
+import org.apache.nifi.admin.service.AccountNotFoundException;
+import org.apache.nifi.admin.service.AccountPendingException;
+import org.apache.nifi.admin.service.AdministrationException;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+import org.apache.nifi.security.util.CertificateUtils;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUser;
+
+/**
+ *
+ */
+public class AuthorizeUserAction extends AbstractUserAction<NiFiUser> {
+
+    private final String dn;
+    private final int cacheDurationSeconds;
+
+    public AuthorizeUserAction(String dn, int cacheDurationSeconds) {
+        this.dn = dn;
+        this.cacheDurationSeconds = cacheDurationSeconds;
+    }
+
+    @Override
+    public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) throws DataAccessException {
+        UserDAO userDao = daoFactory.getUserDAO();
+
+        // get the user
+        NiFiUser user = userDao.findUserByDn(dn);
+
+        // verify the user was found
+        if (user == null) {
+            // determine whether this users exists
+            boolean doesDnExist = false;
+            try {
+                doesDnExist = authorityProvider.doesDnExist(dn);
+            } catch (AuthorityAccessException aae) {
+                throw new AdministrationException(String.format("Unable to 
access authority details: %s", aae.getMessage()), aae);
+            }
+
+            // if the authority provider has the details for this user, create 
the account
+            if (doesDnExist) {
+                // create the user
+                user = new NiFiUser();
+                user.setDn(dn);
+                user.setUserName(CertificateUtils.extractUsername(dn));
+                user.setJustification("User details specified by authority 
provider.");
+
+                try {
+                    // verify the users account
+                    verifyAccount(authorityProvider, user);
+
+                    // get the date used for verification
+                    Date now = user.getLastVerified();
+
+                    // update the last accessed field
+                    user.setLastAccessed(now);
+                    user.setCreation(now);
+
+                    // create the new user account
+                    CreateUserAction createUser = new CreateUserAction(user);
+                    createUser.execute(daoFactory, authorityProvider);
+                } catch (UnknownIdentityException uie) {
+                    // strange since the provider just reported this dn 
existed but handleing anyways...
+                    throw new AccountNotFoundException(String.format("Unable 
to verify access for %s.", dn));
+                } catch (AuthorityAccessException aae) {
+                    throw new AdministrationException(String.format("Unable to 
access authority details: %s", aae.getMessage()), aae);
+                }
+            } else {
+                throw new AccountNotFoundException(String.format("Unable to 
verify access for %s.", dn));
+            }
+        } else {
+            Throwable providerError = null;
+
+            // verify the users account if necessary
+            if (isAccountVerificationRequired(user)) {
+                try {
+                    // verify the users account
+                    verifyAccount(authorityProvider, user);
+
+                    // update the last accessed field
+                    user.setLastAccessed(user.getLastVerified());
+                } catch (UnknownIdentityException uie) {
+                    // check the account status before attempting to update 
the account - depending on the account
+                    // status we might not need to update the account
+                    checkAccountStatus(user);
+
+                    // the user is currently active and they were not found in 
the providers - disable the account...
+                    user.setStatus(AccountStatus.DISABLED);
+
+                    // record the exception
+                    providerError = uie;
+                } catch (AuthorityAccessException aae) {
+                    throw new AdministrationException(String.format("Unable to 
access authority details: %s", aae.getMessage()), aae);
+                }
+            } else {
+                // verfiy the users account status before allowing access.
+                checkAccountStatus(user);
+
+                // update the users last accessed time
+                user.setLastAccessed(new Date());
+            }
+
+            // persist the user's updates
+            UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user);
+            updateUser.execute(daoFactory, authorityProvider);
+
+            // persist the user's authorities
+            UpdateUserAuthoritiesCacheAction updateUserAuthorities = new 
UpdateUserAuthoritiesCacheAction(user);
+            updateUserAuthorities.execute(daoFactory, authorityProvider);
+
+            if (providerError != null) {
+                throw new AccountDisabledException(String.format("User 
credentials for %s were not found. This account has been disabled.", 
user.getDn()), providerError);
+            }
+        }
+
+        return user;
+    }
+
+    /**
+     * @return Determines if account verification is required
+     */
+    private boolean isAccountVerificationRequired(NiFiUser user) {
+        // accounts that have never been verified obviously needs to be 
re-verified
+        if (user.getLastVerified() == null) {
+            return true;
+        }
+
+        // create a calendar and substract the threshold - anything
+        // before this time will need to be re-verified
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.SECOND, -cacheDurationSeconds);
+
+        return user.getLastVerified().before(calendar.getTime());
+    }
+
+    /**
+     * Checks the account status of the specified user.
+     *
+     * @param user to check
+     */
+    private void checkAccountStatus(NiFiUser user) {
+        if (AccountStatus.DISABLED.equals(user.getStatus())) {
+            throw new AccountDisabledException(String.format("Account for %s 
is disabled.", user.getDn()));
+        } else if (AccountStatus.PENDING.equals(user.getStatus())) {
+            throw new AccountPendingException(String.format("Account for %s is 
pending.", user.getDn()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/CreateUserAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/CreateUserAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/CreateUserAction.java
new file mode 100644
index 0000000..3833abb
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/CreateUserAction.java
@@ -0,0 +1,53 @@
+/*
+ * 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.admin.service.action;
+
+import java.util.Set;
+import org.apache.nifi.admin.dao.AuthorityDAO;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.authorization.Authority;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.user.NiFiUser;
+
+/**
+ * Action for creating a NiFiUser account.
+ */
+public class CreateUserAction extends AbstractUserAction<Void> {
+
+    private final NiFiUser user;
+
+    public CreateUserAction(NiFiUser user) {
+        this.user = user;
+    }
+
+    @Override
+    public Void execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) throws DataAccessException {
+        UserDAO userDao = daoFactory.getUserDAO();
+        AuthorityDAO authorityDao = daoFactory.getAuthorityDAO();
+
+        // create the user entry
+        userDao.createUser(user);
+
+        // create the authorities
+        Set<Authority> authorities = user.getAuthorities();
+        authorityDao.createAuthorities(authorities, user.getId());
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DeleteUserAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DeleteUserAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DeleteUserAction.java
new file mode 100644
index 0000000..0d59b43
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DeleteUserAction.java
@@ -0,0 +1,68 @@
+/*
+ * 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.admin.service.action;
+
+import org.apache.nifi.admin.dao.AuthorityDAO;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.admin.service.AccountNotFoundException;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUser;
+
+/**
+ *
+ */
+public class DeleteUserAction implements AdministrationAction<Void> {
+
+    private final String userId;
+
+    /**
+     * Creates a new transactions for deleting the specified user.
+     *
+     * @param userId user identifier
+     */
+    public DeleteUserAction(String userId) {
+        this.userId = userId;
+    }
+
+    @Override
+    public Void execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) throws DataAccessException {
+        final AuthorityDAO authorityDAO = daoFactory.getAuthorityDAO();
+        final UserDAO userDAO = daoFactory.getUserDAO();
+
+        // find the user and ensure they are currently revoked
+        final NiFiUser user = userDAO.findUserById(userId);
+
+        // ensure the user was found
+        if (user == null) {
+            throw new AccountNotFoundException(String.format("Unable to find 
account with ID %s.", userId));
+        }
+
+        // ensure the user is in the appropriate state
+        if (AccountStatus.ACTIVE.equals(user.getStatus())) {
+            throw new IllegalStateException(String.format("An active user 
cannot be removed. Revoke user access before attempting to remove."));
+        }
+
+        // remove the user and their authorities
+        authorityDAO.deleteAuthorities(userId);
+        userDAO.deleteUser(userId);
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserAction.java
new file mode 100644
index 0000000..c31f107
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserAction.java
@@ -0,0 +1,76 @@
+/*
+ * 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.admin.service.action;
+
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.admin.service.AccountNotFoundException;
+import org.apache.nifi.admin.service.AdministrationException;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class DisableUserAction implements AdministrationAction<NiFiUser> {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(DisableUserAction.class);
+
+    private final String id;
+
+    public DisableUserAction(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) throws DataAccessException {
+        UserDAO userDao = daoFactory.getUserDAO();
+
+        // get the user
+        NiFiUser user = userDao.findUserById(id);
+
+        // ensure the user exists
+        if (user == null) {
+            throw new AccountNotFoundException(String.format("Unable to find 
account with ID %s.", id));
+        }
+
+        // update the account
+        user.setStatus(AccountStatus.DISABLED);
+        user.setUserGroup(null);
+
+        // update the user locally
+        userDao.updateUser(user);
+
+        try {
+            // revoke the user in the authority provider
+            authorityProvider.revokeUser(user.getDn());
+        } catch (UnknownIdentityException uie) {
+            // user identity is not known
+            logger.info(String.format("User %s has already been removed from 
the authority provider.", user.getDn()));
+        } catch (AuthorityAccessException aae) {
+            throw new AdministrationException(String.format("Unable to revoke 
user '%s': %s", user.getDn(), aae.getMessage()), aae);
+        }
+
+        return user;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserGroupAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserGroupAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserGroupAction.java
new file mode 100644
index 0000000..385fce6
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/DisableUserGroupAction.java
@@ -0,0 +1,69 @@
+/*
+ * 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.admin.service.action;
+
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.admin.service.AdministrationException;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.authorization.exception.UnknownIdentityException;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUserGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class DisableUserGroupAction implements 
AdministrationAction<NiFiUserGroup> {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(DisableUserGroupAction.class);
+
+    private final String group;
+
+    public DisableUserGroupAction(final String group) {
+        this.group = group;
+    }
+
+    @Override
+    public NiFiUserGroup execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) throws DataAccessException {
+        final NiFiUserGroup userGroup = new NiFiUserGroup();
+
+        final UserDAO userDao = daoFactory.getUserDAO();
+
+        // update the user group locally
+        userDao.updateGroupStatus(group, AccountStatus.DISABLED);
+
+        // populate the group details
+        userGroup.setGroup(group);
+        userGroup.setUsers(userDao.findUsersForGroup(group));
+
+        try {
+            // revoke the user in the authority provider
+            authorityProvider.revokeGroup(group);
+        } catch (UnknownIdentityException uie) {
+            // user identity is not known
+            logger.info(String.format("User group %s has already been removed 
from the authority provider.", group));
+        } catch (AuthorityAccessException aae) {
+            throw new AdministrationException(String.format("Unable to revoke 
user group '%s': %s", group, aae.getMessage()), aae);
+        }
+
+        return userGroup;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByDnAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByDnAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByDnAction.java
new file mode 100644
index 0000000..8e5b574
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByDnAction.java
@@ -0,0 +1,49 @@
+/*
+ * 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.admin.service.action;
+
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.user.NiFiUser;
+
+/**
+ *
+ */
+public class FindUserByDnAction implements AdministrationAction<NiFiUser> {
+
+    private final String dn;
+
+    /**
+     * Creates a new transactions for getting a user with the specified DN.
+     *
+     * @param dn The DN of the user to obtain
+     */
+    public FindUserByDnAction(String dn) {
+        this.dn = dn;
+    }
+
+    @Override
+    public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) throws DataAccessException {
+        // get a UserDAO
+        UserDAO userDAO = daoFactory.getUserDAO();
+
+        // return the desired user
+        return userDAO.findUserByDn(dn);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByIdAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByIdAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByIdAction.java
new file mode 100644
index 0000000..0a10841
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/FindUserByIdAction.java
@@ -0,0 +1,46 @@
+/*
+ * 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.admin.service.action;
+
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.DataAccessException;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.user.NiFiUser;
+
+public class FindUserByIdAction implements AdministrationAction<NiFiUser> {
+
+    private final String id;
+
+    /**
+     * Creates a new transactions for getting a user with the specified id.
+     *
+     * @param id of user
+     */
+    public FindUserByIdAction(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) throws DataAccessException {
+        // get a UserDAO
+        UserDAO userDAO = daoFactory.getUserDAO();
+
+        // return the desired user
+        return userDAO.findUserById(id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionAction.java
new file mode 100644
index 0000000..1dc5588
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionAction.java
@@ -0,0 +1,41 @@
+/*
+ * 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.admin.service.action;
+
+import org.apache.nifi.action.Action;
+import org.apache.nifi.admin.dao.ActionDAO;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.authorization.AuthorityProvider;
+
+/**
+ * Gets the action with the specified id.
+ */
+public class GetActionAction implements AdministrationAction<Action> {
+
+    private final Integer id;
+
+    public GetActionAction(Integer id) {
+        this.id = id;
+    }
+
+    @Override
+    public Action execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) {
+        ActionDAO actionDao = daoFactory.getActionDAO();
+        return actionDao.getAction(id);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionsAction.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionsAction.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionsAction.java
new file mode 100644
index 0000000..3b82d79
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetActionsAction.java
@@ -0,0 +1,48 @@
+/*
+ * 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.admin.service.action;
+
+import java.util.Date;
+import org.apache.nifi.admin.dao.ActionDAO;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.history.History;
+import org.apache.nifi.history.HistoryQuery;
+
+/**
+ * Get all actions that match the specified query.
+ */
+public class GetActionsAction implements AdministrationAction<History> {
+
+    private final HistoryQuery query;
+
+    public GetActionsAction(HistoryQuery query) {
+        this.query = query;
+    }
+
+    @Override
+    public History execute(DAOFactory daoFactory, AuthorityProvider 
authorityProvider) {
+        ActionDAO actionDao = daoFactory.getActionDAO();
+
+        // find all matching history
+        History history = actionDao.findActions(query);
+        history.setLastRefreshed(new Date());
+
+        return history;
+    }
+
+}

Reply via email to