This is an automated email from the ASF dual-hosted git repository.

kdoran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/master by this push:
     new d35d15c  NIFI-6027
d35d15c is described below

commit d35d15cdda32c2aedd5bfd4124662f522461c159
Author: Matt Gilman <matt.c.gil...@gmail.com>
AuthorDate: Mon Mar 18 13:01:15 2019 -0400

    NIFI-6027
    
    - Allowing user or group existence enforcement to be parameterized.
    - Fixing error handling when loading user groups which may have resulted in 
stack trace leaking.
    
    This closes #3377.
    
    Signed-off-by: Kevin Doran <kdo...@apache.org>
---
 .../apache/nifi/web/StandardNiFiServiceFacade.java | 70 +++++++++++++---------
 .../web/security/NiFiAuthenticationFilter.java     | 19 ++++--
 2 files changed, 58 insertions(+), 31 deletions(-)

diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index a960dbf..fbce19b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -39,8 +39,8 @@ import org.apache.nifi.authorization.User;
 import org.apache.nifi.authorization.UserContextKeys;
 import org.apache.nifi.authorization.resource.Authorizable;
 import 
org.apache.nifi.authorization.resource.EnforcePolicyPermissionsThroughBaseResource;
-import org.apache.nifi.authorization.resource.ResourceFactory;
 import org.apache.nifi.authorization.resource.OperationAuthorizable;
+import org.apache.nifi.authorization.resource.ResourceFactory;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserUtils;
 import org.apache.nifi.bundle.BundleCoordinate;
@@ -48,10 +48,10 @@ import 
org.apache.nifi.cluster.coordination.ClusterCoordinator;
 import org.apache.nifi.cluster.coordination.heartbeat.HeartbeatMonitor;
 import org.apache.nifi.cluster.coordination.heartbeat.NodeHeartbeat;
 import org.apache.nifi.cluster.coordination.node.ClusterRoles;
-import org.apache.nifi.cluster.coordination.node.OffloadCode;
 import org.apache.nifi.cluster.coordination.node.DisconnectionCode;
 import org.apache.nifi.cluster.coordination.node.NodeConnectionState;
 import org.apache.nifi.cluster.coordination.node.NodeConnectionStatus;
+import org.apache.nifi.cluster.coordination.node.OffloadCode;
 import org.apache.nifi.cluster.event.NodeEvent;
 import org.apache.nifi.cluster.manager.exception.IllegalNodeDeletionException;
 import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
@@ -599,8 +599,8 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
                 authorizable,
                 () -> accessPolicyDAO.updateAccessPolicy(accessPolicyDTO),
                 accessPolicy -> {
-                    final Set<TenantEntity> users = 
accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
-                    final Set<TenantEntity> userGroups = 
accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+                    final Set<TenantEntity> users = 
accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet());
+                    final Set<TenantEntity> userGroups = 
accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet());
                     final ComponentReferenceEntity componentReference = 
createComponentReferenceEntity(accessPolicy.getResource());
                     return dtoFactory.createAccessPolicyDto(accessPolicy, 
userGroups, users, componentReference);
                 });
@@ -618,7 +618,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
                 usersAuthorizable,
                 () -> userDAO.updateUser(userDTO),
                 user -> {
-                    final Set<TenantEntity> tenantEntities = 
groups.stream().map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+                    final Set<TenantEntity> tenantEntities = 
groups.stream().map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet());
                     final Set<AccessPolicySummaryEntity> policyEntities = 
policies.stream().map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
                     return dtoFactory.createUserDto(user, tenantEntities, 
policyEntities);
                 });
@@ -635,7 +635,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
                 userGroupsAuthorizable,
                 () -> userGroupDAO.updateUserGroup(userGroupDTO),
                 userGroup -> {
-                    final Set<TenantEntity> tenantEntities = 
userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+                    final Set<TenantEntity> tenantEntities = 
userGroup.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet());
                     final Set<AccessPolicySummaryEntity> policyEntities = 
policies.stream().map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
                     return dtoFactory.createUserGroupDto(userGroup, 
tenantEntities, policyEntities);
                 }
@@ -1254,7 +1254,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final User user = userDAO.getUser(userId);
         final PermissionsDTO permissions = 
dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
         final Set<TenantEntity> userGroups = user != null ? 
userGroupDAO.getUserGroupsForUser(userId).stream()
-                .map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet())
 : null;
+                .map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet())
 : null;
         final Set<AccessPolicySummaryEntity> policyEntities = user != null ? 
userGroupDAO.getAccessPoliciesForUser(userId).stream()
                 .map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()) : null;
 
@@ -1289,7 +1289,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
         final PermissionsDTO permissions = 
dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
         final Set<TenantEntity> users = userGroup != null ? 
