You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2016/11/21 20:31:19 UTC
[2/3] nifi git commit: NIFI-3050: Implemented access control logic
for restricted components.
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
index 52af285..7aa8321 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/StandardAuthorizableLookup.java
@@ -23,6 +23,7 @@ import org.apache.nifi.authorization.resource.DataAuthorizable;
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.resource.ResourceType;
+import org.apache.nifi.authorization.resource.RestrictedComponentsAuthorizable;
import org.apache.nifi.authorization.resource.TenantAuthorizable;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.components.PropertyDescriptor;
@@ -62,6 +63,8 @@ import java.util.Set;
class StandardAuthorizableLookup implements AuthorizableLookup {
private static final TenantAuthorizable TENANT_AUTHORIZABLE = new TenantAuthorizable();
+ private static final Authorizable RESTRICTED_COMPONENTS_AUTHORIZABLE = new RestrictedComponentsAuthorizable();
+
private static final Authorizable POLICIES_AUTHORIZABLE = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
@@ -134,15 +137,20 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
- public ControllerServiceReferencingComponentAuthorizable getProcessor(final String id) {
+ public ConfigurableComponentAuthorizable getProcessor(final String id) {
final ProcessorNode processorNode = processorDAO.getProcessor(id);
- return new ControllerServiceReferencingComponentAuthorizable() {
+ return new ConfigurableComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return processorNode;
}
@Override
+ public boolean isRestricted() {
+ return processorNode.isRestricted();
+ }
+
+ @Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return processorNode.getProperty(propertyDescriptor);
}
@@ -155,16 +163,21 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
- public ControllerServiceReferencingComponentAuthorizable getProcessorByType(String type) {
+ public ConfigurableComponentAuthorizable getProcessorByType(String type) {
try {
final ProcessorNode processorNode = controllerFacade.createTemporaryProcessor(type);
- return new ControllerServiceReferencingComponentAuthorizable() {
+ return new ConfigurableComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return processorNode;
}
@Override
+ public boolean isRestricted() {
+ return processorNode.isRestricted();
+ }
+
+ @Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return processorNode.getProperty(propertyDescriptor);
}
@@ -328,15 +341,20 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
- public ControllerServiceReferencingComponentAuthorizable getControllerService(final String id) {
+ public ConfigurableComponentAuthorizable getControllerService(final String id) {
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(id);
- return new ControllerServiceReferencingComponentAuthorizable() {
+ return new ConfigurableComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return controllerService;
}
@Override
+ public boolean isRestricted() {
+ return controllerService.isRestricted();
+ }
+
+ @Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return controllerService.getProperty(propertyDescriptor);
}
@@ -349,16 +367,21 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
- public ControllerServiceReferencingComponentAuthorizable getControllerServiceByType(String type) {
+ public ConfigurableComponentAuthorizable getControllerServiceByType(String type) {
try {
final ControllerServiceNode controllerService = controllerFacade.createTemporaryControllerService(type);
- return new ControllerServiceReferencingComponentAuthorizable() {
+ return new ConfigurableComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return controllerService;
}
@Override
+ public boolean isRestricted() {
+ return controllerService.isRestricted();
+ }
+
+ @Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return controllerService.getProperty(propertyDescriptor);
}
@@ -417,15 +440,20 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
- public ControllerServiceReferencingComponentAuthorizable getReportingTask(final String id) {
+ public ConfigurableComponentAuthorizable getReportingTask(final String id) {
final ReportingTaskNode reportingTaskNode = reportingTaskDAO.getReportingTask(id);
- return new ControllerServiceReferencingComponentAuthorizable() {
+ return new ConfigurableComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return reportingTaskNode;
}
@Override
+ public boolean isRestricted() {
+ return reportingTaskNode.isRestricted();
+ }
+
+ @Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return reportingTaskNode.getProperty(propertyDescriptor);
}
@@ -438,16 +466,21 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
- public ControllerServiceReferencingComponentAuthorizable getReportingTaskByType(String type) {
+ public ConfigurableComponentAuthorizable getReportingTaskByType(String type) {
try {
final ReportingTaskNode reportingTask = controllerFacade.createTemporaryReportingTask(type);
- return new ControllerServiceReferencingComponentAuthorizable() {
+ return new ConfigurableComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return reportingTask;
}
@Override
+ public boolean isRestricted() {
+ return reportingTask.isRestricted();
+ }
+
+ @Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return reportingTask.getProperty(propertyDescriptor);
}
@@ -603,17 +636,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
authorizable = getController();
break;
case Counters:
- authorizable = new Authorizable() {
- @Override
- public Authorizable getParentAuthorizable() {
- return null;
- }
-
- @Override
- public Resource getResource() {
- return ResourceFactory.getCountersResource();
- }
- };
+ authorizable = getCounters();
break;
case Flow:
authorizable = new Authorizable() {
@@ -629,17 +652,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
};
break;
case Provenance:
- authorizable = new Authorizable() {
- @Override
- public Authorizable getParentAuthorizable() {
- return null;
- }
-
- @Override
- public Resource getResource() {
- return ResourceFactory.getProvenanceResource();
- }
- };
+ authorizable = getProvenance();
break;
case Proxy:
authorizable = new Authorizable() {
@@ -655,7 +668,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
};
break;
case Policy:
- authorizable = POLICIES_AUTHORIZABLE;
+ authorizable = getPolicies();
break;
case Resource:
authorizable = new Authorizable() {
@@ -671,7 +684,6 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
};
break;
case SiteToSite:
- // TODO - new site-to-site and port specific site-to-site
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
@@ -685,21 +697,14 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
};
break;
case System:
- authorizable = new Authorizable() {
- @Override
- public Authorizable getParentAuthorizable() {
- return null;
- }
-
- @Override
- public Resource getResource() {
- return ResourceFactory.getSystemResource();
- }
- };
+ authorizable = getSystem();
break;
case Tenant:
authorizable = getTenant();
break;
+ case RestrictedComponents:
+ authorizable = getRestrictedComponents();
+ break;
}
if (authorizable == null) {
@@ -721,6 +726,11 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
+ public Authorizable getRestrictedComponents() {
+ return RESTRICTED_COMPONENTS_AUTHORIZABLE;
+ }
+
+ @Override
public Authorizable getSystem() {
return SYSTEM_AUTHORIZABLE;
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/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 53c0fe6..67f768a 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
@@ -2958,6 +2958,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
entity.setControllerPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getController()));
entity.setPoliciesPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getPolicies()));
entity.setSystemPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getSystem()));
+ entity.setRestrictedComponentsPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getRestrictedComponents()));
return entity;
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/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 fb38ce9..177e557 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
@@ -31,7 +31,7 @@ import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.AuthorizationResult.Result;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
+import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.UserContextKeys;
import org.apache.nifi.authorization.resource.Authorizable;
@@ -397,7 +397,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access
serviceFacade.authorizeAccess(lookup -> {
// authorize the processor
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessor(id);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getProcessor(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced service
@@ -588,7 +588,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access
serviceFacade.authorizeAccess(lookup -> {
// authorize the controller service
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerService(id);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getControllerService(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced service
@@ -753,7 +753,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access
serviceFacade.authorizeAccess(lookup -> {
// authorize the reporting task
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTask(id);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getReportingTask(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced service
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/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 09abe53..8f33ba6 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
@@ -30,7 +30,7 @@ import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.AuthorizationResult.Result;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
+import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.UserContextKeys;
import org.apache.nifi.authorization.resource.ResourceFactory;
@@ -283,8 +283,12 @@ public class ControllerResource extends ApplicationResource {
lookup -> {
authorizeController(RequestAction.WRITE);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestReportingTask.getType());
+ if (authorizable.isRestricted()) {
+ lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+ }
+
if (requestReportingTask.getProperties() != null) {
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTaskByType(requestReportingTask.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTask.getProperties(), authorizable, authorizer, lookup);
}
},
@@ -376,8 +380,12 @@ public class ControllerResource extends ApplicationResource {
lookup -> {
authorizeController(RequestAction.WRITE);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestControllerService.getType());
+ if (authorizable.isRestricted()) {
+ lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+ }
+
if (requestControllerService.getProperties() != null) {
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerServiceByType(requestControllerService.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
}
},
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.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/ControllerServiceResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
index 9b3805a..47a8189 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
@@ -25,7 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
+import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUserUtils;
@@ -621,7 +621,7 @@ public class ControllerServiceResource extends ApplicationResource {
requestRevision,
lookup -> {
// authorize the service
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerService(id);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getControllerService(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced services
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.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/ProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
index 527364c..c1ea58c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
@@ -28,7 +28,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizableLookup;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
+import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
import org.apache.nifi.authorization.ProcessGroupAuthorizable;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
@@ -615,12 +615,18 @@ public class ProcessGroupResource extends ApplicationResource {
serviceFacade,
requestProcessorEntity,
lookup -> {
+ final NiFiUser user = NiFiUserUtils.getNiFiUser();
+
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
- processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+ processGroup.authorize(authorizer, RequestAction.WRITE, user);
+
+ final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestProcessor.getType());
+ if (authorizable.isRestricted()) {
+ lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, user);
+ }
final ProcessorConfigDTO config = requestProcessor.getConfig();
if (config != null && config.getProperties() != null) {
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessorByType(requestProcessor.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(), authorizable, authorizer, lookup);
}
},
@@ -2129,11 +2135,17 @@ public class ProcessGroupResource extends ApplicationResource {
serviceFacade,
requestControllerServiceEntity,
lookup -> {
+ final NiFiUser user = NiFiUserUtils.getNiFiUser();
+
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
- processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
+ processGroup.authorize(authorizer, RequestAction.WRITE, user);
+
+ final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestControllerService.getType());
+ if (authorizable.isRestricted()) {
+ lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, user);
+ }
if (requestControllerService.getProperties() != null) {
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerServiceByType(requestControllerService.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
}
},
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.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/ProcessorResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
index cc16d26..fcdb99f 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
@@ -25,7 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
+import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUser;
@@ -448,7 +448,7 @@ public class ProcessorResource extends ApplicationResource {
lookup -> {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessor(id);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getProcessor(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
final ProcessorConfigDTO config = requestProcessorDTO.getConfig();
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.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/ReportingTaskResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
index 4d23804..57bc51d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
@@ -25,7 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
+import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUserUtils;
@@ -425,7 +425,7 @@ public class ReportingTaskResource extends ApplicationResource {
requestRevision,
lookup -> {
// authorize reporting task
- final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTask(id);
+ final ConfigurableComponentAuthorizable authorizable = lookup.getReportingTask(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced services
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.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/dto/DtoFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 3383632..3f48128 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -31,6 +31,7 @@ import org.apache.nifi.action.details.FlowChangeMoveDetails;
import org.apache.nifi.action.details.FlowChangePurgeDetails;
import org.apache.nifi.action.details.MoveDetails;
import org.apache.nifi.action.details.PurgeDetails;
+import org.apache.nifi.annotation.behavior.Restricted;
import org.apache.nifi.annotation.behavior.Stateful;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
@@ -1239,6 +1240,7 @@ public final class DtoFactory {
dto.setAnnotationData(reportingTaskNode.getAnnotationData());
dto.setComments(reportingTaskNode.getComments());
dto.setPersistsState(reportingTaskNode.getReportingTask().getClass().isAnnotationPresent(Stateful.class));
+ dto.setRestricted(reportingTaskNode.isRestricted());
final Map<String, String> defaultSchedulingPeriod = new HashMap<>();
defaultSchedulingPeriod.put(SchedulingStrategy.TIMER_DRIVEN.name(), SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod());
@@ -1308,6 +1310,7 @@ public final class DtoFactory {
dto.setAnnotationData(controllerServiceNode.getAnnotationData());
dto.setComments(controllerServiceNode.getComments());
dto.setPersistsState(controllerServiceNode.getControllerServiceImplementation().getClass().isAnnotationPresent(Stateful.class));
+ dto.setRestricted(controllerServiceNode.isRestricted());
// sort a copy of the properties
final Map<PropertyDescriptor, String> sortedProperties = new TreeMap<>(new Comparator<PropertyDescriptor>() {
@@ -2011,6 +2014,11 @@ public final class DtoFactory {
return dto;
}
+ private String getUsageRestriction(final Class<?> cls) {
+ final Restricted restriction = cls.getAnnotation(Restricted.class);
+ return restriction == null ? null : restriction.value();
+ }
+
/**
* Gets the capability description from the specified class.
*/
@@ -2050,6 +2058,7 @@ public final class DtoFactory {
final DocumentedTypeDTO type = new DocumentedTypeDTO();
type.setType(cls.getName());
type.setDescription(getCapabilityDescription(cls));
+ type.setUsageRestriction(getUsageRestriction(cls));
type.setTags(getTags(cls));
types.add(type);
}
@@ -2075,6 +2084,7 @@ public final class DtoFactory {
dto.setParentGroupId(node.getProcessGroup().getIdentifier());
dto.setInputRequirement(node.getInputRequirement().name());
dto.setPersistsState(node.getProcessor().getClass().isAnnotationPresent(Stateful.class));
+ dto.setRestricted(node.isRestricted());
dto.setType(node.getCanonicalClassName());
dto.setName(node.getName());
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/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 41eaae3..30fcbd7 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
@@ -788,6 +788,7 @@ public class ControllerFacade implements Authorizable {
final List<Resource> resources = new ArrayList<>();
resources.add(ResourceFactory.getFlowResource());
resources.add(ResourceFactory.getSystemResource());
+ resources.add(ResourceFactory.getRestrictedComponentsResource());
resources.add(ResourceFactory.getControllerResource());
resources.add(ResourceFactory.getCountersResource());
resources.add(ResourceFactory.getProvenanceResource());
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessControlHelper.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessControlHelper.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessControlHelper.java
index 6bd0b36..d22f418 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessControlHelper.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/AccessControlHelper.java
@@ -43,6 +43,7 @@ public class AccessControlHelper {
private NiFiTestUser writeUser;
private NiFiTestUser readWriteUser;
private NiFiTestUser noneUser;
+ private NiFiTestUser privilegedUser;
private static final String CONTEXT_PATH = "/nifi-api";
@@ -78,6 +79,7 @@ public class AccessControlHelper {
writeUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.WRITE_USER_DN);
readWriteUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.READ_WRITE_USER_DN);
noneUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.NONE_USER_DN);
+ privilegedUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.PRIVILEGED_USER_DN);
// populate the initial data flow
NiFiWebApiTest.populateFlow(server.getClient(), baseUrl, readWriteUser, READ_WRITE_CLIENT_ID);
@@ -99,6 +101,10 @@ public class AccessControlHelper {
return noneUser;
}
+ public NiFiTestUser getPrivilegedUser() {
+ return privilegedUser;
+ }
+
public void testGenericGetUri(final String uri) throws Exception {
ClientResponse response;
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ITProcessorAccessControl.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ITProcessorAccessControl.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ITProcessorAccessControl.java
index 37567c4..02817fc 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ITProcessorAccessControl.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/accesscontrol/ITProcessorAccessControl.java
@@ -19,6 +19,7 @@ package org.apache.nifi.integration.accesscontrol;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.nifi.integration.util.NiFiTestAuthorizer;
import org.apache.nifi.integration.util.NiFiTestUser;
+import org.apache.nifi.integration.util.RestrictedProcessor;
import org.apache.nifi.integration.util.SourceTestProcessor;
import org.apache.nifi.web.api.dto.ProcessorDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
@@ -399,6 +400,43 @@ public class ITProcessorAccessControl {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
+ /**
+ * Tests attempt to create a restricted processor.
+ *
+ * @throws Exception if there is an error creating this processor
+ */
+ @Test
+ public void testCreateRestrictedProcessor() throws Exception {
+ String url = helper.getBaseUrl() + "/process-groups/root/processors";
+
+ // create the processor
+ ProcessorDTO processor = new ProcessorDTO();
+ processor.setName("restricted");
+ processor.setType(RestrictedProcessor.class.getName());
+
+ // create the revision
+ final RevisionDTO revision = new RevisionDTO();
+ revision.setClientId(READ_WRITE_CLIENT_ID);
+ revision.setVersion(0L);
+
+ // create the entity body
+ ProcessorEntity entity = new ProcessorEntity();
+ entity.setRevision(revision);
+ entity.setComponent(processor);
+
+ // perform the request as a user with read/write but no restricted access
+ ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
+
+ // ensure the request is successful
+ assertEquals(403, response.getStatus());
+
+ // perform the request as a user with read/write and restricted access
+ response = helper.getPrivilegedUser().testPost(url, entity);
+
+ // ensure the request is successful
+ assertEquals(201, response.getStatus());
+ }
+
private ProcessorEntity getRandomProcessor(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
index f5d70cf..de55b83 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestAuthorizer.java
@@ -39,6 +39,7 @@ public class NiFiTestAuthorizer implements Authorizer {
public static final String READ_USER_DN = "read@nifi";
public static final String WRITE_USER_DN = "write@nifi";
public static final String READ_WRITE_USER_DN = "readwrite@nifi";
+ public static final String PRIVILEGED_USER_DN = "privileged@nifi";
public static final String TOKEN_USER = "user@nifi";
@@ -78,15 +79,24 @@ public class NiFiTestAuthorizer implements Authorizer {
return AuthorizationResult.approved();
}
+ // restricted component access
+ if (ResourceFactory.getRestrictedComponentsResource().getIdentifier().equals(request.getResource().getIdentifier())) {
+ if (PRIVILEGED_USER_DN.equals(request.getIdentity())) {
+ return AuthorizationResult.approved();
+ } else {
+ return AuthorizationResult.denied();
+ }
+ }
+
// read access
- if (READ_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity())) {
+ if (READ_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity()) || PRIVILEGED_USER_DN.equals(request.getIdentity())) {
if (RequestAction.READ.equals(request.getAction())) {
return AuthorizationResult.approved();
}
}
// write access
- if (WRITE_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity())) {
+ if (WRITE_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity()) || PRIVILEGED_USER_DN.equals(request.getIdentity())) {
if (RequestAction.WRITE.equals(request.getAction())) {
return AuthorizationResult.approved();
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/RestrictedProcessor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/RestrictedProcessor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/RestrictedProcessor.java
new file mode 100644
index 0000000..4da4b5a
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/RestrictedProcessor.java
@@ -0,0 +1,51 @@
+/*
+ * 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.integration.util;
+
+import org.apache.nifi.annotation.behavior.Restricted;
+import org.apache.nifi.processor.AbstractSessionFactoryProcessor;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSessionFactory;
+import org.apache.nifi.processor.ProcessorInitializationContext;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processor.exception.ProcessException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Restricted("")
+public class RestrictedProcessor extends AbstractSessionFactoryProcessor {
+
+ public RestrictedProcessor() {
+ }
+
+ @Override
+ public Set<Relationship> getRelationships() {
+ final Set<Relationship> rels = new HashSet<>();
+ rels.add(new Relationship.Builder().name("success").build());
+ return rels;
+ }
+
+ @Override
+ public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) throws ProcessException {
+ }
+
+ @Override
+ protected void init(final ProcessorInitializationContext context) {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
index 0466df5..cdd8318 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/common-ui.css
@@ -427,7 +427,13 @@ div.button {
cursor: pointer;
}
-div.button:hover {
+div.button.disabled-button {
+ color: #a8a8a8 !important;
+ cursor: not-allowed;
+ opacity: 0.7;
+}
+
+div.button:hover:not(.disabled-button) {
background-color: #004849;
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
index e965bf2..bc198a9 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
@@ -175,6 +175,18 @@ text.processor-icon {
font-size: 30px;
}
+circle.restricted-background {
+ visibility: hidden;
+ fill: rgba(255, 255, 255, 0.90);
+}
+
+text.restricted {
+ visibility: hidden;
+ font-family: FontAwesome;
+ font-size: 12px;
+ fill: #ba554a;
+}
+
text.run-status-icon {
font-size: 13px;
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-processor-dialog.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-processor-dialog.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-processor-dialog.css
index 111550c..29a3232 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-processor-dialog.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-processor-dialog.css
@@ -86,4 +86,12 @@
#processor-type-filter {
width: 200px;
+}
+
+/*
+ Restricted
+*/
+
+div.view-usage-restriction {
+ color: #ba554a !important;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css
index a1a5f89..8b90b8d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css
@@ -89,7 +89,7 @@ div.policy-controls {
#policy-type-list {
float: left;
- width: 190px;
+ width: 225px;
margin-right: 3px;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
index 82f8bf6..03cca96 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
@@ -36,6 +36,7 @@
* hover: '#004849',
* text: '#ffffff'
* },
+ * disabled: isDisabledFunction,
* handler: {
* click: cancelHandler
* }
@@ -46,6 +47,7 @@
* hover: '#C7D2D7',
* text: '#004849'
* },
+ * disabled: isDisabledFunction,
* handler: {
* click: applyHandler
* }
@@ -101,27 +103,54 @@
var addButtons = function (dialog, buttonModel) {
if (isDefinedAndNotNull(buttonModel)) {
var buttonWrapper = $('<div class="dialog-buttons"></div>');
- var button;
$.each(buttonModel, function (i, buttonConfig) {
- var clazz = isDefinedAndNotNull(buttonConfig.clazz) ? buttonConfig.clazz : '';
- if (buttonConfig.color) {
- button = $('<div class="button ' + clazz + '" style="color:' + buttonConfig.color.text + '; background:' + buttonConfig.color.base + ';"><span>' + buttonConfig.buttonText + '</span></div>');
- button.hover(function () {
- $(this).css("background-color", buttonConfig.color.hover);
- }, function () {
- $(this).css("background-color", buttonConfig.color.base);
+ var isDisabled = function () {
+ return typeof buttonConfig.disabled === 'function' && buttonConfig.disabled.call() === true;
+ };
+
+ // create the button
+ var button = $('<div class="button"></div>').append($('<span></span>').text(buttonConfig.buttonText));
+
+ // add the class if specified
+ if (isDefinedAndNotNull(buttonConfig.clazz)) {
+ button.addClass(buttonConfig.clazz);
+ }
+
+ // set the color if specified
+ if (isDefinedAndNotNull(buttonConfig.color)) {
+ button.css({
+ 'background': buttonConfig.color.base,
+ 'color': buttonConfig.color.text
});
- } else {
- button = $('<div class="button ' + clazz + '"><span>' + buttonConfig.buttonText + '</span></div>');
}
- button.click(function () {
- var handler = $(this).data('handler');
- if (isDefinedAndNotNull(handler) && typeof handler.click === 'function') {
- handler.click.call(dialog);
+
+ // check if the button should be disabled
+ if (isDisabled()) {
+ button.addClass('disabled-button');
+ } else {
+ // enable custom hover if specified
+ if (isDefinedAndNotNull(buttonConfig.color)) {
+ button.hover(function () {
+ $(this).css("background-color", buttonConfig.color.hover);
+ }, function () {
+ $(this).css("background-color", buttonConfig.color.base);
+ });
}
- }).data('handler', buttonConfig.handler).appendTo(buttonWrapper);
+
+ button.click(function () {
+ var handler = $(this).data('handler');
+ if (isDefinedAndNotNull(handler) && typeof handler.click === 'function') {
+ handler.click.call(dialog);
+ }
+ });
+ }
+
+ // add the button to the wrapper
+ button.data('handler', buttonConfig.handler).appendTo(buttonWrapper);
});
- buttonWrapper.appendTo(dialog);
+
+ // store the button model to refresh later
+ dialog.append(buttonWrapper).data('buttonModel', buttonModel);
}
};
@@ -259,6 +288,22 @@
},
/**
+ * Refreshes the buttons with the existing model.
+ */
+ refreshButtons: function () {
+ return this.each(function () {
+ var dialog = $(this);
+ var buttons = dialog.data('buttonModel');
+
+ // remove the current buttons
+ dialog.children('.dialog-buttons').remove();
+
+ // add the new buttons
+ addButtons(dialog, buttons);
+ });
+ },
+
+ /**
* Sets the header text of the dialog.
*
* @argument {string} text Text to use a as a header
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js
index b563b10..c96bab4 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js
@@ -235,6 +235,15 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
}).fail(nf.Common.handleAjaxError);
};
+ /**
+ * Whether the specified item is selectable.
+ *
+ * @param item process type
+ */
+ var isSelectable = function (item) {
+ return nf.Common.isBlank(item.usageRestriction) || nf.Common.canAccessRestrictedComponents();
+ };
+
function ProcessorComponent() {
this.icon = 'icon icon-processor';
@@ -257,7 +266,7 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
init: function () {
// initialize the processor type table
var processorTypesColumns = [
- {id: 'type', name: 'Type', field: 'label', sortable: true, resizable: true},
+ {id: 'type', name: 'Type', field: 'label', formatter: nf.Common.typeFormatter, sortable: true, resizable: true},
{id: 'tags', name: 'Tags', field: 'tags', sortable: true, resizable: true}
];
var processorTypesOptions = {
@@ -319,9 +328,15 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
$('#processor-type-name').text(processorType.label).ellipsis();
$('#selected-processor-name').text(processorType.label);
$('#selected-processor-type').text(processorType.type);
+
+ // refresh the buttons based on the current selection
+ $('#new-processor-dialog').modal('refreshButtons');
}
}
});
+ processorTypesGrid.onViewportChanged.subscribe(function (e, args) {
+ nf.Common.cleanUpTooltips($('#processor-types-table'), 'div.view-usage-restriction');
+ });
// wire up the dataview to the grid
processorTypesData.onRowCountChanged.subscribe(function (e, args) {
@@ -338,7 +353,31 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
processorTypesData.syncGridSelection(processorTypesGrid, false);
// hold onto an instance of the grid
- $('#processor-types-table').data('gridInstance', processorTypesGrid);
+ $('#processor-types-table').data('gridInstance', processorTypesGrid).on('mouseenter', 'div.slick-cell', function (e) {
+ var usageRestriction = $(this).find('div.view-usage-restriction');
+ if (usageRestriction.length && !usageRestriction.data('qtip')) {
+ var rowId = $(this).find('span.row-id').text();
+
+ // get the status item
+ var item = processorTypesData.getItemById(rowId);
+
+ // show the tooltip
+ if (nf.Common.isDefinedAndNotNull(item.usageRestriction)) {
+ usageRestriction.qtip($.extend({}, nf.Common.config.tooltipConfig, {
+ content: item.usageRestriction,
+ position: {
+ container: $('#summary'),
+ at: 'bottom right',
+ my: 'top left',
+ adjust: {
+ x: 4,
+ y: 4
+ }
+ }
+ }));
+ }
+ }
+ });
// load the available processor types, this select is shown in the
// new processor dialog when a processor is dragged onto the screen
@@ -362,6 +401,7 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
label: nf.Common.substringAfterLast(type, '.'),
type: type,
description: nf.Common.escapeHtml(documentedType.description),
+ usageRestriction: nf.Common.escapeHtml(documentedType.usageRestriction),
tags: documentedType.tags.join(', ')
});
@@ -497,6 +537,7 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
*/
promptForProcessorType: function (pt) {
var self = this;
+
// handles adding the selected processor at the specified point
var addProcessor = function () {
// get the type of processor currently selected
@@ -525,10 +566,12 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
var gridDoubleClick = function (e, args) {
var processorType = grid.getDataItem(args.row);
- $('#selected-processor-name').text(processorType.label);
- $('#selected-processor-type').text(processorType.type);
+ if (isSelectable(processorType)) {
+ $('#selected-processor-name').text(processorType.label);
+ $('#selected-processor-type').text(processorType.type);
- addProcessor();
+ addProcessor();
+ }
};
// register a handler for double click events
@@ -542,6 +585,17 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
hover: '#004849',
text: '#ffffff'
},
+ disabled: function () {
+ var selected = grid.getSelectedRows();
+
+ if (selected.length > 0) {
+ // grid configured with multi-select = false
+ var item = grid.getDataItem(selected[0]);
+ return isSelectable(item) === false;
+ } else {
+ return false;
+ }
+ },
handler: {
click: addProcessor
}
@@ -576,7 +630,15 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
$('#processor-type-filter').focus().off('keyup').on('keyup', function (e) {
var code = e.keyCode ? e.keyCode : e.which;
if (code === $.ui.keyCode.ENTER) {
- addProcessor();
+ var selected = grid.getSelectedRows();
+
+ if (selected.length > 0) {
+ // grid configured with multi-select = false
+ var item = grid.getDataItem(selected[0]);
+ if (isSelectable(item)) {
+ addProcessor();
+ }
+ }
} else {
applyFilter();
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
index cb88182..9473978 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
@@ -40,6 +40,15 @@ nf.ControllerServices = (function () {
};
/**
+ * Whether the specified item is selectable.
+ *
+ * @param item controller service type
+ */
+ var isSelectable = function (item) {
+ return nf.Common.isBlank(item.usageRestriction) || nf.Common.canAccessRestrictedComponents();
+ };
+
+ /**
* Get the text out of the filter field. If the filter field doesn't
* have any text it will contain the text 'filter list' so this method
* accounts for that.
@@ -254,7 +263,7 @@ nf.ControllerServices = (function () {
var initNewControllerServiceDialog = function () {
// initialize the processor type table
var controllerServiceTypesColumns = [
- {id: 'type', name: 'Type', field: 'label', sortable: false, resizable: true},
+ {id: 'type', name: 'Type', field: 'label', formatter: nf.Common.typeFormatter, sortable: false, resizable: true},
{id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true}
];
@@ -298,9 +307,15 @@ nf.ControllerServices = (function () {
$('#controller-service-type-name').text(controllerServiceType.label).ellipsis();
$('#selected-controller-service-name').text(controllerServiceType.label);
$('#selected-controller-service-type').text(controllerServiceType.type);
+
+ // refresh the buttons based on the current selection
+ $('#new-controller-service-dialog').modal('refreshButtons');
}
}
});
+ controllerServiceTypesGrid.onViewportChanged.subscribe(function (e, args) {
+ nf.Common.cleanUpTooltips($('#controller-service-types-table'), 'div.view-usage-restriction');
+ });
// wire up the dataview to the grid
controllerServiceTypesData.onRowCountChanged.subscribe(function (e, args) {
@@ -317,7 +332,31 @@ nf.ControllerServices = (function () {
controllerServiceTypesData.syncGridSelection(controllerServiceTypesGrid, true);
// hold onto an instance of the grid
- $('#controller-service-types-table').data('gridInstance', controllerServiceTypesGrid);
+ $('#controller-service-types-table').data('gridInstance', controllerServiceTypesGrid).on('mouseenter', 'div.slick-cell', function (e) {
+ var usageRestriction = $(this).find('div.view-usage-restriction');
+ if (usageRestriction.length && !usageRestriction.data('qtip')) {
+ var rowId = $(this).find('span.row-id').text();
+
+ // get the status item
+ var item = controllerServiceTypesData.getItemById(rowId);
+
+ // show the tooltip
+ if (nf.Common.isDefinedAndNotNull(item.usageRestriction)) {
+ usageRestriction.qtip($.extend({}, nf.Common.config.tooltipConfig, {
+ content: item.usageRestriction,
+ position: {
+ container: $('#summary'),
+ at: 'bottom right',
+ my: 'top left',
+ adjust: {
+ x: 4,
+ y: 4
+ }
+ }
+ }));
+ }
+ }
+ });
// load the available controller services
$.ajax({
@@ -339,6 +378,7 @@ nf.ControllerServices = (function () {
label: nf.Common.substringAfterLast(documentedType.type, '.'),
type: documentedType.type,
description: nf.Common.escapeHtml(documentedType.description),
+ usageRestriction: nf.Common.escapeHtml(documentedType.usageRestriction),
tags: documentedType.tags.join(', ')
});
@@ -831,11 +871,22 @@ nf.ControllerServices = (function () {
* @param {jQuery} serviceTable
*/
promptNewControllerService: function (controllerServicesUri, serviceTable) {
+ // get the grid reference
+ var grid = $('#controller-service-types-table').data('gridInstance');
+
// update the keyhandler
$('#controller-service-type-filter').off('keyup').on('keyup', function (e) {
var code = e.keyCode ? e.keyCode : e.which;
if (code === $.ui.keyCode.ENTER) {
- addSelectedControllerService(controllerServicesUri, serviceTable);
+ var selected = grid.getSelectedRows();
+
+ if (selected.length > 0) {
+ // grid configured with multi-select = false
+ var item = grid.getDataItem(selected[0]);
+ if (isSelectable(item)) {
+ addSelectedControllerService(controllerServicesUri, serviceTable);
+ }
+ }
} else {
applyControllerServiceTypeFilter();
}
@@ -849,6 +900,17 @@ nf.ControllerServices = (function () {
hover: '#004849',
text: '#ffffff'
},
+ disabled: function () {
+ var selected = grid.getSelectedRows();
+
+ if (selected.length > 0) {
+ // grid configured with multi-select = false
+ var item = grid.getDataItem(selected[0]);
+ return isSelectable(item) === false;
+ } else {
+ return false;
+ }
+ },
handler: {
click: function () {
addSelectedControllerService(controllerServicesUri, serviceTable);
@@ -878,7 +940,10 @@ nf.ControllerServices = (function () {
// update the dbl click handler and subsrcibe
dblClick = function(e, args) {
var controllerServiceType = controllerServiceTypesGrid.getDataItem(args.row);
- addControllerService(controllerServicesUri, serviceTable, controllerServiceType.type);
+
+ if (isSelectable(controllerServiceType)) {
+ addControllerService(controllerServicesUri, serviceTable, controllerServiceType.type);
+ }
};
controllerServiceTypesGrid.onDblClick.subscribe(dblClick);
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
index 19ea71e..b2f95ba 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js
@@ -343,6 +343,7 @@ nf.PolicyManagement = (function () {
nf.Common.getPolicyTypeListing('flow'),
nf.Common.getPolicyTypeListing('controller'),
nf.Common.getPolicyTypeListing('provenance'),
+ nf.Common.getPolicyTypeListing('restricted-components'),
nf.Common.getPolicyTypeListing('policies'),
nf.Common.getPolicyTypeListing('tenants'),
nf.Common.getPolicyTypeListing('site-to-site'),
@@ -364,7 +365,7 @@ nf.PolicyManagement = (function () {
$('#controller-policy-target').hide();
// record the action
- if (option.value === 'proxy') {
+ if (option.value === 'proxy' || option.value === 'restricted-components') {
$('#selected-policy-action').text('write');
} else {
$('#selected-policy-action').text('read');
@@ -1398,7 +1399,7 @@ nf.PolicyManagement = (function () {
if (policyType === 'controller') {
$('#selected-policy-action').text($('#controller-policy-target').combo('getSelectedOption').value);
- } else if (policyType === 'proxy') {
+ } else if (policyType === 'proxy' || policyType === 'restricted-components') {
$('#selected-policy-action').text('write');
} else {
$('#selected-policy-action').text('read');
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor.js
index 9a5506a..1a02dae 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor.js
@@ -132,6 +132,24 @@ nf.Processor = (function () {
})
.text('\ue807');
+ // restricted icon background
+ processor.append('circle')
+ .attr({
+ 'r': 9,
+ 'cx': 12,
+ 'cy': 12,
+ 'class': 'restricted-background'
+ });
+
+ // restricted icon
+ processor.append('text')
+ .attr({
+ 'x': 7.75,
+ 'y': 17,
+ 'class': 'restricted'
+ })
+ .text('\uf132');
+
// make processors selectable
processor.call(nf.Selectable.activate).call(nf.ContextMenu.activate);
};
@@ -603,10 +621,27 @@ nf.Processor = (function () {
return color;
});
+
+ // restricted component indicator
+ processor.select('circle.restricted-background').style('visibility', showRestricted);
+ processor.select('text.restricted').style('visibility', showRestricted);
});
};
/**
+ * Returns whether the resticted indicator should be shown for a given
+ * @param d
+ * @returns {*}
+ */
+ var showRestricted = function (d) {
+ if (!d.permissions.canRead) {
+ return 'hidden';
+ }
+
+ return d.component.restricted ? 'visible' : 'hidden';
+ }
+
+ /**
* Updates the stats for the processors in the specified selection.
*
* @param {selection} updated The processors to update
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
index ed70367..d41752e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
@@ -156,6 +156,15 @@ nf.Settings = (function () {
};
/**
+ * Whether the specified item is selectable.
+ *
+ * @param item reporting task type
+ */
+ var isSelectable = function (item) {
+ return nf.Common.isBlank(item.usageRestriction) || nf.Common.canAccessRestrictedComponents();
+ };
+
+ /**
* Formatter for the name column.
*
* @param {type} row
@@ -406,7 +415,17 @@ nf.Settings = (function () {
$('#reporting-task-type-filter').on('keyup', function (e) {
var code = e.keyCode ? e.keyCode : e.which;
if (code === $.ui.keyCode.ENTER) {
- addSelectedReportingTask();
+ // get the grid reference
+ var grid = $('#reporting-task-types-table').data('gridInstance');
+ var selected = grid.getSelectedRows();
+
+ if (selected.length > 0) {
+ // grid configured with multi-select = false
+ var item = grid.getDataItem(selected[0]);
+ if (isSelectable(item)) {
+ addSelectedReportingTask();
+ }
+ }
} else {
applyReportingTaskTypeFilter();
}
@@ -414,7 +433,7 @@ nf.Settings = (function () {
// initialize the processor type table
var reportingTaskTypesColumns = [
- {id: 'type', name: 'Type', field: 'label', sortable: false, resizable: true},
+ {id: 'type', name: 'Type', field: 'label', formatter: nf.Common.typeFormatter, sortable: false, resizable: true},
{id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true}
];
@@ -458,12 +477,21 @@ nf.Settings = (function () {
$('#reporting-task-type-name').text(reportingTaskType.label).ellipsis();
$('#selected-reporting-task-name').text(reportingTaskType.label);
$('#selected-reporting-task-type').text(reportingTaskType.type);
+
+ // refresh the buttons based on the current selection
+ $('#new-reporting-task-dialog').modal('refreshButtons');
}
}
});
reportingTaskTypesGrid.onDblClick.subscribe(function (e, args) {
var reportingTaskType = reportingTaskTypesGrid.getDataItem(args.row);
- addReportingTask(reportingTaskType.type);
+
+ if (isSelectable(reportingTaskType)) {
+ addReportingTask(reportingTaskType.type);
+ }
+ });
+ reportingTaskTypesGrid.onViewportChanged.subscribe(function (e, args) {
+ nf.Common.cleanUpTooltips($('#reporting-task-types-table'), 'div.view-usage-restriction');
});
// wire up the dataview to the grid
@@ -481,7 +509,31 @@ nf.Settings = (function () {
reportingTaskTypesData.syncGridSelection(reportingTaskTypesGrid, true);
// hold onto an instance of the grid
- $('#reporting-task-types-table').data('gridInstance', reportingTaskTypesGrid);
+ $('#reporting-task-types-table').data('gridInstance', reportingTaskTypesGrid).on('mouseenter', 'div.slick-cell', function (e) {
+ var usageRestriction = $(this).find('div.view-usage-restriction');
+ if (usageRestriction.length && !usageRestriction.data('qtip')) {
+ var rowId = $(this).find('span.row-id').text();
+
+ // get the status item
+ var item = reportingTaskTypesData.getItemById(rowId);
+
+ // show the tooltip
+ if (nf.Common.isDefinedAndNotNull(item.usageRestriction)) {
+ usageRestriction.qtip($.extend({}, nf.Common.config.tooltipConfig, {
+ content: item.usageRestriction,
+ position: {
+ container: $('#summary'),
+ at: 'bottom right',
+ my: 'top left',
+ adjust: {
+ x: 4,
+ y: 4
+ }
+ }
+ }));
+ }
+ }
+ });
// load the available reporting tasks
$.ajax({
@@ -503,6 +555,7 @@ nf.Settings = (function () {
label: nf.Common.substringAfterLast(documentedType.type, '.'),
type: documentedType.type,
description: nf.Common.escapeHtml(documentedType.description),
+ usageRestriction: nf.Common.escapeHtml(documentedType.usageRestriction),
tags: documentedType.tags.join(', ')
});
@@ -537,6 +590,17 @@ nf.Settings = (function () {
hover: '#004849',
text: '#ffffff'
},
+ disabled: function () {
+ var selected = reportingTaskTypesGrid.getSelectedRows();
+
+ if (selected.length > 0) {
+ // grid configured with multi-select = false
+ var item = reportingTaskTypesGrid.getDataItem(selected[0]);
+ return isSelectable(item) === false;
+ } else {
+ return false;
+ }
+ },
handler: {
click: function () {
addSelectedReportingTask();
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/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 5d7054c..b0fdb3e 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
@@ -91,6 +91,10 @@ nf.Common = (function () {
value: 'provenance',
description: 'Allows users to submit a Provenance Search and request Event Lineage'
}, {
+ text: 'access restricted components',
+ value: 'restricted-components',
+ description: 'Allows users to create/modify restricted components assuming otherwise sufficient permissions'
+ }, {
text: 'access all policies',
value: 'policies',
description: 'Allows users to view/modify the policies for all components'
@@ -157,6 +161,32 @@ nf.Common = (function () {
currentUser: undefined,
/**
+ * Formats type of a component for a new instance dialog.
+ *
+ * @param row
+ * @param cell
+ * @param value
+ * @param columnDef
+ * @param dataContext
+ * @returns {string}
+ */
+ typeFormatter: function (row, cell, value, columnDef, dataContext) {
+ var markup = '';
+
+ // restriction
+ if (nf.Common.isBlank(dataContext.usageRestriction) === false) {
+ markup += '<div class="view-usage-restriction fa fa-shield"></div><span class="hidden row-id">' + nf.Common.escapeHtml(dataContext.id) + '</span>';
+ } else {
+ markup += '<div class="fa"></div>';
+ }
+
+ // type
+ markup += value;
+
+ return markup;
+ },
+
+ /**
* Sets the current user.
*
* @param currentUser
@@ -272,6 +302,19 @@ nf.Common = (function () {
},
/**
+ * Determines whether the current user can access restricted comopnents.
+ *
+ * @returns {boolean}
+ */
+ canAccessRestrictedComponents: function () {
+ if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
+ return nf.Common.currentUser.restrictedComponentsPermissions.canWrite === true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
* Determines whether the current user can access counters.
*
* @returns {boolean}
http://git-wip-us.apache.org/repos/asf/nifi/blob/7f5eabd6/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/src/main/java/org/apache/nifi/processors/hadoop/DeleteHDFS.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/src/main/java/org/apache/nifi/processors/hadoop/DeleteHDFS.java b/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/src/main/java/org/apache/nifi/processors/hadoop/DeleteHDFS.java
index 371b9e1..ed4d10d 100644
--- a/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/src/main/java/org/apache/nifi/processors/hadoop/DeleteHDFS.java
+++ b/nifi-nar-bundles/nifi-hadoop-bundle/nifi-hdfs-processors/src/main/java/org/apache/nifi/processors/hadoop/DeleteHDFS.java
@@ -16,20 +16,13 @@
*/
package org.apache.nifi.processors.hadoop;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.nifi.annotation.behavior.InputRequirement;
+import org.apache.nifi.annotation.behavior.Restricted;
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
import org.apache.nifi.annotation.documentation.CapabilityDescription;
import org.apache.nifi.annotation.documentation.Tags;
@@ -41,16 +34,24 @@ import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.util.StandardValidators;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
@TriggerWhenEmpty
@InputRequirement(InputRequirement.Requirement.INPUT_ALLOWED)
-@Tags({ "hadoop", "HDFS", "delete", "remove", "filesystem" })
+@Tags({ "hadoop", "HDFS", "delete", "remove", "filesystem", "restricted" })
@CapabilityDescription("Deletes a file from HDFS. The file can be provided as an attribute from an incoming FlowFile, "
+ "or a statically set file that is periodically removed. If this processor has an incoming connection, it"
+ "will ignore running on a periodic basis and instead rely on incoming FlowFiles to trigger a delete. "
+ "Optionally, you may specify use a wildcard character to match multiple files or directories.")
+@Restricted("Provides operator the ability to delete any file that NiFi has access to in HDFS or the local filesystem.")
public class DeleteHDFS extends AbstractHadoopProcessor {
public static final Relationship REL_SUCCESS = new Relationship.Builder()
.name("success")