mirror of https://github.com/apache/nifi.git
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.
This closes #736 Signed-off-by: jpercivall <joepercivall@yahoo.com>
This commit is contained in:
parent
5e4ba04589
commit
da238b16ef
|
@ -29,6 +29,7 @@ import java.util.Date;
|
|||
@XmlType(name = "flowConfiguration")
|
||||
public class FlowConfigurationDTO {
|
||||
|
||||
private Boolean supportsConfigurableAuthorizer;
|
||||
private Long autoRefreshIntervalSeconds;
|
||||
|
||||
private Date currentTime;
|
||||
|
@ -49,6 +50,21 @@ public class FlowConfigurationDTO {
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -28,7 +28,9 @@ import org.apache.nifi.cluster.coordination.http.endpoints.ControllerServiceRefe
|
|||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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<CurrentUserEntity> {
|
||||
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<CurrentUserEntity> getEntityClass() {
|
||||
return CurrentUserEntity.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void mergeResponses(final CurrentUserEntity clientEntity, final Map<NodeIdentifier, CurrentUserEntity> entityMap,
|
||||
final Set<NodeResponse> successfulResponses, final Set<NodeResponse> problematicResponses) {
|
||||
|
||||
for (final Map.Entry<NodeIdentifier, CurrentUserEntity> 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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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<FlowConfigurationEntity, FlowConfigurationDTO> {
|
||||
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<FlowConfigurationEntity> getEntityClass() {
|
||||
return FlowConfigurationEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FlowConfigurationDTO getDto(FlowConfigurationEntity entity) {
|
||||
return entity.getFlowConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mergeResponses(FlowConfigurationDTO clientDto, Map<NodeIdentifier, FlowConfigurationDTO> dtoMap, NodeIdentifier selectedNodeId) {
|
||||
|
||||
for (final Map.Entry<NodeIdentifier, FlowConfigurationDTO> entry : dtoMap.entrySet()) {
|
||||
final NodeIdentifier nodeId = entry.getKey();
|
||||
final FlowConfigurationDTO toMerge = entry.getValue();
|
||||
if (toMerge != clientDto) {
|
||||
clientDto.setSupportsConfigurableAuthorizer(clientDto.getSupportsConfigurableAuthorizer() && toMerge.getSupportsConfigurableAuthorizer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,7 @@ import com.wordnik.swagger.annotations.ApiResponse;
|
|||
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.dto.RevisionDTO;
|
|||
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 class AccessPolicyResource extends ApplicationResource {
|
|||
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 class AccessPolicyResource extends ApplicationResource {
|
|||
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 class AccessPolicyResource extends ApplicationResource {
|
|||
)
|
||||
@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 class AccessPolicyResource extends ApplicationResource {
|
|||
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 class AccessPolicyResource extends ApplicationResource {
|
|||
)
|
||||
@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);
|
||||
}
|
||||
|
|
|
@ -300,6 +300,10 @@ public class FlowResource extends ApplicationResource {
|
|||
|
||||
authorizeFlow();
|
||||
|
||||
if (isReplicateRequest()) {
|
||||
return replicate(HttpMethod.GET);
|
||||
}
|
||||
|
||||
final FlowConfigurationEntity entity = serviceFacade.getFlowConfiguration();
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
@ -321,6 +325,10 @@ public class FlowResource extends ApplicationResource {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.wordnik.swagger.annotations.ApiResponse;
|
|||
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.UserGroupsEntity;
|
|||
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 class TenantsResource extends ApplicationResource {
|
|||
* @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 class TenantsResource extends ApplicationResource {
|
|||
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 class TenantsResource extends ApplicationResource {
|
|||
)
|
||||
@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 class TenantsResource extends ApplicationResource {
|
|||
)
|
||||
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 class TenantsResource extends ApplicationResource {
|
|||
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 class TenantsResource extends ApplicationResource {
|
|||
)
|
||||
@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 class TenantsResource extends ApplicationResource {
|
|||
* @return userGroupEntity
|
||||
*/
|
||||
public UserGroupEntity populateRemainingUserGroupEntityContent(UserGroupEntity userGroupEntity) {
|
||||
userGroupEntity.setUri(generateResourceUri("tenants/user-groups", userGroupEntity.getId()));
|
||||
userGroupEntity.setUri(generateResourceUri("tenants", "user-groups", userGroupEntity.getId()));
|
||||
return userGroupEntity;
|
||||
}
|
||||
|
||||
|
@ -505,6 +532,11 @@ public class TenantsResource extends ApplicationResource {
|
|||
required = true
|
||||
) final UserGroupEntity userGroupEntity) {
|
||||
|
||||
// ensure we're running with a configurable authorizer
|
||||
if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) {
|
||||
throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
if (userGroupEntity == null || userGroupEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("User group details must be specified.");
|
||||
}
|
||||
|
@ -585,6 +617,11 @@ public class TenantsResource extends ApplicationResource {
|
|||
)
|
||||
@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);
|
||||
}
|
||||
|
@ -632,6 +669,11 @@ public class TenantsResource extends ApplicationResource {
|
|||
)
|
||||
public Response getUserGroups() {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -694,6 +736,11 @@ public class TenantsResource extends ApplicationResource {
|
|||
required = true
|
||||
) final UserGroupEntity userGroupEntity) {
|
||||
|
||||
// ensure we're running with a configurable authorizer
|
||||
if (!(authorizer instanceof AbstractPolicyBasedAuthorizer)) {
|
||||
throw new IllegalStateException(AccessPolicyDAO.MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER);
|
||||
}
|
||||
|
||||
if (userGroupEntity == null || userGroupEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("User group details must be specified.");
|
||||
}
|
||||
|
@ -784,6 +831,11 @@ public class TenantsResource extends ApplicationResource {
|
|||
)
|
||||
@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);
|
||||
}
|
||||
|
@ -846,6 +898,11 @@ public class TenantsResource extends ApplicationResource {
|
|||
)
|
||||
@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.nifi.action.details.PurgeDetails;
|
|||
import org.apache.nifi.annotation.behavior.Stateful;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.Tags;
|
||||
import org.apache.nifi.authorization.AbstractPolicyBasedAuthorizer;
|
||||
import org.apache.nifi.authorization.AccessPolicy;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.authorization.Group;
|
||||
|
@ -199,6 +200,7 @@ public final class DtoFactory {
|
|||
// get the refresh interval
|
||||
final long refreshInterval = FormatUtils.getTimeDuration(autoRefreshInterval, TimeUnit.SECONDS);
|
||||
dto.setAutoRefreshIntervalSeconds(refreshInterval);
|
||||
dto.setSupportsConfigurableAuthorizer(authorizer instanceof AbstractPolicyBasedAuthorizer);
|
||||
|
||||
final Date now = new Date();
|
||||
dto.setTimeOffset(TimeZone.getDefault().getOffset(now.getTime()));
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.apache.nifi.web.api.dto.AccessPolicyDTO;
|
|||
|
||||
public interface AccessPolicyDAO {
|
||||
|
||||
String MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER = "This NiFi is not configured to internally manage users, groups, and policies. Please contact your system administrator.";
|
||||
|
||||
/**
|
||||
* Whether or not NiFi supports a configurable authorizer.
|
||||
*
|
||||
|
|
|
@ -44,7 +44,6 @@ import java.util.stream.Collectors;
|
|||
|
||||
public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGroupDAO, UserDAO {
|
||||
|
||||
static final String MSG_NON_ABSTRACT_POLICY_BASED_AUTHORIZER = "This NiFi is not configured to internally manage users, groups, and policies. Please contact your system administrator.";
|
||||
private final AbstractPolicyBasedAuthorizer authorizer;
|
||||
private final boolean supportsConfigurableAuthorizer;
|
||||
|
||||
|
|
|
@ -147,15 +147,15 @@
|
|||
<i class="fa fa-history"></i>Flow Configuration History
|
||||
</a>
|
||||
</md-menu-item>
|
||||
<md-menu-divider></md-menu-divider>
|
||||
<md-menu-item layout-align="space-around center">
|
||||
<md-menu-divider ng-if="appCtrl.nf.Canvas.isConfigurableAuthorizer()"></md-menu-divider>
|
||||
<md-menu-item layout-align="space-around center" ng-if="appCtrl.nf.Canvas.isConfigurableAuthorizer()">
|
||||
<a id="users-link" layout="row"
|
||||
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.users.shell.launch();"
|
||||
ng-class="{disabled: !appCtrl.nf.Common.canAccessTenants()}">
|
||||
ng-class="{disabled: !(appCtrl.nf.Common.canAccessTenants())}">
|
||||
<i class="fa fa-users"></i>Users
|
||||
</a>
|
||||
</md-menu-item>
|
||||
<md-menu-item layout-align="space-around center">
|
||||
<md-menu-item layout-align="space-around center" ng-if="appCtrl.nf.Canvas.isConfigurableAuthorizer()">
|
||||
<a id="policies-link" layout="row"
|
||||
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.policies.shell.launch();"
|
||||
ng-class="{disabled: !(appCtrl.nf.Common.canAccessTenants() && appCtrl.nf.Common.canModifyPolicies())}">
|
||||
|
|
|
@ -99,8 +99,8 @@
|
|||
ng-disabled="!(appCtrl.serviceProvider.graphControlsCtrl.canConfigureOrOpenDetails())">
|
||||
<div class="graph-control-action-icon fa fa-gear"></div></button>
|
||||
</div>
|
||||
<div class="button-spacer-small"> </div>
|
||||
<div id="operate-policy" class="action-button" title="Access Policies">
|
||||
<div class="button-spacer-small" ng-if="appCtrl.nf.Canvas.isConfigurableAuthorizer()"> </div>
|
||||
<div id="operate-policy" class="action-button" title="Access Policies" ng-if="appCtrl.nf.Canvas.isConfigurableAuthorizer()">
|
||||
<button ng-click="appCtrl.nf.Actions['managePolicies'](appCtrl.nf.CanvasUtils.getSelection());"
|
||||
ng-disabled="!(appCtrl.serviceProvider.graphControlsCtrl.canManagePolicies())">
|
||||
<div class="graph-control-action-icon fa fa-key"></div></button>
|
||||
|
|
|
@ -133,7 +133,7 @@ div.policy-selected-component-name {
|
|||
color: #262626;
|
||||
width: 300px;
|
||||
text-overflow: ellipsis;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -605,8 +605,10 @@ nf.ControllerServices = (function () {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO - only if we can adminster policies
|
||||
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
|
||||
// allow policy configuration conditionally
|
||||
if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) {
|
||||
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
|
||||
}
|
||||
|
||||
return markup;
|
||||
};
|
||||
|
|
|
@ -682,8 +682,10 @@ nf.Settings = (function () {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO - only if we can adminster policies
|
||||
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
|
||||
// allow policy configuration conditionally
|
||||
if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) {
|
||||
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
|
||||
}
|
||||
|
||||
return markup;
|
||||
};
|
||||
|
|
|
@ -283,10 +283,11 @@ nf.TemplatesTable = (function () {
|
|||
markup += '<div title="Remove Template" class="pointer prompt-to-delete-template fa fa-trash" style="margin-top: 2px; margin-right: 3px;"></div>';
|
||||
}
|
||||
|
||||
// if we in the shell
|
||||
// TODO - only if we can adminster policies
|
||||
if (top !== window) {
|
||||
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
|
||||
// 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 += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
|
||||
}
|
||||
}
|
||||
|
||||
return markup;
|
||||
|
|
Loading…
Reference in New Issue