You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2017/01/04 18:06:45 UTC
nifi git commit: NIFI-2695: - Providing more granular and meaningful
authorization error messages.
Repository: nifi
Updated Branches:
refs/heads/master 41189b055 -> b1c9f0e76
NIFI-2695: - Providing more granular and meaningful authorization error messages.
This closes #1309.
Signed-off-by: Bryan Bende <bb...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/b1c9f0e7
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/b1c9f0e7
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/b1c9f0e7
Branch: refs/heads/master
Commit: b1c9f0e76428d69e7ee39448ef182ad0a23327ec
Parents: 41189b0
Author: Matt Gilman <ma...@gmail.com>
Authored: Thu Dec 8 11:29:32 2016 -0500
Committer: Bryan Bende <bb...@apache.org>
Committed: Wed Jan 4 13:06:19 2017 -0500
----------------------------------------------------------------------
.../AbstractPolicyBasedAuthorizer.java | 3 +-
.../authorization/AuthorizationRequest.java | 31 ++++
.../nifi/authorization/AuthorizationResult.java | 8 +-
.../org/apache/nifi/authorization/Resource.java | 7 +
.../authorization/resource/Authorizable.java | 103 +++++++++++--
.../TestAbstractPolicyBasedAuthorizer.java | 6 +-
.../nifi/authorization/FileAuthorizer.java | 8 +-
.../nifi/authorization/FileAuthorizerTest.java | 12 +-
.../resource/AccessPolicyAuthorizable.java | 4 +-
.../resource/DataAuthorizable.java | 4 +-
.../authorization/resource/ResourceFactory.java | 153 +++++++++++++++----
.../nifi/connectable/StandardConnection.java | 9 +-
.../nifi/web/StandardNiFiServiceFacade.java | 36 ++++-
.../StandardNiFiWebConfigurationContext.java | 4 +-
.../org/apache/nifi/web/api/AccessResource.java | 4 +-
.../apache/nifi/web/api/ControllerResource.java | 15 +-
.../apache/nifi/web/api/CountersResource.java | 15 +-
.../org/apache/nifi/web/api/FlowResource.java | 4 +-
.../apache/nifi/web/api/ProvenanceResource.java | 4 +-
.../apache/nifi/web/api/ResourceResource.java | 4 +-
.../apache/nifi/web/api/SiteToSiteResource.java | 4 +-
.../nifi/web/api/SystemDiagnosticsResource.java | 4 +-
.../api/config/AccessDeniedExceptionMapper.java | 7 +-
.../nifi/web/controller/ControllerFacade.java | 4 +-
.../src/main/webapp/js/nf/nf-common.js | 11 +-
.../PersistentProvenanceRepository.java | 8 +-
.../VolatileProvenanceRepository.java | 8 +-
.../authorization/RangerNiFiAuthorizer.java | 10 +-
.../authorization/TestRangerNiFiAuthorizer.java | 10 ++
29 files changed, 400 insertions(+), 100 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
index 98b8102..0d047f1 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AbstractPolicyBasedAuthorizer.java
@@ -158,8 +158,7 @@ public abstract class AbstractPolicyBasedAuthorizer implements Authorizer {
return AuthorizationResult.approved();
}
-
- return AuthorizationResult.denied();
+ return AuthorizationResult.denied(request.getExplanationSupplier().get());
}
/**
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
index da0a276..4f5a8f8 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationRequest.java
@@ -20,12 +20,15 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import java.util.function.Supplier;
/**
* Represents an authorization request for a given user/entity performing an action against a resource within some userContext.
*/
public class AuthorizationRequest {
+ public static final String DEFAULT_EXPLANATION = "Unable to perform the desired action.";
+
private final Resource resource;
private final String identity;
private final RequestAction action;
@@ -33,6 +36,7 @@ public class AuthorizationRequest {
private final boolean isAnonymous;
private final Map<String, String> userContext;
private final Map<String, String> resourceContext;
+ private final Supplier<String> explanationSupplier;
private AuthorizationRequest(final Builder builder) {
Objects.requireNonNull(builder.resource, "The resource is required when creating an authorization request");
@@ -47,6 +51,16 @@ public class AuthorizationRequest {
this.isAnonymous = builder.isAnonymous;
this.userContext = builder.userContext == null ? null : Collections.unmodifiableMap(builder.userContext);
this.resourceContext = builder.resourceContext == null ? null : Collections.unmodifiableMap(builder.resourceContext);
+ this.explanationSupplier = () -> {
+ final String explanation = builder.explanationSupplier.get();
+
+ // ensure the specified supplier returns non null
+ if (explanation == null) {
+ return DEFAULT_EXPLANATION;
+ } else {
+ return explanation;
+ }
+ };
}
/**
@@ -113,6 +127,15 @@ public class AuthorizationRequest {
}
/**
+ * A supplier for the explanation if access is denied. Non null.
+ *
+ * @return The explanation supplier if access is denied
+ */
+ public Supplier<String> getExplanationSupplier() {
+ return explanationSupplier;
+ }
+
+ /**
* AuthorizationRequest builder.
*/
public static final class Builder {
@@ -124,6 +147,7 @@ public class AuthorizationRequest {
private RequestAction action;
private Map<String, String> userContext;
private Map<String, String> resourceContext;
+ private Supplier<String> explanationSupplier = () -> DEFAULT_EXPLANATION;
public Builder resource(final Resource resource) {
this.resource = resource;
@@ -164,6 +188,13 @@ public class AuthorizationRequest {
return this;
}
+ public Builder explanationSupplier(final Supplier<String> explanationSupplier) {
+ if (explanationSupplier != null) {
+ this.explanationSupplier = explanationSupplier;
+ }
+ return this;
+ }
+
public AuthorizationRequest build() {
return new AuthorizationRequest(this);
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
index a3f520c..acfdc02 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/AuthorizationResult.java
@@ -28,7 +28,7 @@ public class AuthorizationResult {
}
private static final AuthorizationResult APPROVED = new AuthorizationResult(Result.Approved, null);
- private static final AuthorizationResult RESOURCE_NOT_FOUND = new AuthorizationResult(Result.ResourceNotFound, null);
+ private static final AuthorizationResult RESOURCE_NOT_FOUND = new AuthorizationResult(Result.ResourceNotFound, "Not authorized for the requested resource.");
private final Result result;
private final String explanation;
@@ -44,6 +44,10 @@ public class AuthorizationResult {
throw new IllegalArgumentException("An explanation is required when the authorization request is denied.");
}
+ if (Result.ResourceNotFound.equals(result) && explanation == null) {
+ throw new IllegalArgumentException("An explanation is required when the authorization request is resource not found.");
+ }
+
this.result = result;
this.explanation = explanation;
}
@@ -83,7 +87,7 @@ public class AuthorizationResult {
* @return a new denied AuthorizationResult
*/
public static AuthorizationResult denied() {
- return denied("Access is denied");
+ return denied(AuthorizationRequest.DEFAULT_EXPLANATION);
}
/**
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java
index 661b326..2aae7b2 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/Resource.java
@@ -34,4 +34,11 @@ public interface Resource {
* @return name of this resource
*/
String getName();
+
+ /**
+ * The description of this resource that may be safely used in messages to the client.
+ *
+ * @return safe description
+ */
+ String getSafeDescription();
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
index 39e9642..3219ac2 100644
--- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java
@@ -26,8 +26,8 @@ import org.apache.nifi.authorization.Resource;
import org.apache.nifi.authorization.UserContextKeys;
import org.apache.nifi.authorization.user.NiFiUser;
-import java.util.Map;
import java.util.HashMap;
+import java.util.Map;
public interface Authorizable {
@@ -70,7 +70,7 @@ public interface Authorizable {
*/
default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) {
if (user == null) {
- return AuthorizationResult.denied("Unknown user");
+ return AuthorizationResult.denied("Unknown user.");
}
final Map<String,String> userContext;
@@ -81,15 +81,28 @@ public interface Authorizable {
userContext = null;
}
- // build the request
+ final Resource resource = getResource();
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(false)
.action(action)
- .resource(getResource())
+ .resource(resource)
.resourceContext(resourceContext)
.userContext(userContext)
+ .explanationSupplier(() -> {
+ // build the safe explanation
+ final StringBuilder safeDescription = new StringBuilder("Unable to ");
+
+ if (RequestAction.READ.equals(action)) {
+ safeDescription.append("view ");
+ } else {
+ safeDescription.append("modify ");
+ }
+ safeDescription.append(resource.getSafeDescription()).append(".");
+
+ return safeDescription.toString();
+ })
.build();
// perform the authorization
@@ -99,9 +112,37 @@ public interface Authorizable {
if (Result.ResourceNotFound.equals(result.getResult())) {
final Authorizable parent = getParentAuthorizable();
if (parent == null) {
- return AuthorizationResult.denied();
+ return AuthorizationResult.denied("No applicable policies could be found.");
} else {
- return parent.checkAuthorization(authorizer, action, user, resourceContext);
+ // create a custom authorizable to override the safe description but still defer to the parent authorizable
+ final Authorizable parentProxy = new Authorizable() {
+ @Override
+ public Authorizable getParentAuthorizable() {
+ return parent.getParentAuthorizable();
+ }
+
+ @Override
+ public Resource getResource() {
+ final Resource parentResource = parent.getResource();
+ return new Resource() {
+ @Override
+ public String getIdentifier() {
+ return parentResource.getIdentifier();
+ }
+
+ @Override
+ public String getName() {
+ return parentResource.getName();
+ }
+
+ @Override
+ public String getSafeDescription() {
+ return resource.getSafeDescription();
+ }
+ };
+ }
+ };
+ return parentProxy.checkAuthorization(authorizer, action, user, resourceContext);
}
} else {
return result;
@@ -133,7 +174,7 @@ public interface Authorizable {
*/
default void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) throws AccessDeniedException {
if (user == null) {
- throw new AccessDeniedException("Unknown user");
+ throw new AccessDeniedException("Unknown user.");
}
final Map<String,String> userContext;
@@ -144,23 +185,65 @@ public interface Authorizable {
userContext = null;
}
+ final Resource resource = getResource();
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(true)
.action(action)
- .resource(getResource())
+ .resource(resource)
.resourceContext(resourceContext)
.userContext(userContext)
+ .explanationSupplier(() -> {
+ // build the safe explanation
+ final StringBuilder safeDescription = new StringBuilder("Unable to ");
+
+ if (RequestAction.READ.equals(action)) {
+ safeDescription.append("view ");
+ } else {
+ safeDescription.append("modify ");
+ }
+ safeDescription.append(resource.getSafeDescription()).append(".");
+
+ return safeDescription.toString();
+ })
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (Result.ResourceNotFound.equals(result.getResult())) {
final Authorizable parent = getParentAuthorizable();
if (parent == null) {
- throw new AccessDeniedException("Access is denied");
+ throw new AccessDeniedException("No applicable policies could be found.");
} else {
- parent.authorize(authorizer, action, user, resourceContext);
+ // create a custom authorizable to override the safe description but still defer to the parent authorizable
+ final Authorizable parentProxy = new Authorizable() {
+ @Override
+ public Authorizable getParentAuthorizable() {
+ return parent.getParentAuthorizable();
+ }
+
+ @Override
+ public Resource getResource() {
+ final Resource parentResource = parent.getResource();
+ return new Resource() {
+ @Override
+ public String getIdentifier() {
+ return parentResource.getIdentifier();
+ }
+
+ @Override
+ public String getName() {
+ return parentResource.getName();
+ }
+
+ @Override
+ public String getSafeDescription() {
+ return resource.getSafeDescription();
+ }
+ };
+ }
+ };
+ parentProxy.authorize(authorizer, action, user, resourceContext);
}
} else if (Result.Denied.equals(result.getResult())) {
throw new AccessDeniedException(result.getExplanation());
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
index a5cf351..cda2ac5 100644
--- a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
+++ b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
@@ -16,7 +16,6 @@
*/
package org.apache.nifi.authorization;
-import org.apache.nifi.authorization.MockPolicyBasedAuthorizer;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.junit.Assert;
import org.junit.Test;
@@ -42,6 +41,11 @@ public class TestAbstractPolicyBasedAuthorizer {
public String getName() {
return "resource1";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "description1";
+ }
};
@Test
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
index 7f89ddd..be20b60 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
@@ -447,8 +447,12 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
// convert any access controls on ports to the appropriate policies
for (PortDTO portDTO : ports) {
- final boolean isInputPort = portDTO.getType() != null && portDTO.getType().equals("inputPort");
- final Resource resource = ResourceFactory.getDataTransferResource(isInputPort, portDTO.getId(), portDTO.getName());
+ final Resource resource;
+ if (portDTO.getType() != null && portDTO.getType().equals("inputPort")) {
+ resource = ResourceFactory.getDataTransferResource(ResourceFactory.getComponentResource(ResourceType.InputPort, portDTO.getId(), portDTO.getName()));
+ } else {
+ resource = ResourceFactory.getDataTransferResource(ResourceFactory.getComponentResource(ResourceType.OutputPort, portDTO.getId(), portDTO.getName()));
+ }
if (portDTO.getUserAccessControl() != null) {
for (String userAccessControl : portDTO.getUserAccessControl()) {
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
index c335e19..55a1839 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
@@ -358,7 +358,8 @@ public class FileAuthorizerTest {
assertEquals(2, user6Policies.get(ResourceType.SiteToSite.getValue()).size());
assertTrue(user6Policies.get(ResourceType.SiteToSite.getValue()).contains(RequestAction.WRITE));
- final Resource inputPortResource = ResourceFactory.getDataTransferResource(true, "2f7d1606-b090-4be7-a592-a5b70fb55531", "TCP Input");
+ final Resource inputPortResource = ResourceFactory.getDataTransferResource(
+ ResourceFactory.getComponentResource(ResourceType.InputPort, "2f7d1606-b090-4be7-a592-a5b70fb55531", "TCP Input"));
final AccessPolicy inputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(inputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(inputPortPolicy);
assertEquals(1, inputPortPolicy.getUsers().size());
@@ -366,7 +367,8 @@ public class FileAuthorizerTest {
assertEquals(1, inputPortPolicy.getGroups().size());
assertTrue(inputPortPolicy.getGroups().contains(group1.getIdentifier()));
- final Resource outputPortResource = ResourceFactory.getDataTransferResource(false, "2f7d1606-b090-4be7-a592-a5b70fb55532", "TCP Output");
+ final Resource outputPortResource = ResourceFactory.getDataTransferResource(
+ ResourceFactory.getComponentResource(ResourceType.OutputPort, "2f7d1606-b090-4be7-a592-a5b70fb55532", "TCP Output"));
final AccessPolicy outputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(outputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(outputPortPolicy);
assertEquals(1, outputPortPolicy.getUsers().size());
@@ -432,7 +434,8 @@ public class FileAuthorizerTest {
final Group group1 = groups.iterator().next();
assertEquals("group1", group1.getName());
- final Resource inputPortResource = ResourceFactory.getDataTransferResource(true, "2f7d1606-b090-4be7-a592-a5b70fb55531", "TCP Input");
+ final Resource inputPortResource = ResourceFactory.getDataTransferResource(
+ ResourceFactory.getComponentResource(ResourceType.InputPort, "2f7d1606-b090-4be7-a592-a5b70fb55531", "TCP Input"));
final AccessPolicy inputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(inputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(inputPortPolicy);
assertEquals(1, inputPortPolicy.getUsers().size());
@@ -440,7 +443,8 @@ public class FileAuthorizerTest {
assertEquals(1, inputPortPolicy.getGroups().size());
assertTrue(inputPortPolicy.getGroups().contains(group1.getIdentifier()));
- final Resource outputPortResource = ResourceFactory.getDataTransferResource(false, "2f7d1606-b090-4be7-a592-a5b70fb55532", "TCP Output");
+ final Resource outputPortResource = ResourceFactory.getDataTransferResource(
+ ResourceFactory.getComponentResource(ResourceType.OutputPort, "2f7d1606-b090-4be7-a592-a5b70fb55532", "TCP Output"));
final AccessPolicy outputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(outputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(outputPortPolicy);
assertEquals(1, outputPortPolicy.getUsers().size());
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/AccessPolicyAuthorizable.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/AccessPolicyAuthorizable.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/AccessPolicyAuthorizable.java
index 041b982..81f8a13 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/AccessPolicyAuthorizable.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/AccessPolicyAuthorizable.java
@@ -89,7 +89,7 @@ public class AccessPolicyAuthorizable implements Authorizable, EnforcePolicyPerm
@Override
public AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) {
if (user == null) {
- throw new AccessDeniedException("Unknown user");
+ throw new AccessDeniedException("Unknown user.");
}
final AuthorizationResult resourceResult = Authorizable.super.checkAuthorization(authorizer, action, user, resourceContext);
@@ -105,7 +105,7 @@ public class AccessPolicyAuthorizable implements Authorizable, EnforcePolicyPerm
@Override
public void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) throws AccessDeniedException {
if (user == null) {
- throw new AccessDeniedException("Unknown user");
+ throw new AccessDeniedException("Unknown user.");
}
try {
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/DataAuthorizable.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/DataAuthorizable.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/DataAuthorizable.java
index cb0d0f1..7269560 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/DataAuthorizable.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/DataAuthorizable.java
@@ -62,7 +62,7 @@ public class DataAuthorizable implements Authorizable, EnforcePolicyPermissionsT
@Override
public AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) {
if (user == null) {
- return AuthorizationResult.denied("Unknown user");
+ return AuthorizationResult.denied("Unknown user.");
}
AuthorizationResult result = null;
@@ -100,7 +100,7 @@ public class DataAuthorizable implements Authorizable, EnforcePolicyPermissionsT
@Override
public void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) throws AccessDeniedException {
if (user == null) {
- throw new AccessDeniedException("Unknown user");
+ throw new AccessDeniedException("Unknown user.");
}
// calculate the dn chain
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
index 83c5bb9..79392b7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
@@ -32,6 +32,11 @@ public final class ResourceFactory {
public String getName() {
return "Controller";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "the controller";
+ }
};
private final static Resource FLOW_RESOURCE = new Resource() {
@@ -44,6 +49,11 @@ public final class ResourceFactory {
public String getName() {
return "NiFi Flow";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "the user interface";
+ }
};
private final static Resource POLICY_RESOURCE = new Resource() {
@@ -54,7 +64,12 @@ public final class ResourceFactory {
@Override
public String getName() {
- return "Policy";
+ return "Policies for ";
+ }
+
+ @Override
+ public String getSafeDescription() {
+ return "the policies for ";
}
};
@@ -68,6 +83,11 @@ public final class ResourceFactory {
public String getName() {
return "Counters";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "counters";
+ }
};
private final static Resource PROVENANCE_RESOURCE = new Resource() {
@@ -80,6 +100,11 @@ public final class ResourceFactory {
public String getName() {
return "Provenance";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "provenance";
+ }
};
private final static Resource DATA_RESOURCE = new Resource() {
@@ -90,7 +115,12 @@ public final class ResourceFactory {
@Override
public String getName() {
- return "Data";
+ return "Data for ";
+ }
+
+ @Override
+ public String getSafeDescription() {
+ return "the data for ";
}
};
@@ -104,6 +134,11 @@ public final class ResourceFactory {
public String getName() {
return "Proxy User Requests";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "proxy requests on behalf of users";
+ }
};
private final static Resource RESOURCE_RESOURCE = new Resource() {
@@ -116,6 +151,11 @@ public final class ResourceFactory {
public String getName() {
return "NiFi Resources";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "resources";
+ }
};
private final static Resource SITE_TO_SITE_RESOURCE = new Resource() {
@@ -128,6 +168,11 @@ public final class ResourceFactory {
public String getName() {
return "Site to Site";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "site-to-site details";
+ }
};
private final static Resource SYSTEM_RESOURCE = new Resource() {
@@ -140,6 +185,11 @@ public final class ResourceFactory {
public String getName() {
return "System";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "system diagnostics";
+ }
};
private final static Resource RESTRICTED_COMPONENTS_RESOURCE = new Resource() {
@@ -152,6 +202,11 @@ public final class ResourceFactory {
public String getName() {
return "Restricted Components";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "restricted components";
+ }
};
private final static Resource TENANT_RESOURCE = new Resource() {
@@ -164,6 +219,11 @@ public final class ResourceFactory {
public String getName() {
return "Tenant";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "users/user groups";
+ }
};
private final static Resource POLICIES_RESOURCE = new Resource() {
@@ -177,6 +237,11 @@ public final class ResourceFactory {
public String getName() {
return "Access Policies";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "policies";
+ }
};
/**
@@ -274,30 +339,6 @@ public final class ResourceFactory {
/**
* Gets a Resource for performing transferring data to a port.
*
- * @param isInputPort Whether this port is an input port or an output port
- * @param identifier The identifier of the component being accessed
- * @param name The name of the component being accessed
- * @return The resource
- */
- public static Resource getDataTransferResource(final boolean isInputPort, final String identifier, final String name) {
- Objects.requireNonNull(identifier, "The component identifier must be specified.");
-
- return new Resource() {
- @Override
- public String getIdentifier() {
- return String.format("%s/%s/%s", ResourceType.DataTransfer.getValue(), isInputPort ? "input-ports" : "output-ports", identifier);
- }
-
- @Override
- public String getName() {
- return name;
- }
- };
- }
-
- /**
- * Gets a Resource for performing transferring data to a port.
- *
* @param resource The resource to transfer data to
* @return The resource
*/
@@ -314,6 +355,11 @@ public final class ResourceFactory {
public String getName() {
return "Transfer data to " + resource.getName();
}
+
+ @Override
+ public String getSafeDescription() {
+ return "data transfers to " + resource.getSafeDescription();
+ }
};
}
@@ -342,7 +388,12 @@ public final class ResourceFactory {
@Override
public String getName() {
- return "Policies for " + resource.getName();
+ return POLICY_RESOURCE.getName() + resource.getName();
+ }
+
+ @Override
+ public String getSafeDescription() {
+ return POLICY_RESOURCE.getSafeDescription() + resource.getSafeDescription();
}
};
}
@@ -369,6 +420,47 @@ public final class ResourceFactory {
public String getName() {
return name;
}
+
+ @Override
+ public String getSafeDescription() {
+ final String componentType;
+ switch (resourceType) {
+ case ControllerService:
+ componentType = "Controller Service";
+ break;
+ case ProcessGroup:
+ componentType = "Process Group";
+ break;
+ case Template:
+ componentType = "Template";
+ break;
+ case Funnel:
+ componentType = "Funnel";
+ break;
+ case InputPort:
+ componentType = "Input Port";
+ break;
+ case OutputPort:
+ componentType = "Output Port";
+ break;
+ case Processor:
+ componentType = "Processor";
+ break;
+ case RemoteProcessGroup:
+ componentType = "Remote Process Group";
+ break;
+ case ReportingTask:
+ componentType = "Reporting Task";
+ break;
+ case Label:
+ componentType = "Label";
+ break;
+ default:
+ componentType = "Component";
+ break;
+ }
+ return componentType + " with ID " + identifier;
+ }
};
}
@@ -387,7 +479,12 @@ public final class ResourceFactory {
@Override
public String getName() {
- return "Data for " + resource.getName();
+ return DATA_RESOURCE.getName() + resource.getName();
+ }
+
+ @Override
+ public String getSafeDescription() {
+ return DATA_RESOURCE.getSafeDescription() + resource.getSafeDescription();
}
};
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
index 3d5efed..ddb4523 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java
@@ -136,6 +136,11 @@ public final class StandardConnection implements Connection {
return name;
}
+
+ @Override
+ public String getSafeDescription() {
+ return "Connection " + StandardConnection.this.getIdentifier();
+ }
};
}
@@ -172,7 +177,7 @@ public final class StandardConnection implements Connection {
@Override
public AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) {
if (user == null) {
- return AuthorizationResult.denied("Unknown user");
+ return AuthorizationResult.denied("Unknown user.");
}
// check the source
@@ -188,7 +193,7 @@ public final class StandardConnection implements Connection {
@Override
public void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) throws AccessDeniedException {
if (user == null) {
- throw new AccessDeniedException("Unknown user");
+ throw new AccessDeniedException("Unknown user.");
}
getSourceAuthorizable().authorize(authorizer, action, user, resourceContext);
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
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 67f768a..c8aad31 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
@@ -963,6 +963,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public String getName() {
return resourceIdentifier;
}
+
+ @Override
+ public String getSafeDescription() {
+ return "User " + userId;
+ }
},
() -> userDAO.deleteUser(userId),
false, // no user specific policies to remove
@@ -993,6 +998,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public String getName() {
return resourceIdentifier;
}
+
+ @Override
+ public String getSafeDescription() {
+ return "User Group " + userGroupId;
+ }
},
() -> userGroupDAO.deleteUserGroup(userGroupId),
false, // no user group specific policies to remove
@@ -1020,6 +1030,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public String getName() {
return accessPolicy.getResource();
}
+
+ @Override
+ public String getSafeDescription() {
+ return "Policy " + accessPolicyId;
+ }
},
() -> accessPolicyDAO.deleteAccessPolicy(accessPolicyId),
false, // no need to clean up any policies as it's already been removed above
@@ -2514,6 +2529,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
.accessAttempt(false)
.action(RequestAction.WRITE)
.userContext(userContext)
+ .explanationSupplier(() -> "Unable to retrieve port details.")
.build();
final AuthorizationResult result = authorizer.authorize(request);
@@ -2680,6 +2696,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public String getName() {
return resource;
}
+
+ @Override
+ public String getSafeDescription() {
+ return "Policy " + resource;
+ }
};
}
};
@@ -3100,7 +3121,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return entityFactory.createStatusHistoryEntity(dto, permissions);
}
- private boolean authorizeAction(final Action action) {
+ private AuthorizationResult authorizeAction(final Action action) {
final String sourceId = action.getSourceId();
final Component type = action.getSourceType();
@@ -3149,12 +3170,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
} catch (final ResourceNotFoundException e) {
// if the underlying component is gone, disallow
- return false;
+ return AuthorizationResult.denied("The component of this action is no longer in the data flow.");
}
// perform the authorization
- final AuthorizationResult result = authorizable.checkAuthorization(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
- return Result.Approved.equals(result.getResult());
+ return authorizable.checkAuthorization(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}
@Override
@@ -3178,7 +3198,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
if (history.getActions() != null) {
final List<ActionEntity> actionEntities = new ArrayList<>();
for (final Action action : history.getActions()) {
- actionEntities.add(entityFactory.createActionEntity(dtoFactory.createActionDto(action), authorizeAction(action)));
+ final AuthorizationResult result = authorizeAction(action);
+ actionEntities.add(entityFactory.createActionEntity(dtoFactory.createActionDto(action), Result.Approved.equals(result.getResult())));
}
historyDto.setActions(actionEntities);
}
@@ -3197,9 +3218,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
throw new ResourceNotFoundException(String.format("Unable to find action with id '%s'.", actionId));
}
- final boolean authorized = authorizeAction(action);
+ final AuthorizationResult result = authorizeAction(action);
+ final boolean authorized = Result.Approved.equals(result.getResult());
if (!authorized) {
- throw new AccessDeniedException("Access is denied.");
+ throw new AccessDeniedException(result.getExplanation());
}
// return the action
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
index 177e557..8146a39 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java
@@ -115,12 +115,12 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
.accessAttempt(true)
.action(RequestAction.READ)
.userContext(userContext)
+ .explanationSupplier(() -> "Unable to view the user interface.")
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
});
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
index 5c108a4..529f049 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
@@ -252,7 +252,7 @@ public class AccessResource extends ApplicationResource {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
if (user == null) {
- throw new AccessDeniedException("Unable to determine user details.");
+ throw new AccessDeniedException("No user authenticated in the request.");
}
final OtpAuthenticationToken authenticationToken = new OtpAuthenticationToken(user.getIdentity());
@@ -297,7 +297,7 @@ public class AccessResource extends ApplicationResource {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
if (user == null) {
- throw new AccessDeniedException("Unable to determine user details.");
+ throw new AccessDeniedException("No user authenticated in the request.");
}
final OtpAuthenticationToken authenticationToken = new OtpAuthenticationToken(user.getIdentity());
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
index 20b9f87..86ca792 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
@@ -112,12 +112,23 @@ public class ControllerResource extends ApplicationResource {
.accessAttempt(true)
.action(action)
.userContext(userContext)
+ .explanationSupplier(() -> {
+ final StringBuilder explanation = new StringBuilder("Unable to ");
+
+ if (RequestAction.READ.equals(action)) {
+ explanation.append("view ");
+ } else {
+ explanation.append("modify ");
+ }
+ explanation.append("the controller.");
+
+ return explanation.toString();
+ })
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java
index e3a2b9e..3d6c3be 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/CountersResource.java
@@ -98,12 +98,23 @@ public class CountersResource extends ApplicationResource {
.accessAttempt(true)
.action(action)
.userContext(userContext)
+ .explanationSupplier(() -> {
+ final StringBuilder explanation = new StringBuilder("Unable to ");
+
+ if (RequestAction.READ.equals(action)) {
+ explanation.append("view ");
+ } else {
+ explanation.append("modify ");
+ }
+ explanation.append("counters.");
+
+ return explanation.toString();
+ })
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
index 1b9bc99..a031725 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java
@@ -218,12 +218,12 @@ public class FlowResource extends ApplicationResource {
.accessAttempt(true)
.action(RequestAction.READ)
.userContext(userContext)
+ .explanationSupplier(() -> "Unable to view the user interface.")
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java
index 4e7a171..9044bbe 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProvenanceResource.java
@@ -108,12 +108,12 @@ public class ProvenanceResource extends ApplicationResource {
.accessAttempt(true)
.action(RequestAction.READ)
.userContext(userContext)
+ .explanationSupplier(() -> "Unable to query provenance.")
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java
index 67c1b22..cd41ed9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ResourceResource.java
@@ -78,12 +78,12 @@ public class ResourceResource extends ApplicationResource {
.accessAttempt(true)
.action(RequestAction.READ)
.userContext(userContext)
+ .explanationSupplier(() -> "Unable to retrieve resources.")
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
index efb1c26..744a9f4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SiteToSiteResource.java
@@ -116,12 +116,12 @@ public class SiteToSiteResource extends ApplicationResource {
.accessAttempt(true)
.action(RequestAction.READ)
.userContext(userContext)
+ .explanationSupplier(() -> "Unable to retrieve site to site details.")
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
index 0be9c49..04e8683 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/SystemDiagnosticsResource.java
@@ -81,12 +81,12 @@ public class SystemDiagnosticsResource extends ApplicationResource {
.accessAttempt(true)
.action(RequestAction.READ)
.userContext(userContext)
+ .explanationSupplier(() -> "Unable to view system diagnostics.")
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
- final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
- throw new AccessDeniedException(message);
+ throw new AccessDeniedException(result.getExplanation());
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/AccessDeniedExceptionMapper.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/AccessDeniedExceptionMapper.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/AccessDeniedExceptionMapper.java
index d55a386..9c5ba4d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/AccessDeniedExceptionMapper.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/AccessDeniedExceptionMapper.java
@@ -58,13 +58,16 @@ public class AccessDeniedExceptionMapper implements ExceptionMapper<AccessDenied
identity = user.getIdentity();
}
- logger.info(String.format("%s does not have permission to access the requested resource. Returning %s response.", identity, status));
+ logger.info(String.format("%s does not have permission to access the requested resource. %s Returning %s response.", identity, exception.getMessage(), status));
if (logger.isDebugEnabled()) {
logger.debug(StringUtils.EMPTY, exception);
}
- return Response.status(status).entity("Unable to perform the desired action due to insufficient permissions. Contact the system administrator.").type("text/plain").build();
+ return Response.status(status)
+ .entity(String.format("%s Contact the system administrator.", exception.getMessage()))
+ .type("text/plain")
+ .build();
}
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 55a0235..93d86c9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -1241,7 +1241,7 @@ public class ControllerFacade implements Authorizable {
private AuthorizationResult checkAuthorizationForReplay(final ProvenanceEventRecord event) {
// if the connection id isn't specified, then the replay wouldn't be available anyways and we have nothing to authorize against so deny it`
if (event.getSourceQueueIdentifier() == null) {
- return AuthorizationResult.denied();
+ return AuthorizationResult.denied("The connection id in the provenance event is unknown.");
}
final NiFiUser user = NiFiUserUtils.getNiFiUser();
@@ -1272,7 +1272,7 @@ public class ControllerFacade implements Authorizable {
private void authorizeReplay(final ProvenanceEventRecord event) {
// if the connection id isn't specified, then the replay wouldn't be available anyways and we have nothing to authorize against so deny it`
if (event.getSourceQueueIdentifier() == null) {
- throw new AccessDeniedException("The connection id is unknown.");
+ throw new AccessDeniedException("The connection id in the provenance event is unknown.");
}
final NiFiUser user = NiFiUserUtils.getNiFiUser();
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index 0b0e614..faecda7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -514,7 +514,7 @@ nf.Common = (function () {
if (xhr.status === 401) {
$('#message-title').text('Unauthorized');
} else if (xhr.status === 403) {
- $('#message-title').text('Access Denied');
+ $('#message-title').text('Insufficient Permissions');
} else if (xhr.status === 409) {
$('#message-title').text('Invalid State');
} else {
@@ -535,12 +535,17 @@ nf.Common = (function () {
return;
}
- // status code 400, 403, 404, and 409 are expected response codes for common errors.
- if (xhr.status === 400 || xhr.status === 403 || xhr.status === 404 || xhr.status === 409 || xhr.status === 503) {
+ // status code 400, 404, and 409 are expected response codes for common errors.
+ if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409 || xhr.status === 503) {
nf.Dialog.showOkDialog({
headerText: 'Error',
dialogContent: nf.Common.escapeHtml(xhr.responseText)
});
+ } else if (xhr.status === 403) {
+ nf.Dialog.showOkDialog({
+ headerText: 'Insufficient Permissions',
+ dialogContent: nf.Common.escapeHtml(xhr.responseText)
+ });
} else {
if (xhr.status < 99 || xhr.status === 12007 || xhr.status === 12029) {
var content = 'Please ensure the application is running and check the logs for any errors.';
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
index 03cc3b7..282fabc 100644
--- a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
+++ b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-persistent-provenance-repository/src/main/java/org/apache/nifi/provenance/PersistentProvenanceRepository.java
@@ -2384,14 +2384,14 @@ public class PersistentProvenanceRepository implements ProvenanceRepository {
}
if (user == null) {
- throw new AccessDeniedException("Cannot retrieve Provenance Lineage Submission because no user id was provided");
+ throw new AccessDeniedException("Cannot retrieve Provenance Lineage Submission because no user id was provided in the lineage request.");
}
if (userId == null || userId.equals(user.getIdentity())) {
return submission;
}
- throw new AccessDeniedException("Cannot retrieve Provenance Lineage Submission because " + user.getIdentity() + " is not the user who submitted the request");
+ throw new AccessDeniedException("Cannot retrieve Provenance Lineage Submission because " + user.getIdentity() + " is not the user who submitted the request.");
}
@Override
@@ -2405,14 +2405,14 @@ public class PersistentProvenanceRepository implements ProvenanceRepository {
}
if (user == null) {
- throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because no user id was provided");
+ throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because no user id was provided in the provenance request.");
}
if (userId == null || userId.equals(user.getIdentity())) {
return submission;
}
- throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because " + user.getIdentity() + " is not the user who submitted the request");
+ throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because " + user.getIdentity() + " is not the user who submitted the request.");
}
@Override
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/VolatileProvenanceRepository.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/VolatileProvenanceRepository.java b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/VolatileProvenanceRepository.java
index f889e8b..e467676 100644
--- a/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/VolatileProvenanceRepository.java
+++ b/nifi-nar-bundles/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/VolatileProvenanceRepository.java
@@ -460,14 +460,14 @@ public class VolatileProvenanceRepository implements ProvenanceRepository {
}
if (user == null) {
- throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because no user id was provided");
+ throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because no user id was provided in the provenance request.");
}
if (userId == null || userId.equals(user.getIdentity())) {
return submission;
}
- throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because " + user.getIdentity() + " is not the user who submitted the request");
+ throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because " + user.getIdentity() + " is not the user who submitted the request.");
}
public Lineage computeLineage(final String flowFileUUID, final NiFiUser user) throws IOException {
@@ -520,14 +520,14 @@ public class VolatileProvenanceRepository implements ProvenanceRepository {
}
if (user == null) {
- throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because no user id was provided");
+ throw new AccessDeniedException("Cannot retrieve Provenance Lineage Submission because no user id was provided in the lineage request.");
}
if (userId == null || userId.equals(user.getIdentity())) {
return submission;
}
- throw new AccessDeniedException("Cannot retrieve Provenance Query Submission because " + user.getIdentity() + " is not the user who submitted the request");
+ throw new AccessDeniedException("Cannot retrieve Provenance Lineage Submission because " + user.getIdentity() + " is not the user who submitted the request.");
}
public Lineage expandSpawnEventParents(String identifier) throws IOException {
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java
index a86423c..41b8106 100644
--- a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java
+++ b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/RangerNiFiAuthorizer.java
@@ -179,13 +179,13 @@ public class RangerNiFiAuthorizer implements Authorizer {
final boolean doesPolicyExist = nifiPlugin.doesPolicyExist(request.getResource().getIdentifier());
if (doesPolicyExist) {
- // a policy does exist for the resource so we were really denied access here
final String reason = result == null ? null : result.getReason();
- if (reason == null) {
- return AuthorizationResult.denied();
- } else {
- return AuthorizationResult.denied(result.getReason());
+ if (reason != null) {
+ logger.debug(String.format("Unable to authorize %s due to %s", identity, reason));
}
+
+ // a policy does exist for the resource so we were really denied access here
+ return AuthorizationResult.denied(request.getExplanationSupplier().get());
} else {
// a policy doesn't exist so return resource not found so NiFi can work back up the resource hierarchy
return AuthorizationResult.resourceNotFound();
http://git-wip-us.apache.org/repos/asf/nifi/blob/b1c9f0e7/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java
index 46084c4..679d2cb 100644
--- a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java
+++ b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/test/java/org/apache/nifi/ranger/authorization/TestRangerNiFiAuthorizer.java
@@ -467,6 +467,11 @@ public class TestRangerNiFiAuthorizer {
public String getName() {
return "/system";
}
+
+ @Override
+ public String getSafeDescription() {
+ return "system";
+ }
})
.action(RequestAction.WRITE)
.identity("admin")
@@ -526,6 +531,11 @@ public class TestRangerNiFiAuthorizer {
public String getName() {
return name;
}
+
+ @Override
+ public String getSafeDescription() {
+ return name;
+ }
}
/**