userGroup.getUsers().stream()
-                .map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : 
null;
+                
.map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()) : null;
         final Set<AccessPolicySummaryEntity> policyEntities = 
userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream()
                 .map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
 
@@ -1324,8 +1324,8 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final AccessPolicy accessPolicy = 
accessPolicyDAO.getAccessPolicy(accessPolicyId);
         final ComponentReferenceEntity componentReference = 
createComponentReferenceEntity(accessPolicy.getResource());
         final PermissionsDTO permissions = 
dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyId));
-        final Set<TenantEntity> userGroups = accessPolicy != null ? 
accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet())
 : null;
-        final Set<TenantEntity> users = accessPolicy != null ? 
accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet())
 : null;
+        final Set<TenantEntity> userGroups = accessPolicy != null ? 
accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet())
 : null;
+        final Set<TenantEntity> users = accessPolicy != null ? 
accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet())
 : null;
         final AccessPolicyDTO snapshot = deleteComponent(
                 revision,
                 new Resource() {
@@ -1700,7 +1700,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final AccessPolicy newAccessPolicy = 
accessPolicyDAO.createAccessPolicy(accessPolicyDTO);
         final ComponentReferenceEntity componentReference = 
createComponentReferenceEntity(newAccessPolicy.getResource());
         final AccessPolicyDTO newAccessPolicyDto = 
dtoFactory.createAccessPolicyDto(newAccessPolicy,
-                
newAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
+                
newAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()),
                 newAccessPolicy.getUsers().stream().map(userId -> {
                     final RevisionDTO userRevision = 
dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
                     return 
entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)),
 userRevision,
@@ -1716,7 +1716,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final String creator = NiFiUserUtils.getNiFiUserIdentity();
         final User newUser = userDAO.createUser(userDTO);
         final Set<TenantEntity> tenantEntities = 
userGroupDAO.getUserGroupsForUser(newUser.getIdentifier()).stream()
-                .map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+                .map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet());
         final Set<AccessPolicySummaryEntity> policyEntities = 
userGroupDAO.getAccessPoliciesForUser(newUser.getIdentifier()).stream()
                 .map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
         final UserDTO newUserDto = dtoFactory.createUserDto(newUser, 
tenantEntities, policyEntities);
@@ -1762,7 +1762,7 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     public UserGroupEntity createUserGroup(final Revision revision, final 
UserGroupDTO userGroupDTO) {
         final String creator = NiFiUserUtils.getNiFiUserIdentity();
         final Group newUserGroup = userGroupDAO.createUserGroup(userGroupDTO);
-        final Set<TenantEntity> tenantEntities = 
newUserGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+        final Set<TenantEntity> tenantEntities = 
newUserGroup.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet());
         final Set<AccessPolicySummaryEntity> policyEntities = 
userGroupDAO.getAccessPoliciesForUserGroup(newUserGroup.getIdentifier()).stream()
                 .map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
         final UserGroupDTO newUserGroupDto = 
dtoFactory.createUserGroupDto(newUserGroup, tenantEntities, policyEntities);
@@ -3302,39 +3302,39 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final ComponentReferenceEntity componentReference = 
createComponentReferenceEntity(accessPolicy.getResource());
         return entityFactory.createAccessPolicyEntity(
                 dtoFactory.createAccessPolicyDto(accessPolicy,
-                        
accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
-                        
accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()),
 componentReference),
+                        
accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()),
+                        
accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()),
 componentReference),
                 revision, permissions);
     }
 
     @Override
     public UserEntity getUser(final String userId) {
         final User user = userDAO.getUser(userId);
-        return createUserEntity(user);
+        return createUserEntity(user, true);
     }
 
     @Override
     public Set<UserEntity> getUsers() {
         final Set<User> users = userDAO.getUsers();
         return users.stream()
-            .map(user -> createUserEntity(user))
+            .map(user -> createUserEntity(user, false))
             .collect(Collectors.toSet());
     }
 
