From 5125b9676f4ae840296a4f79845acdb0960878e4 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Thu, 28 Jul 2016 16:22:58 -0400 Subject: [PATCH] NIFI-2122: - Merging responses for the current user and the flow configuration. - Returning whether NiFi is configured with a policy based authorizer in the flow configuration. - Only showing the users and policy icons when configured with a policy based authorizer. - Failing faster when invoking the users or policies endpoint when not configured with a configurable authorizer. --- .../web/api/dto/FlowConfigurationDTO.java | 16 +++++ .../http/StandardHttpResponseMerger.java | 4 ++ .../endpoints/CurrentUserEndpointMerger.java | 65 +++++++++++++++++++ .../FlowConfigurationEndpointMerger.java | 58 +++++++++++++++++ .../nifi/web/api/AccessPolicyResource.java | 27 ++++++++ .../org/apache/nifi/web/api/FlowResource.java | 8 +++ .../apache/nifi/web/api/TenantsResource.java | 61 ++++++++++++++++- .../apache/nifi/web/api/dto/DtoFactory.java | 2 + .../apache/nifi/web/dao/AccessPolicyDAO.java | 2 + .../StandardPolicyBasedAuthorizerDAO.java | 1 - .../WEB-INF/partials/canvas/canvas-header.jsp | 8 +-- .../WEB-INF/partials/canvas/navigation.jsp | 4 +- .../src/main/webapp/css/policy-management.css | 2 +- .../src/main/webapp/js/nf/canvas/nf-canvas.js | 11 ++++ .../js/nf/canvas/nf-controller-services.js | 6 +- .../main/webapp/js/nf/canvas/nf-settings.js | 6 +- .../js/nf/templates/nf-templates-table.js | 9 +-- 17 files changed, 272 insertions(+), 18 deletions(-) create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CurrentUserEndpointMerger.java create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowConfigurationEndpointMerger.java diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java index d5028d254c4d..969168cd0000 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java @@ -29,6 +29,7 @@ @XmlType(name = "flowConfiguration") public class FlowConfigurationDTO { + private Boolean supportsConfigurableAuthorizer; private Long autoRefreshIntervalSeconds; private Date currentTime; @@ -49,6 +50,21 @@ public void setAutoRefreshIntervalSeconds(Long autoRefreshIntervalSeconds) { this.autoRefreshIntervalSeconds = autoRefreshIntervalSeconds; } + /** + * @return whether this NiFi supports a configurable authorizer. This value is read only + */ + @ApiModelProperty( + value = "Whether this NiFi supports a configurable authorizer.", + readOnly = true + ) + public Boolean getSupportsConfigurableAuthorizer() { + return supportsConfigurableAuthorizer; + } + + public void setSupportsConfigurableAuthorizer(Boolean supportsConfigurableAuthorizer) { + this.supportsConfigurableAuthorizer = supportsConfigurableAuthorizer; + } + /** * @return current time on the server */ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java index 8ff321d53396..ad9f33feceb9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/StandardHttpResponseMerger.java @@ -28,7 +28,9 @@ import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServicesEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.ControllerStatusEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.CountersEndpointMerger; +import org.apache.nifi.cluster.coordination.http.endpoints.CurrentUserEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.DropRequestEndpiontMerger; +import org.apache.nifi.cluster.coordination.http.endpoints.FlowConfigurationEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.FlowMerger; import org.apache.nifi.cluster.coordination.http.endpoints.FlowSnippetEndpointMerger; import org.apache.nifi.cluster.coordination.http.endpoints.GroupStatusEndpointMerger; @@ -105,6 +107,8 @@ public class StandardHttpResponseMerger implements HttpResponseMerger { endpointMergers.add(new SystemDiagnosticsEndpointMerger()); endpointMergers.add(new CountersEndpointMerger()); endpointMergers.add(new FlowMerger()); + endpointMergers.add(new CurrentUserEndpointMerger()); + endpointMergers.add(new FlowConfigurationEndpointMerger()); endpointMergers.add(new TemplatesEndpointMerger()); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CurrentUserEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CurrentUserEndpointMerger.java new file mode 100644 index 000000000000..4a97d7a63d24 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/CurrentUserEndpointMerger.java @@ -0,0 +1,65 @@ +/* + * 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.cluster.coordination.http.endpoints; + +import org.apache.nifi.cluster.manager.NodeResponse; +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.dto.PermissionsDTO; +import org.apache.nifi.web.api.entity.CurrentUserEntity; + +import java.net.URI; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class CurrentUserEndpointMerger extends AbstractSingleEntityEndpoint { + public static final Pattern CURRENT_USER_URI_PATTERN = Pattern.compile("/nifi-api/flow/current-user"); + + @Override + public boolean canHandle(URI uri, String method) { + return "GET".equalsIgnoreCase(method) && CURRENT_USER_URI_PATTERN.matcher(uri.getPath()).matches(); + } + + @Override + protected Class getEntityClass() { + return CurrentUserEntity.class; + } + + + @Override + protected void mergeResponses(final CurrentUserEntity clientEntity, final Map entityMap, + final Set successfulResponses, final Set problematicResponses) { + + for (final Map.Entry entry : entityMap.entrySet()) { + final CurrentUserEntity entity = entry.getValue(); + if (entity != clientEntity) { + mergePermissions(clientEntity.getControllerPermissions(), entity.getControllerPermissions()); + mergePermissions(clientEntity.getCountersPermissions(), entity.getCountersPermissions()); + mergePermissions(clientEntity.getPoliciesPermissions(), entity.getPoliciesPermissions()); + mergePermissions(clientEntity.getProvenancePermissions(), entity.getProvenancePermissions()); + mergePermissions(clientEntity.getTenantsPermissions(), entity.getTenantsPermissions()); + } + } + } + + private void mergePermissions(PermissionsDTO clientPermissions, PermissionsDTO permissions) { + clientPermissions.setCanRead(clientPermissions.getCanRead() && permissions.getCanRead()); + clientPermissions.setCanWrite(clientPermissions.getCanWrite() && permissions.getCanWrite()); + } + +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowConfigurationEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowConfigurationEndpointMerger.java new file mode 100644 index 000000000000..22fa68411d05 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/FlowConfigurationEndpointMerger.java @@ -0,0 +1,58 @@ +/* + * 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.cluster.coordination.http.endpoints; + +import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.web.api.dto.FlowConfigurationDTO; +import org.apache.nifi.web.api.entity.FlowConfigurationEntity; + +import java.net.URI; +import java.util.Map; +import java.util.regex.Pattern; + +public class FlowConfigurationEndpointMerger extends AbstractNodeStatusEndpoint { + public static final Pattern FLOW_CONFIGURATION_URI_PATTERN = Pattern.compile("/nifi-api/flow/config"); + + @Override + public boolean canHandle(URI uri, String method) { + return "GET".equalsIgnoreCase(method) && FLOW_CONFIGURATION_URI_PATTERN.matcher(uri.getPath()).matches(); + } + + @Override + protected Class getEntityClass() { + return FlowConfigurationEntity.class; + } + + @Override + protected FlowConfigurationDTO getDto(FlowConfigurationEntity entity) { + return entity.getFlowConfiguration(); + } + + @Override + protected void mergeResponses(FlowConfigurationDTO clientDto, Map dtoMap, NodeIdentifier selectedNodeId) { + + for (final Map.Entry entry : dtoMap.entrySet()) { + final NodeIdentifier nodeId = entry.getKey(); + final FlowConfigurationDTO toMerge = entry.getValue(); + if (toMerge != clientDto) { + clientDto.setSupportsConfigurableAuthorizer(clientDto.getSupportsConfigurableAuthorizer() && toMerge.getSupportsConfigurableAuthorizer()); + } + } + } + +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java index 8a03dbf45687..54f98f14cd0e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessPolicyResource.java @@ -23,6 +23,7 @@ import com.wordnik.swagger.annotations.ApiResponses; import com.wordnik.swagger.annotations.Authorization; import org.apache.commons.lang3.StringUtils; +import org.apache.nifi.authorization.AbstractPolicyBasedAuthorizer; import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.resource.Authorizable; @@ -37,6 +38,7 @@ import org.apache.nifi.web.api.entity.AccessPolicyEntity; import org.apache.nifi.web.api.request.ClientIdParameter; import org.apache.nifi.web.api.request.LongParameter; +import org.apache.nifi.web.dao.AccessPolicyDAO; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -130,6 +132,11 @@ public Response getAccessPolicyForResource( required = true ) @PathParam("resource") String rawResource) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + // parse the action and resource type final RequestAction requestAction = RequestAction.valueOfValue(action); final String resource = "/" + rawResource; @@ -189,6 +196,11 @@ public Response createAccessPolicy( required = true ) final AccessPolicyEntity accessPolicyEntity) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (accessPolicyEntity == null || accessPolicyEntity.getComponent() == null) { throw new IllegalArgumentException("Access policy details must be specified."); } @@ -277,6 +289,11 @@ public Response getAccessPolicy( ) @PathParam("id") final String id) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (isReplicateRequest()) { return replicate(HttpMethod.GET); } @@ -335,6 +352,11 @@ public Response updateAccessPolicy( required = true ) final AccessPolicyEntity accessPolicyEntity) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (accessPolicyEntity == null || accessPolicyEntity.getComponent() == null) { throw new IllegalArgumentException("Access policy details must be specified."); } @@ -425,6 +447,11 @@ public Response removeAccessPolicy( ) @PathParam("id") final String id) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (isReplicateRequest()) { return replicate(HttpMethod.DELETE); } 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 f9c67085c380..96e7dbcdbaf2 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 @@ -300,6 +300,10 @@ public Response getFlowConfig() { authorizeFlow(); + if (isReplicateRequest()) { + return replicate(HttpMethod.GET); + } + final FlowConfigurationEntity entity = serviceFacade.getFlowConfiguration(); return clusterContext(generateOkResponse(entity)).build(); } @@ -321,6 +325,10 @@ public Response getCurrentUser() { authorizeFlow(); + if (isReplicateRequest()) { + return replicate(HttpMethod.GET); + } + // note that the cluster manager will handle this request directly final NiFiUser user = NiFiUserUtils.getNiFiUser(); if (user == null) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java index 860bf7f7cd4f..b944bf7a3389 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/TenantsResource.java @@ -23,6 +23,7 @@ import com.wordnik.swagger.annotations.ApiResponses; import com.wordnik.swagger.annotations.Authorization; import org.apache.commons.lang3.StringUtils; +import org.apache.nifi.authorization.AbstractPolicyBasedAuthorizer; import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.resource.Authorizable; @@ -45,6 +46,7 @@ import org.apache.nifi.web.api.entity.UsersEntity; import org.apache.nifi.web.api.request.ClientIdParameter; import org.apache.nifi.web.api.request.LongParameter; +import org.apache.nifi.web.dao.AccessPolicyDAO; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -105,7 +107,7 @@ public Set populateRemainingUserEntitiesContent(Set user * @return userEntity */ public UserEntity populateRemainingUserEntityContent(UserEntity userEntity) { - userEntity.setUri(generateResourceUri("tenants/users", userEntity.getId())); + userEntity.setUri(generateResourceUri("tenants", "users", userEntity.getId())); return userEntity; } @@ -144,6 +146,11 @@ public Response createUser( required = true ) final UserEntity userEntity) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (userEntity == null || userEntity.getComponent() == null) { throw new IllegalArgumentException("User details must be specified."); } @@ -224,6 +231,11 @@ public Response getUser( ) @PathParam("id") final String id) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (isReplicateRequest()) { return replicate(HttpMethod.GET); } @@ -271,6 +283,11 @@ public Response getUser( ) public Response getUsers() { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (isReplicateRequest()) { return replicate(HttpMethod.GET); } @@ -334,6 +351,11 @@ public Response updateUser( required = true ) final UserEntity userEntity) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (userEntity == null || userEntity.getComponent() == null) { throw new IllegalArgumentException("User details must be specified."); } @@ -424,6 +446,11 @@ public Response removeUser( ) @PathParam("id") final String id) { + // ensure we're running with a configurable authorizer + if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) { + throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER); + } + if (isReplicateRequest()) { return replicate(HttpMethod.DELETE); } @@ -466,7 +493,7 @@ public Set populateRemainingUserGroupEntitiesContent(SetFlow Configuration History - - + + + ng-class="{disabled: !(appCtrl.nf.Common.canAccessTenants())}"> Users - + diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp index 3e719e97a3b8..7babfa0ec81c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp @@ -99,8 +99,8 @@ ng-disabled="!(appCtrl.serviceProvider.graphControlsCtrl.canConfigureOrOpenDetails())">
-
 
-
+
 
+
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 919f4c0c73bf..6259c4f4b964 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 @@ -133,7 +133,7 @@ div.policy-selected-component-name { color: #262626; width: 300px; text-overflow: ellipsis; - overflow-x: hidden; + overflow: hidden; white-space: nowrap; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js index 6f54962c7c4d..54d5845aa8f0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js @@ -118,6 +118,7 @@ nf.Canvas = (function () { var parentGroupId = null; var clustered = false; var connectedToCluster = false; + var configurableAuthorizer = false; var svg = null; var canvas = null; @@ -884,6 +885,9 @@ nf.Canvas = (function () { // get the auto refresh interval var autoRefreshIntervalSeconds = parseInt(configDetails.autoRefreshIntervalSeconds, 10); + // record whether we can configure the authorizer + configurableAuthorizer = configDetails.supportsConfigurableAuthorizer; + // init storage nf.Storage.init(); @@ -1008,6 +1012,13 @@ nf.Canvas = (function () { return parentGroupId; }, + /** + * Returns whether the authorizer is configurable. + */ + isConfigurableAuthorizer: function () { + return configurableAuthorizer; + }, + /** * Whether the current user can write in this group. * 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 e77ab19931ee..fc0051743f4a 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 @@ -605,8 +605,10 @@ nf.ControllerServices = (function () { } } - // TODO - only if we can adminster policies - markup += '
'; + // allow policy configuration conditionally + if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) { + markup += '
'; + } return markup; }; 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 74f1ea614808..5456a02ab25e 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 @@ -682,8 +682,10 @@ nf.Settings = (function () { } } - // TODO - only if we can adminster policies - markup += '
'; + // allow policy configuration conditionally + if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) { + markup += '
'; + } return markup; }; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates-table.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates-table.js index 272a1fe6c9c5..6afba5e0d9be 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates-table.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/templates/nf-templates-table.js @@ -283,10 +283,11 @@ nf.TemplatesTable = (function () { markup += '
'; } - // if we in the shell - // TODO - only if we can adminster policies - if (top !== window) { - markup += '
'; + // allow policy configuration conditionally + if (top !== window && nf.Common.canAccessTenants()) { + if (nf.Common.isDefinedAndNotNull(parent.nf) && nf.Common.isDefinedAndNotNull(parent.nf.Canvas) && parent.nf.Canvas.isConfigurableAuthorizer()) { + markup += '
'; + } } return markup;