-    private UserEntity createUserEntity(final User user) {
+    private UserEntity createUserEntity(final User user, final boolean 
enforceUserExistence) {
         final RevisionDTO userRevision = 
dtoFactory.createRevisionDTO(revisionManager.getRevision(user.getIdentifier()));
         final PermissionsDTO permissions = 
dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
         final Set<TenantEntity> userGroups = 
userGroupDAO.getUserGroupsForUser(user.getIdentifier()).stream()
-                .map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
+                .map(g -> 
g.getIdentifier()).map(mapUserGroupIdToTenantEntity(enforceUserExistence)).collect(Collectors.toSet());
         final Set<AccessPolicySummaryEntity> policyEntities = 
userGroupDAO.getAccessPoliciesForUser(user.getIdentifier()).stream()
                 .map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
         return entityFactory.createUserEntity(dtoFactory.createUserDto(user, 
userGroups, policyEntities), userRevision, permissions);
     }
 
-    private UserGroupEntity createUserGroupEntity(final Group userGroup) {
+    private UserGroupEntity createUserGroupEntity(final Group userGroup, final 
boolean enforceGroupExistence) {
         final RevisionDTO userGroupRevision = 
dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroup.getIdentifier()));
         final PermissionsDTO permissions = 
dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
-        final Set<TenantEntity> users = 
userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
+        final Set<TenantEntity> users = 
userGroup.getUsers().stream().map(mapUserIdToTenantEntity(enforceGroupExistence)).collect(Collectors.toSet());
         final Set<AccessPolicySummaryEntity> policyEntities = 
userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream()
                 .map(ap -> 
createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
         return 
entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, 
users, policyEntities), userGroupRevision, permissions);
@@ -3343,14 +3343,14 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     @Override
     public UserGroupEntity getUserGroup(final String userGroupId) {
         final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
-        return createUserGroupEntity(userGroup);
+        return createUserGroupEntity(userGroup, true);
     }
 
     @Override
     public Set<UserGroupEntity> getUserGroups() {
         final Set<Group> userGroups = userGroupDAO.getUserGroups();
         return userGroups.stream()
-            .map(userGroup -> createUserGroupEntity(userGroup))
+            .map(userGroup -> createUserGroupEntity(userGroup, false))
             .collect(Collectors.toSet());
     }
 
@@ -4740,18 +4740,34 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     /* reusable function declarations for converting ids to tenant entities */
-    private Function<String, TenantEntity> mapUserGroupIdToTenantEntity() {
+    private Function<String, TenantEntity> mapUserGroupIdToTenantEntity(final 
boolean enforceGroupExistence) {
         return userGroupId -> {
             final RevisionDTO userGroupRevision = 
dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroupId));
-            return 
entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userGroupDAO.getUserGroup(userGroupId)),
 userGroupRevision,
+
+            final Group group;
+            if (enforceGroupExistence || 
userGroupDAO.hasUserGroup(userGroupId)) {
+                group = userGroupDAO.getUserGroup(userGroupId);
+            } else {
+                group = new 
Group.Builder().identifier(userGroupId).name("Group ID - " + userGroupId + " 
(removed externally)").build();
+            }
+
+            return 
entityFactory.createTenantEntity(dtoFactory.createTenantDTO(group), 
userGroupRevision,
                     
dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
         };
     }
 
-    private Function<String, TenantEntity> mapUserIdToTenantEntity() {
+    private Function<String, TenantEntity> mapUserIdToTenantEntity(final 
boolean enforceUserExistence) {
         return userId -> {
             final RevisionDTO userRevision = 
dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
-            return 
entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)),
 userRevision,
+
+            final User user;
+            if (enforceUserExistence || userDAO.hasUser(userId)) {
+                user = userDAO.getUser(userId);
+            } else {
+                user = new User.Builder().identifier(userId).identity("User ID 
- " + userId + " (removed externally)").build();
+            }
+
+            return 
entityFactory.createTenantEntity(dtoFactory.createTenantDTO(user), userRevision,
                     
dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
         };
     }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
index 75f1c56..030b19e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/NiFiAuthenticationFilter.java
@@ -67,7 +67,6 @@ public abstract class NiFiAuthenticationFilter extends 
GenericFilterBean {
     }
 
     private void authenticate(final HttpServletRequest request, final 
HttpServletResponse response, final FilterChain chain) throws IOException, 
ServletException {
-        String dnChain = null;
         try {
             final Authentication authenticationRequest = 
attemptAuthentication(request);
             if (authenticationRequest != null) {
@@ -79,13 +78,25 @@ public abstract class NiFiAuthenticationFilter extends 
GenericFilterBean {
                 final Authentication authenticated = 
authenticationManager.authenticate(authenticationRequest);
                 successfulAuthorization(request, response, authenticated);
             }
-
-            // continue
-            chain.doFilter(request, response);
         } catch (final AuthenticationException ae) {
             // invalid authentication - always error out
             unsuccessfulAuthorization(request, response, ae);
+            return;
+        } catch (final Exception e) {
+            log.error(String.format("Unable to authorize: %s", 
e.getMessage()), e);
+
+            // set the response status
+            response.setContentType("text/plain");
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+
+            // other exception - always error out
+            PrintWriter out = response.getWriter();
+            out.println(String.format("Failed to authorize request. Please 
contact the system administrator."));
+            return;
         }
+
+        // continue
+        chain.doFilter(request, response);
     }
 
     /**

Reply via email to