NIFI-1901: - Building component based access control tests for Connections, Funnels, Labels, Input Ports, Output Ports, Processors, and Process Groups. - Restoring Access Token Endpoint tests.

This closes #518

Signed-off-by: Bryan Bende <bbende@apache.org>
This commit is contained in:
Matt Gilman 2016-06-13 15:39:44 -04:00 committed by Bryan Bende
parent c2b26eb311
commit fbd299e885
25 changed files with 3241 additions and 156 deletions

View File

@ -14,4 +14,4 @@ before_install:
- sed -e "s/^\\(127\\.0\\.0\\.1.*\\)/\\1 $(hostname | cut -c1-63)/" /etc/hosts | sudo tee /etc/hosts
- sed -i.bak -e 's|https://nexus.codehaus.org/snapshots/|https://oss.sonatype.org/content/repositories/codehaus-snapshots/|g' ~/.m2/settings.xml
script: mvn clean install -Pcontrib-check
script: mvn clean install -T4

View File

@ -508,7 +508,7 @@ public class NiFiProperties extends Properties {
/**
* @return the user authorizers file
*/
public File getAuthorizerConfiguraitonFile() {
public File getAuthorizerConfigurationFile() {
final String value = getProperty(AUTHORIZER_CONFIGURATION_FILE);
if (StringUtils.isBlank(value)) {
return new File(DEFAULT_AUTHORIZER_CONFIGURATION_FILE);
@ -520,7 +520,7 @@ public class NiFiProperties extends Properties {
/**
* @return the user authorities file
*/
public File getLoginIdentityProviderConfiguraitonFile() {
public File getLoginIdentityProviderConfigurationFile() {
final String value = getProperty(LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE);
if (StringUtils.isBlank(value)) {
return new File(DEFAULT_LOGIN_IDENTITY_PROVIDER_CONFIGURATION_FILE);

View File

@ -126,7 +126,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
}
private Authorizers loadAuthorizersConfiguration() throws Exception {
final File authorizersConfigurationFile = properties.getAuthorizerConfiguraitonFile();
final File authorizersConfigurationFile = properties.getAuthorizerConfigurationFile();
// load the authorizers from the specified file
if (authorizersConfigurationFile.exists()) {

View File

@ -31,7 +31,6 @@ public class ComponentEntity extends Entity {
private RevisionDTO revision;
private String id;
private String uri;
private PositionDTO position;
private AccessPolicyDTO accessPolicy;
@ -65,22 +64,6 @@ public class ComponentEntity extends Entity {
this.id = id;
}
/**
* The uri for linking to this component in this NiFi.
*
* @return The uri
*/
@ApiModelProperty(
value = "The URI for futures requests to the component."
)
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
/**
* The position of this component in the UI if applicable, null otherwise.
*

View File

@ -210,6 +210,11 @@
<artifactId>nifi-framework-authorization</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-authorizer</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>

View File

@ -16,8 +16,25 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.Set;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.FlowFileSummaryDTO;
import org.apache.nifi.web.api.dto.ListingRequestDTO;
import org.apache.nifi.web.api.entity.ConnectionEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
@ -33,27 +50,8 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.FlowFileSummaryDTO;
import org.apache.nifi.web.api.dto.ListingRequestDTO;
import org.apache.nifi.web.api.entity.ConnectionEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization;
import java.net.URI;
import java.util.Set;
/**
* RESTful endpoint for managing a Connection.
@ -286,7 +284,7 @@ public class ConnectionResource extends ApplicationResource {
// generate the response
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getUri()), entity)).build();
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}

View File

@ -16,30 +16,12 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
@ -66,12 +48,28 @@ import org.apache.nifi.web.api.request.LongParameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* RESTful endpoint for managing a Controller Service.
@ -369,14 +367,17 @@ public class ControllerServiceResource extends ApplicationResource {
return replicate(HttpMethod.POST);
}
// handle expects request (usually from the cluster manager)
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase) {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable controllerService = lookup.getControllerService(id);
controllerService.authorize(authorizer, RequestAction.WRITE);
});
}
// handle expects request (usually from the cluster manager)
if (validationPhase) {
serviceFacade.verifyCanClearControllerServiceState(id);
return generateContinueResponse().build();
}

View File

@ -16,8 +16,23 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.Set;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.FunnelDTO;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
@ -33,25 +48,8 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.FunnelDTO;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization;
import java.net.URI;
import java.util.Set;
/**
* RESTful endpoint for managing a Funnel.
@ -316,7 +314,7 @@ public class FunnelResource extends ApplicationResource {
revision,
lookup -> {
final Authorizable funnel = lookup.getFunnel(id);
funnel.authorize(authorizer, RequestAction.READ);
funnel.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyDeleteFunnel(id),
() -> {

View File

@ -16,27 +16,12 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
@ -57,12 +42,25 @@ import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.List;
import java.util.Set;
/**
* RESTful endpoint for managing a Processor.
@ -377,13 +375,17 @@ public class ProcessorResource extends ApplicationResource {
return replicate(HttpMethod.POST);
}
// handle expects request (usually from the cluster manager)
if (isValidationPhase(httpServletRequest)) {
final boolean isValidationPhase = isValidationPhase(httpServletRequest);
if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable processor = lookup.getProcessor(id);
processor.authorize(authorizer, RequestAction.WRITE);
});
}
// handle expects request (usually from the cluster manager)
if (isValidationPhase) {
serviceFacade.verifyCanClearProcessorState(id);
return generateContinueResponse().build();
}

View File

@ -355,13 +355,17 @@ public class ReportingTaskResource extends ApplicationResource {
return replicate(HttpMethod.POST);
}
// handle expects request (usually from the cluster manager)
if (isValidationPhase(httpServletRequest)) {
final boolean isValidationPhase = isValidationPhase(httpServletRequest);
if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable reportingTask = lookup.getReportingTask(id);
reportingTask.authorize(authorizer, RequestAction.WRITE);
});
}
// handle expects request (usually from the cluster manager)
if (isValidationPhase) {
serviceFacade.verifyCanClearReportingTaskState(id);
return generateContinueResponse().build();
}

View File

@ -20,18 +20,19 @@ import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.ClientResponse.Status;
import org.apache.nifi.connectable.ConnectableType;
import org.apache.nifi.integration.accesscontrol.DfmAccessControlTest;
import org.apache.nifi.integration.util.NiFiTestUser;
import org.apache.nifi.integration.util.SourceTestProcessor;
import org.apache.nifi.integration.util.TerminationTestProcessor;
import org.apache.nifi.web.api.dto.ConnectableDTO;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.FunnelDTO;
import org.apache.nifi.web.api.dto.LabelDTO;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.ProcessorDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.entity.ConnectionEntity;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
@ -48,11 +49,15 @@ import java.util.Set;
public class NiFiWebApiTest {
public static void populateFlow(Client client, String baseUrl, String clientId) throws Exception {
NiFiTestUser dfm = new NiFiTestUser(client, DfmAccessControlTest.DFM_USER_DN);
}
public static void populateFlow(Client client, String baseUrl, NiFiTestUser user, String clientId) throws Exception {
// -----------------------------------------------
// Create a local selection processor
// Create a source processor
// -----------------------------------------------
// create the local selection processor
ProcessorDTO processorDTO = new ProcessorDTO();
processorDTO.setName("Pick up");
@ -69,7 +74,7 @@ public class NiFiWebApiTest {
processorEntity.setComponent(processorDTO);
// add the processor
ClientResponse response = dfm.testPost(baseUrl + "/controller/process-groups/root/processors", processorEntity);
ClientResponse response = user.testPost(baseUrl + "/process-groups/root/processors", processorEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {
@ -87,6 +92,7 @@ public class NiFiWebApiTest {
// -----------------------------------------------
// Create a termination processor
// -----------------------------------------------
// create the termination processor
processorDTO = new ProcessorDTO();
processorDTO.setName("End");
@ -98,7 +104,7 @@ public class NiFiWebApiTest {
processorEntity.setComponent(processorDTO);
// add the processor
response = dfm.testPost(baseUrl + "/controller/process-groups/root/processors", processorEntity);
response = user.testPost(baseUrl + "/process-groups/root/processors", processorEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {
@ -116,6 +122,7 @@ public class NiFiWebApiTest {
// -----------------------------------------------
// Connect the two processors
// -----------------------------------------------
ConnectableDTO source = new ConnectableDTO();
source.setId(localSelectionId);
source.setType(ConnectableType.PROCESSOR.name());
@ -140,7 +147,7 @@ public class NiFiWebApiTest {
connectionEntity.setComponent(connectionDTO);
// add the processor
response = dfm.testPost(baseUrl + "/controller/process-groups/root/connections", connectionEntity);
response = user.testPost(baseUrl + "/process-groups/root/connections", connectionEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {
@ -153,6 +160,7 @@ public class NiFiWebApiTest {
// -----------------------------------------------
// Create a label
// -----------------------------------------------
// create the label
LabelDTO labelDTO = new LabelDTO();
labelDTO.setLabel("Test label");
@ -163,7 +171,30 @@ public class NiFiWebApiTest {
labelEntity.setComponent(labelDTO);
// add the label
response = dfm.testPost(baseUrl + "/controller/process-groups/root/labels", labelEntity);
response = user.testPost(baseUrl + "/process-groups/root/labels", labelEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {
// since it was unable to create the component attempt to extract an
// error message from the response body
final String responseEntity = response.getEntity(String.class);
throw new Exception("Unable to populate initial flow: " + responseEntity);
}
// -----------------------------------------------
// Create a funnel
// -----------------------------------------------
// create the funnel
FunnelDTO funnelDTO = new FunnelDTO();
// create the funnel entity
FunnelEntity funnelEntity = new FunnelEntity();
funnelEntity.setRevision(revision);
funnelEntity.setComponent(funnelDTO);
// add the funnel
response = user.testPost(baseUrl + "/process-groups/root/funnels", funnelEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {
@ -176,6 +207,7 @@ public class NiFiWebApiTest {
// -----------------------------------------------
// Create a process group
// -----------------------------------------------
// create the process group
ProcessGroupDTO processGroup = new ProcessGroupDTO();
processGroup.setName("group name");
@ -186,7 +218,7 @@ public class NiFiWebApiTest {
processGroupEntity.setComponent(processGroup);
// add the process group
response = dfm.testPost(baseUrl + "/controller/process-groups/root/process-group-references", processGroupEntity);
response = user.testPost(baseUrl + "/process-groups/root/process-groups", processGroupEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {
@ -199,6 +231,7 @@ public class NiFiWebApiTest {
// -----------------------------------------------
// Create an input port
// -----------------------------------------------
// create the input port
PortDTO inputPort = new PortDTO();
inputPort.setName("input");
@ -209,7 +242,7 @@ public class NiFiWebApiTest {
inputPortEntity.setComponent(inputPort);
// add the input port
response = dfm.testPost(baseUrl + "/controller/process-groups/root/input-ports", inputPortEntity);
response = user.testPost(baseUrl + "/process-groups/root/input-ports", inputPortEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {
@ -222,6 +255,7 @@ public class NiFiWebApiTest {
// -----------------------------------------------
// Create a output ports
// -----------------------------------------------
// create the process group
PortDTO outputPort = new PortDTO();
outputPort.setName("output");
@ -232,7 +266,7 @@ public class NiFiWebApiTest {
outputPortEntity.setComponent(outputPort);
// add the output port
response = dfm.testPost(baseUrl + "/controller/process-groups/root/output-ports", outputPortEntity);
response = user.testPost(baseUrl + "/process-groups/root/output-ports", outputPortEntity);
// ensure a successful response
if (Status.CREATED.getStatusCode() != response.getStatusInfo().getStatusCode()) {

View File

@ -0,0 +1,120 @@
/*
* 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.accesscontrol;
import org.apache.nifi.integration.NiFiWebApiTest;
import org.apache.nifi.integration.util.NiFiTestAuthorizer;
import org.apache.nifi.integration.util.NiFiTestServer;
import org.apache.nifi.integration.util.NiFiTestUser;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.nar.NarClassLoaders;
import org.apache.nifi.util.NiFiProperties;
import java.io.File;
/**
* Access control test for the dfm user.
*/
public class AccessControlHelper {
public static final String NONE_CLIENT_ID = "client-id";
public static final String READ_CLIENT_ID = "r-client-id";
public static final String WRITE_CLIENT_ID = "w-client-id";
public static final String READ_WRITE_CLIENT_ID = "rw-client-id";
private NiFiTestUser readUser;
private NiFiTestUser writeUser;
private NiFiTestUser readWriteUser;
private NiFiTestUser noneUser;
private static final String CONTEXT_PATH = "/nifi-api";
private String flowXmlPath;
private NiFiTestServer server;
private String baseUrl;
public AccessControlHelper(final String flowXmlPath) throws Exception {
this.flowXmlPath = flowXmlPath;
// look for the flow.xml and toss it
File flow = new File(flowXmlPath);
if (flow.exists()) {
flow.delete();
}
// configure the location of the nifi properties
File nifiPropertiesFile = new File("src/test/resources/access-control/nifi.properties");
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, nifiPropertiesFile.getAbsolutePath());
// update the flow.xml property
NiFiProperties props = NiFiProperties.getInstance();
props.setProperty(NiFiProperties.FLOW_CONFIGURATION_FILE, flowXmlPath);
// load extensions
NarClassLoaders.load(props);
ExtensionManager.discoverExtensions();
// start the server
server = new NiFiTestServer("src/main/webapp", CONTEXT_PATH);
server.startServer();
server.loadFlow();
// get the base url
baseUrl = server.getBaseUrl() + CONTEXT_PATH;
// create the users - user purposefully decoupled from clientId (same user different browsers tabs)
readUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.READ_USER_DN);
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);
// populate the initial data flow
NiFiWebApiTest.populateFlow(server.getClient(), baseUrl, readWriteUser, READ_WRITE_CLIENT_ID);
}
public NiFiTestUser getReadUser() {
return readUser;
}
public NiFiTestUser getWriteUser() {
return writeUser;
}
public NiFiTestUser getReadWriteUser() {
return readWriteUser;
}
public NiFiTestUser getNoneUser() {
return noneUser;
}
public String getBaseUrl() {
return baseUrl;
}
public void cleanup() throws Exception {
// shutdown the server
server.shutdownServer();
server = null;
// look for the flow.xml and toss it
File flow = new File(flowXmlPath);
if (flow.exists()) {
flow.delete();
}
}
}

View File

@ -37,7 +37,6 @@ import org.apache.nifi.web.util.WebUtils;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import javax.net.ssl.SSLContext;
@ -48,7 +47,6 @@ import java.util.Map;
/**
* Access token endpoint test.
*/
@Ignore
public class AccessTokenEndpointTest {
private static final String CLIENT_ID = "token-endpoint-id";
@ -147,7 +145,7 @@ public class AccessTokenEndpointTest {
}
private ProcessorDTO createProcessor(final String token) throws Exception {
String url = BASE_URL + "/controller/process-groups/root/processors";
String url = BASE_URL + "/process-groups/root/processors";
// authorization header
Map<String, String> headers = new HashMap<>();
@ -224,7 +222,6 @@ public class AccessTokenEndpointTest {
public void testRequestAccessUsingToken() throws Exception {
String accessStatusUrl = BASE_URL + "/access";
String accessTokenUrl = BASE_URL + "/access/token";
String registrationUrl = BASE_URL + "/controller/users";
ClientResponse response = TOKEN_USER.testGet(accessStatusUrl);

View File

@ -0,0 +1,427 @@
/*
* 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.accesscontrol;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.nifi.connectable.ConnectableType;
import org.apache.nifi.integration.util.NiFiTestAuthorizer;
import org.apache.nifi.integration.util.NiFiTestUser;
import org.apache.nifi.web.api.dto.ConnectableDTO;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.entity.ConnectionEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.apache.nifi.web.api.entity.ProcessorEntity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Access control test for connections.
*/
public class ConnectionAccessControlTest {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-connections.xml";
private static AccessControlHelper helper;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
}
/**
* Ensures the READ user can get a connection.
*
* @throws Exception ex
*/
@Test
public void testReadUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the READ WRITE user can get a connection.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the WRITE user can get a connection.
*
* @throws Exception ex
*/
@Test
public void testWriteUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the NONE user can get a connection.
*
* @throws Exception ex
*/
@Test
public void testNoneUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the READ user cannot put a connection.
*
* @throws Exception ex
*/
@Test
public void testReadUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
entity.getRevision().setClientId(READ_CLIENT_ID);
entity.getComponent().setName("Updated Name");
// perform the request
final ClientResponse response = updateConnection(helper.getReadUser(), entity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ_WRITE user can put a connection.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name";
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateConnection(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ConnectionEntity responseEntity = response.getEntity(ConnectionEntity.class);
// verify
assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the READ_WRITE user can put a connection.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutConnectionThroughInheritedPolicy() throws Exception {
final ConnectionEntity entity = createConnection(NiFiTestAuthorizer.NO_POLICY_COMPONENT_NAME);
final String updatedName = "Updated name";
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateConnection(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ConnectionEntity responseEntity = response.getEntity(ConnectionEntity.class);
// verify
assertEquals(AccessControlHelper.READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the WRITE user can put a connection.
*
* @throws Exception ex
*/
@Test
public void testWriteUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
// attempt to update the name
final ConnectionDTO requestDto = new ConnectionDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID);
final ConnectionEntity requestEntity = new ConnectionEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateConnection(helper.getWriteUser(), requestEntity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ConnectionEntity responseEntity = response.getEntity(ConnectionEntity.class);
// verify
assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
}
/**
* Ensures the NONE user cannot put a connection.
*
* @throws Exception ex
*/
@Test
public void testNoneUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
// attempt to update the name
final ConnectionDTO requestDto = new ConnectionDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID);
final ConnectionEntity requestEntity = new ConnectionEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateConnection(helper.getNoneUser(), requestEntity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ user cannot delete a connection.
*
* @throws Exception ex
*/
@Test
public void testReadUserDeleteConnection() throws Exception {
verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403);
}
/**
* Ensures the READ WRITE user can delete a connection.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserDeleteConnection() throws Exception {
verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200);
}
/**
* Ensures the WRITE user can delete a connection.
*
* @throws Exception ex
*/
@Test
public void testWriteUserDeleteConnection() throws Exception {
verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200);
}
/**
* Ensures the NONE user can delete a connection.
*
* @throws Exception ex
*/
@Test
public void testNoneUserDeleteConnection() throws Exception {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
private ConnectionEntity getRandomConnection(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
// get the connections
final ClientResponse response = user.testGet(url);
// ensure the response was successful
assertEquals(200, response.getStatus());
// unmarshal
final ProcessGroupFlowEntity flowEntity = response.getEntity(ProcessGroupFlowEntity.class);
final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow();
final Set<ConnectionEntity> connections = flowDto.getConnections();
// ensure the correct number of connection
assertFalse(connections.isEmpty());
// use the first connection as the target
Iterator<ConnectionEntity> connectionIter = connections.iterator();
assertTrue(connectionIter.hasNext());
return connectionIter.next();
}
private ClientResponse updateConnection(final NiFiTestUser user, final ConnectionEntity entity) throws Exception {
final String url = helper.getBaseUrl() + "/connections/" + entity.getId();
// perform the request
return user.testPut(url, entity);
}
private ConnectionEntity createConnection(final String name) throws Exception {
String url = helper.getBaseUrl() + "/process-groups/root/connections";
// get two processors
final ProcessorEntity one = ProcessorAccessControlTest.createProcessor(helper, "one");
final ProcessorEntity two = ProcessorAccessControlTest.createProcessor(helper, "two");
// create the source connectable
ConnectableDTO source = new ConnectableDTO();
source.setId(one.getId());
source.setType(ConnectableType.PROCESSOR.name());
// create the target connectable
ConnectableDTO target = new ConnectableDTO();
target.setId(two.getId());
target.setType(ConnectableType.PROCESSOR.name());
// create the relationships
Set<String> relationships = new HashSet<>();
relationships.add("success");
// create the connection
ConnectionDTO connection = new ConnectionDTO();
connection.setName(name);
connection.setSource(source);
connection.setDestination(target);
connection.setSelectedRelationships(relationships);
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(READ_WRITE_CLIENT_ID);
revision.setVersion(0L);
// create the entity body
ConnectionEntity entity = new ConnectionEntity();
entity.setRevision(revision);
entity.setComponent(connection);
// perform the request
ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
// ensure the request is successful
assertEquals(201, response.getStatus());
// get the entity body
entity = response.getEntity(ConnectionEntity.class);
// verify creation
connection = entity.getComponent();
assertEquals(name, connection.getName());
// get the connection
return entity;
}
private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception {
final ConnectionEntity entity = createConnection("Copy");
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request
ClientResponse response = user.testDelete(entity.getComponent().getUri(), queryParams);
// ensure the request is failed with a forbidden status code
assertEquals(responseCode, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

View File

@ -0,0 +1,361 @@
/*
* 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.accesscontrol;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.nifi.integration.util.NiFiTestUser;
import org.apache.nifi.web.api.dto.FunnelDTO;
import org.apache.nifi.web.api.dto.PositionDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Access control test for funnels.
*/
public class FunnelAccessControlTest {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-funnels.xml";
private static AccessControlHelper helper;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
}
/**
* Ensures the READ user can get a funnel.
*
* @throws Exception ex
*/
@Test
public void testReadUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the READ WRITE user can get a funnel.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the WRITE user can get a funnel.
*
* @throws Exception ex
*/
@Test
public void testWriteUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the NONE user can get a funnel.
*
* @throws Exception ex
*/
@Test
public void testNoneUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the READ user cannot put a funnel.
*
* @throws Exception ex
*/
@Test
public void testReadUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the position
entity.getRevision().setClientId(READ_CLIENT_ID);
entity.getComponent().setPosition(new PositionDTO(0.0, 10.0));
// perform the request
final ClientResponse response = updateFunnel(helper.getReadUser(), entity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ_WRITE user can put a funnel.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final double y = 15.0;
// attempt to update the position
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID);
entity.getComponent().setPosition(new PositionDTO(0.0, y));
// perform the request
final ClientResponse response = updateFunnel(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final FunnelEntity responseEntity = response.getEntity(FunnelEntity.class);
// verify
assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(y, responseEntity.getComponent().getPosition().getY().doubleValue(), 0);
}
/**
* Ensures the WRITE user can put a funnel.
*
* @throws Exception ex
*/
@Test
public void testWriteUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final double y = 15.0;
// attempt to update the position
final FunnelDTO requestDto = new FunnelDTO();
requestDto.setId(entity.getId());
requestDto.setPosition(new PositionDTO(0.0, y));
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID);
final FunnelEntity requestEntity = new FunnelEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateFunnel(helper.getWriteUser(), requestEntity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final FunnelEntity responseEntity = response.getEntity(FunnelEntity.class);
// verify
assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
}
/**
* Ensures the NONE user cannot put a funnel.
*
* @throws Exception ex
*/
@Test
public void testNoneUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
// attempt to update the position
final FunnelDTO requestDto = new FunnelDTO();
requestDto.setId(entity.getId());
requestDto.setPosition(new PositionDTO(0.0, 15.0));
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID);
final FunnelEntity requestEntity = new FunnelEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateFunnel(helper.getNoneUser(), requestEntity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ user cannot delete a funnel.
*
* @throws Exception ex
*/
@Test
public void testReadUserDeleteFunnel() throws Exception {
verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403);
}
/**
* Ensures the READ WRITE user can delete a funnel.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserDeleteFunnel() throws Exception {
verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200);
}
/**
* Ensures the WRITE user can delete a funnel.
*
* @throws Exception ex
*/
@Test
public void testWriteUserDeleteFunnel() throws Exception {
verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200);
}
/**
* Ensures the NONE user can delete a funnel.
*
* @throws Exception ex
*/
@Test
public void testNoneUserDeleteFunnel() throws Exception {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
private FunnelEntity getRandomFunnel(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
// get the flow
final ClientResponse response = user.testGet(url);
// ensure the response was successful
assertEquals(200, response.getStatus());
// unmarshal
final ProcessGroupFlowEntity flowEntity = response.getEntity(ProcessGroupFlowEntity.class);
final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow();
final Set<FunnelEntity> funnels = flowDto.getFunnels();
// ensure the correct number of funnels
assertFalse(funnels.isEmpty());
// use the first funnel as the target
Iterator<FunnelEntity> funnelIter = funnels.iterator();
assertTrue(funnelIter.hasNext());
return funnelIter.next();
}
private ClientResponse updateFunnel(final NiFiTestUser user, final FunnelEntity entity) throws Exception {
final String url = helper.getBaseUrl() + "/funnels/" + entity.getId();
// perform the request
return user.testPut(url, entity);
}
private FunnelEntity createFunnel() throws Exception {
String url = helper.getBaseUrl() + "/process-groups/root/funnels";
// create the funnel
FunnelDTO funnel = new FunnelDTO();
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(READ_WRITE_CLIENT_ID);
revision.setVersion(0L);
// create the entity body
FunnelEntity entity = new FunnelEntity();
entity.setRevision(revision);
entity.setComponent(funnel);
// perform the request
ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
// ensure the request is successful
assertEquals(201, response.getStatus());
// get the entity body
return response.getEntity(FunnelEntity.class);
}
private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception {
final FunnelEntity entity = createFunnel();
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request
ClientResponse response = user.testDelete(entity.getComponent().getUri(), queryParams);
// ensure the request is failed with a forbidden status code
assertEquals(responseCode, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

View File

@ -0,0 +1,405 @@
/*
* 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.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.web.api.dto.PortDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Access control test for input ports.
*/
public class InputPortAccessControlTest {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-input-ports.xml";
private static AccessControlHelper helper;
private static int count = 0;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
}
/**
* Ensures the READ user can get an input port.
*
* @throws Exception ex
*/
@Test
public void testReadUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the READ WRITE user can get an input port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the WRITE user can get an input port.
*
* @throws Exception ex
*/
@Test
public void testWriteUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the NONE user can get an input port.
*
* @throws Exception ex
*/
@Test
public void testNoneUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the READ user cannot put an input port.
*
* @throws Exception ex
*/
@Test
public void testReadUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
entity.getRevision().setClientId(READ_CLIENT_ID);
entity.getComponent().setName("Updated Name" + count++);
// perform the request
final ClientResponse response = updateInputPort(helper.getReadUser(), entity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ_WRITE user can put an input port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateInputPort(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final PortEntity responseEntity = response.getEntity(PortEntity.class);
// verify
assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the READ_WRITE user can put an input port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutInputPortThroughInheritedPolicy() throws Exception {
final PortEntity entity = createInputPort(NiFiTestAuthorizer.NO_POLICY_COMPONENT_NAME);
final String updatedName = "Updated name" + count++;
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateInputPort(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final PortEntity responseEntity = response.getEntity(PortEntity.class);
// verify
assertEquals(AccessControlHelper.READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the WRITE user can put an input port.
*
* @throws Exception ex
*/
@Test
public void testWriteUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final PortDTO requestDto = new PortDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID);
final PortEntity requestEntity = new PortEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateInputPort(helper.getWriteUser(), requestEntity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final PortEntity responseEntity = response.getEntity(PortEntity.class);
// verify
assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
}
/**
* Ensures the NONE user cannot put an input port.
*
* @throws Exception ex
*/
@Test
public void testNoneUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final PortDTO requestDto = new PortDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID);
final PortEntity requestEntity = new PortEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateInputPort(helper.getNoneUser(), requestEntity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ user cannot delete an input port.
*
* @throws Exception ex
*/
@Test
public void testReadUserDeleteInputPort() throws Exception {
verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403);
}
/**
* Ensures the READ WRITE user can delete an input port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserDeleteInputPort() throws Exception {
verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200);
}
/**
* Ensures the WRITE user can delete an input port.
*
* @throws Exception ex
*/
@Test
public void testWriteUserDeleteInputPort() throws Exception {
verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200);
}
/**
* Ensures the NONE user can delete an input port.
*
* @throws Exception ex
*/
@Test
public void testNoneUserDeleteInputPort() throws Exception {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
private PortEntity getRandomInputPort(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
// get the input ports
final ClientResponse response = user.testGet(url);
// ensure the response was successful
assertEquals(200, response.getStatus());
// unmarshal
final ProcessGroupFlowEntity flowEntity = response.getEntity(ProcessGroupFlowEntity.class);
final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow();
final Set<PortEntity> inputPorts = flowDto.getInputPorts();
// ensure the correct number of input ports
assertFalse(inputPorts.isEmpty());
// use the first input port as the target
Iterator<PortEntity> inputPortIter = inputPorts.iterator();
assertTrue(inputPortIter.hasNext());
return inputPortIter.next();
}
private ClientResponse updateInputPort(final NiFiTestUser user, final PortEntity entity) throws Exception {
final String url = helper.getBaseUrl() + "/input-ports/" + entity.getId();
// perform the request
return user.testPut(url, entity);
}
private PortEntity createInputPort(final String name) throws Exception {
String url = helper.getBaseUrl() + "/process-groups/root/input-ports";
final String updatedName = name + count++;
// create the input port
PortDTO inputPort = new PortDTO();
inputPort.setName(updatedName);
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(READ_WRITE_CLIENT_ID);
revision.setVersion(0L);
// create the entity body
PortEntity entity = new PortEntity();
entity.setRevision(revision);
entity.setComponent(inputPort);
// perform the request
ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
// ensure the request is successful
assertEquals(201, response.getStatus());
// get the entity body
entity = response.getEntity(PortEntity.class);
// verify creation
inputPort = entity.getComponent();
assertEquals(updatedName, inputPort.getName());
// get the input port
return entity;
}
private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception {
final PortEntity entity = createInputPort("Copy");
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request
ClientResponse response = user.testDelete(entity.getComponent().getUri(), queryParams);
// ensure the request is failed with a forbidden status code
assertEquals(responseCode, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

View File

@ -0,0 +1,402 @@
/*
* 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.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.web.api.dto.LabelDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Access control test for labels.
*/
public class LabelAccessControlTest {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-labels.xml";
private static AccessControlHelper helper;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
}
/**
* Ensures the READ user can get a label.
*
* @throws Exception ex
*/
@Test
public void testReadUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the READ WRITE user can get a label.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the WRITE user can get a label.
*
* @throws Exception ex
*/
@Test
public void testWriteUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the NONE user can get a label.
*
* @throws Exception ex
*/
@Test
public void testNoneUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the READ user cannot put a label.
*
* @throws Exception ex
*/
@Test
public void testReadUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
entity.getRevision().setClientId(READ_CLIENT_ID);
entity.getComponent().setLabel("Updated Label");
// perform the request
final ClientResponse response = updateLabel(helper.getReadUser(), entity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ_WRITE user can put a label.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedLabel = "Updated Name";
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID);
entity.getComponent().setLabel(updatedLabel);
// perform the request
final ClientResponse response = updateLabel(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final LabelEntity responseEntity = response.getEntity(LabelEntity.class);
// verify
assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedLabel, responseEntity.getComponent().getLabel());
}
/**
* Ensures the READ_WRITE user can put a label.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutLabelThroughInheritedPolicy() throws Exception {
final LabelEntity entity = createLabel(NiFiTestAuthorizer.NO_POLICY_COMPONENT_NAME);
final String updatedLabel = "Updated name";
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(READ_WRITE_CLIENT_ID);
entity.getComponent().setLabel(updatedLabel);
// perform the request
final ClientResponse response = updateLabel(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final LabelEntity responseEntity = response.getEntity(LabelEntity.class);
// verify
assertEquals(AccessControlHelper.READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedLabel, responseEntity.getComponent().getLabel());
}
/**
* Ensures the WRITE user can put a label.
*
* @throws Exception ex
*/
@Test
public void testWriteUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedLabel = "Updated Name";
// attempt to update the label
final LabelDTO requestDto = new LabelDTO();
requestDto.setId(entity.getId());
requestDto.setLabel(updatedLabel);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID);
final LabelEntity requestEntity = new LabelEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateLabel(helper.getWriteUser(), requestEntity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final LabelEntity responseEntity = response.getEntity(LabelEntity.class);
// verify
assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
}
/**
* Ensures the NONE user cannot put a label.
*
* @throws Exception ex
*/
@Test
public void testNoneUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
// attempt to update the name
final LabelDTO requestDto = new LabelDTO();
requestDto.setId(entity.getId());
requestDto.setLabel(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID);
final LabelEntity requestEntity = new LabelEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateLabel(helper.getNoneUser(), requestEntity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ user cannot delete a label.
*
* @throws Exception ex
*/
@Test
public void testReadUserDeleteLabel() throws Exception {
verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403);
}
/**
* Ensures the READ WRITE user can delete a label.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserDeleteLabel() throws Exception {
verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200);
}
/**
* Ensures the WRITE user can delete a label.
*
* @throws Exception ex
*/
@Test
public void testWriteUserDeleteLabel() throws Exception {
verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200);
}
/**
* Ensures the NONE user can delete a label.
*
* @throws Exception ex
*/
@Test
public void testNoneUserDeleteLabel() throws Exception {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
private LabelEntity getRandomLabel(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
// get the labels
final ClientResponse response = user.testGet(url);
// ensure the response was successful
assertEquals(200, response.getStatus());
// unmarshal
final ProcessGroupFlowEntity flowEntity = response.getEntity(ProcessGroupFlowEntity.class);
final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow();
final Set<LabelEntity> labels = flowDto.getLabels();
// ensure the correct number of labels
assertFalse(labels.isEmpty());
// use the first label as the target
Iterator<LabelEntity> labelIter = labels.iterator();
assertTrue(labelIter.hasNext());
return labelIter.next();
}
private ClientResponse updateLabel(final NiFiTestUser user, final LabelEntity entity) throws Exception {
final String url = helper.getBaseUrl() + "/labels/" + entity.getId();
// perform the request
return user.testPut(url, entity);
}
private LabelEntity createLabel(final String name) throws Exception {
String url = helper.getBaseUrl() + "/process-groups/root/labels";
// create the label
LabelDTO label = new LabelDTO();
label.setLabel(name);
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(READ_WRITE_CLIENT_ID);
revision.setVersion(0L);
// create the entity body
LabelEntity entity = new LabelEntity();
entity.setRevision(revision);
entity.setComponent(label);
// perform the request
ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
// ensure the request is successful
assertEquals(201, response.getStatus());
// get the entity body
entity = response.getEntity(LabelEntity.class);
// verify creation
label = entity.getComponent();
assertEquals(name, label.getLabel());
// get the label id
return entity;
}
private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception {
final LabelEntity entity = createLabel("Copy");
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request
ClientResponse response = user.testDelete(entity.getComponent().getUri(), queryParams);
// ensure the request is failed with a forbidden status code
assertEquals(responseCode, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

View File

@ -0,0 +1,405 @@
/*
* 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.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.web.api.dto.PortDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Access control test for output ports.
*/
public class OutputPortAccessControlTest {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-output-ports.xml";
private static AccessControlHelper helper;
private static int count = 0;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
}
/**
* Ensures the READ user can get an output port.
*
* @throws Exception ex
*/
@Test
public void testReadUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the READ WRITE user can get an output port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the WRITE user can get an output port.
*
* @throws Exception ex
*/
@Test
public void testWriteUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the NONE user can get an output port.
*
* @throws Exception ex
*/
@Test
public void testNoneUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the READ user cannot put an output port.
*
* @throws Exception ex
*/
@Test
public void testReadUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
entity.getRevision().setClientId(READ_CLIENT_ID);
entity.getComponent().setName("Updated Name" + count++);
// perform the request
final ClientResponse response = updateOutputPort(helper.getReadUser(), entity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ_WRITE user can put an output port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateOutputPort(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final PortEntity responseEntity = response.getEntity(PortEntity.class);
// verify
assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the READ_WRITE user can put an output port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutOutputPortThroughInheritedPolicy() throws Exception {
final PortEntity entity = createOutputPort(NiFiTestAuthorizer.NO_POLICY_COMPONENT_NAME);
final String updatedName = "Updated name" + count++;
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateOutputPort(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final PortEntity responseEntity = response.getEntity(PortEntity.class);
// verify
assertEquals(AccessControlHelper.READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the WRITE user can put an output port.
*
* @throws Exception ex
*/
@Test
public void testWriteUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final PortDTO requestDto = new PortDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID);
final PortEntity requestEntity = new PortEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateOutputPort(helper.getWriteUser(), requestEntity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final PortEntity responseEntity = response.getEntity(PortEntity.class);
// verify
assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
}
/**
* Ensures the NONE user cannot put an output port.
*
* @throws Exception ex
*/
@Test
public void testNoneUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final PortDTO requestDto = new PortDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID);
final PortEntity requestEntity = new PortEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateOutputPort(helper.getNoneUser(), requestEntity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ user cannot delete an output port.
*
* @throws Exception ex
*/
@Test
public void testReadUserDeleteOutputPort() throws Exception {
verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403);
}
/**
* Ensures the READ WRITE user can delete an output port.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserDeleteOutputPort() throws Exception {
verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200);
}
/**
* Ensures the WRITE user can delete an Output port.
*
* @throws Exception ex
*/
@Test
public void testWriteUserDeleteOutputPort() throws Exception {
verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200);
}
/**
* Ensures the NONE user can delete an Output port.
*
* @throws Exception ex
*/
@Test
public void testNoneUserDeleteOutputPort() throws Exception {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
private PortEntity getRandomOutputPort(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
// get the output ports
final ClientResponse response = user.testGet(url);
// ensure the response was successful
assertEquals(200, response.getStatus());
// unmarshal
final ProcessGroupFlowEntity flowEntity = response.getEntity(ProcessGroupFlowEntity.class);
final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow();
final Set<PortEntity> outputPorts = flowDto.getOutputPorts();
// ensure the correct number of output ports
assertFalse(outputPorts.isEmpty());
// use the first output port as the target
Iterator<PortEntity> outputPortIter = outputPorts.iterator();
assertTrue(outputPortIter.hasNext());
return outputPortIter.next();
}
private ClientResponse updateOutputPort(final NiFiTestUser user, final PortEntity entity) throws Exception {
final String url = helper.getBaseUrl() + "/output-ports/" + entity.getId();
// perform the request
return user.testPut(url, entity);
}
private PortEntity createOutputPort(final String name) throws Exception {
String url = helper.getBaseUrl() + "/process-groups/root/output-ports";
final String updatedName = name + count++;
// create the output port
PortDTO outputPort = new PortDTO();
outputPort.setName(updatedName);
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(READ_WRITE_CLIENT_ID);
revision.setVersion(0L);
// create the entity body
PortEntity entity = new PortEntity();
entity.setRevision(revision);
entity.setComponent(outputPort);
// perform the request
ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
// ensure the request is successful
assertEquals(201, response.getStatus());
// get the entity body
entity = response.getEntity(PortEntity.class);
// verify creation
outputPort = entity.getComponent();
assertEquals(updatedName, outputPort.getName());
// get the output port
return entity;
}
private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception {
final PortEntity entity = createOutputPort("Copy");
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request
ClientResponse response = user.testDelete(entity.getComponent().getUri(), queryParams);
// ensure the request is failed with a forbidden status code
assertEquals(responseCode, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

View File

@ -0,0 +1,405 @@
/*
* 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.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.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Access control test for process groups.
*/
public class ProcessGroupAccessControlTest {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-processors.xml";
private static AccessControlHelper helper;
private static int count = 0;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
}
/**
* Ensures the READ user can get a process group.
*
* @throws Exception ex
*/
@Test
public void testReadUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the READ WRITE user can get a process group.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the WRITE user can get a process group.
*
* @throws Exception ex
*/
@Test
public void testWriteUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the NONE user can get a process group.
*
* @throws Exception ex
*/
@Test
public void testNoneUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the READ user cannot put a processor.
*
* @throws Exception ex
*/
@Test
public void testReadUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
entity.getRevision().setClientId(READ_CLIENT_ID);
entity.getComponent().setName("Updated Name" + count++);
// perform the request
final ClientResponse response = updateProcessGroup(helper.getReadUser(), entity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ_WRITE user can put a process group.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateProcessGroup(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ProcessGroupEntity responseEntity = response.getEntity(ProcessGroupEntity.class);
// verify
assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the READ_WRITE user can put a process grup.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutProcessGroupThroughInheritedPolicy() throws Exception {
final ProcessGroupEntity entity = createProcessGroup(NiFiTestAuthorizer.NO_POLICY_COMPONENT_NAME);
final String updatedName = "Updated name" + count++;
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateProcessGroup(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ProcessGroupEntity responseEntity = response.getEntity(ProcessGroupEntity.class);
// verify
assertEquals(AccessControlHelper.READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the WRITE user can put a process group.
*
* @throws Exception ex
*/
@Test
public void testWriteUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final ProcessGroupDTO requestDto = new ProcessGroupDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID);
final ProcessGroupEntity requestEntity = new ProcessGroupEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateProcessGroup(helper.getWriteUser(), requestEntity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ProcessGroupEntity responseEntity = response.getEntity(ProcessGroupEntity.class);
// verify
assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
}
/**
* Ensures the NONE user cannot put a process group.
*
* @throws Exception ex
*/
@Test
public void testNoneUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
// attempt to update the name
final ProcessGroupDTO requestDto = new ProcessGroupDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID);
final ProcessGroupEntity requestEntity = new ProcessGroupEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateProcessGroup(helper.getNoneUser(), requestEntity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ user cannot delete a process group.
*
* @throws Exception ex
*/
@Test
public void testReadUserDeleteProcessGroup() throws Exception {
verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403);
}
/**
* Ensures the READ WRITE user can delete a process group.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserDeleteProcessGroup() throws Exception {
verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200);
}
/**
* Ensures the WRITE user can delete a process group.
*
* @throws Exception ex
*/
@Test
public void testWriteUserDeleteProcessGroup() throws Exception {
verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200);
}
/**
* Ensures the NONE user can delete a process group.
*
* @throws Exception ex
*/
@Test
public void testNoneUserDeleteProcessGroup() throws Exception {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
private ProcessGroupEntity getRandomProcessGroup(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
// get the process groups
final ClientResponse response = user.testGet(url);
// ensure the response was successful
assertEquals(200, response.getStatus());
// unmarshal
final ProcessGroupFlowEntity flowEntity = response.getEntity(ProcessGroupFlowEntity.class);
final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow();
final Set<ProcessGroupEntity> processGroups = flowDto.getProcessGroups();
// ensure the correct number of process groups
assertFalse(processGroups.isEmpty());
// use the first process group as the target
Iterator<ProcessGroupEntity> processGroupIter = processGroups.iterator();
assertTrue(processGroupIter.hasNext());
return processGroupIter.next();
}
private ClientResponse updateProcessGroup(final NiFiTestUser user, final ProcessGroupEntity entity) throws Exception {
final String url = helper.getBaseUrl() + "/process-groups/" + entity.getId();
// perform the request
return user.testPut(url, entity);
}
private ProcessGroupEntity createProcessGroup(final String name) throws Exception {
String url = helper.getBaseUrl() + "/process-groups/root/process-groups";
final String updatedName = name + count++;
// create the process group
ProcessGroupDTO processor = new ProcessGroupDTO();
processor.setName(updatedName);
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(READ_WRITE_CLIENT_ID);
revision.setVersion(0L);
// create the entity body
ProcessGroupEntity entity = new ProcessGroupEntity();
entity.setRevision(revision);
entity.setComponent(processor);
// perform the request
ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
// ensure the request is successful
assertEquals(201, response.getStatus());
// get the entity body
entity = response.getEntity(ProcessGroupEntity.class);
// verify creation
processor = entity.getComponent();
assertEquals(updatedName, processor.getName());
// get the processor
return entity;
}
private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception {
final ProcessGroupEntity entity = createProcessGroup("Copy");
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request
ClientResponse response = user.testDelete(entity.getComponent().getUri(), queryParams);
// ensure the request is failed with a forbidden status code
assertEquals(responseCode, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

View File

@ -0,0 +1,489 @@
/*
* 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.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.SourceTestProcessor;
import org.apache.nifi.web.api.dto.ProcessorDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.apache.nifi.web.api.entity.ProcessorEntity;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID;
import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Access control test for processors.
*/
public class ProcessorAccessControlTest {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-processors.xml";
private static AccessControlHelper helper;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
}
/**
* Ensures the READ user can get a processor.
*
* @throws Exception ex
*/
@Test
public void testReadUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the READ WRITE user can get a processor.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
}
/**
* Ensures the WRITE user can get a processor.
*
* @throws Exception ex
*/
@Test
public void testWriteUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the NONE user can get a processor.
*
* @throws Exception ex
*/
@Test
public void testNoneUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
}
/**
* Ensures the READ user cannot put a processor.
*
* @throws Exception ex
*/
@Test
public void testReadUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
entity.getRevision().setClientId(READ_CLIENT_ID);
entity.getComponent().setName("Updated Name");
// perform the request
final ClientResponse response = updateProcessor(helper.getReadUser(), entity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ_WRITE user can put a processor.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name";
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateProcessor(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ProcessorEntity responseEntity = response.getEntity(ProcessorEntity.class);
// verify
assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the READ_WRITE user can put a processor.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserPutProcessorThroughInheritedPolicy() throws Exception {
final ProcessorEntity entity = createProcessor(helper, NiFiTestAuthorizer.NO_POLICY_COMPONENT_NAME);
final String updatedName = "Updated name";
// attempt to update the name
final long version = entity.getRevision().getVersion();
entity.getRevision().setClientId(READ_WRITE_CLIENT_ID);
entity.getComponent().setName(updatedName);
// perform the request
final ClientResponse response = updateProcessor(helper.getReadWriteUser(), entity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ProcessorEntity responseEntity = response.getEntity(ProcessorEntity.class);
// verify
assertEquals(AccessControlHelper.READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
assertEquals(updatedName, responseEntity.getComponent().getName());
}
/**
* Ensures the WRITE user can put a processor.
*
* @throws Exception ex
*/
@Test
public void testWriteUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
// attempt to update the name
final ProcessorDTO requestDto = new ProcessorDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID);
final ProcessorEntity requestEntity = new ProcessorEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateProcessor(helper.getWriteUser(), requestEntity);
// ensure successful response
assertEquals(200, response.getStatus());
// get the response
final ProcessorEntity responseEntity = response.getEntity(ProcessorEntity.class);
// verify
assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId());
assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue());
}
/**
* Ensures the NONE user cannot put a processor.
*
* @throws Exception ex
*/
@Test
public void testNoneUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
// attempt to update the name
final ProcessorDTO requestDto = new ProcessorDTO();
requestDto.setId(entity.getId());
requestDto.setName(updatedName);
final long version = entity.getRevision().getVersion();
final RevisionDTO requestRevision = new RevisionDTO();
requestRevision.setVersion(version);
requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID);
final ProcessorEntity requestEntity = new ProcessorEntity();
requestEntity.setId(entity.getId());
requestEntity.setRevision(requestRevision);
requestEntity.setComponent(requestDto);
// perform the request
final ClientResponse response = updateProcessor(helper.getNoneUser(), requestEntity);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ user cannot clear state.
*
* @throws Exception ex
*/
@Test
public void testReadUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";
// perform the request
final ClientResponse response = helper.getReadUser().testPost(url);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the NONE user cannot clear state.
*
* @throws Exception ex
*/
@Test
public void testNoneUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";
// perform the request
final ClientResponse response = helper.getNoneUser().testPost(url);
// ensure forbidden response
assertEquals(403, response.getStatus());
}
/**
* Ensures the READ WRITE user can clear state.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";
// perform the request
final ClientResponse response = helper.getReadWriteUser().testPost(url);
// ensure ok response
assertEquals(200, response.getStatus());
}
/**
* Ensures the WRITE user can clear state.
*
* @throws Exception ex
*/
@Test
public void testWriteUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";
// perform the request
final ClientResponse response = helper.getWriteUser().testPost(url);
// ensure ok response
assertEquals(200, response.getStatus());
}
/**
* Ensures the READ user cannot delete a processor.
*
* @throws Exception ex
*/
@Test
public void testReadUserDeleteProcessor() throws Exception {
verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403);
}
/**
* Ensures the READ WRITE user can delete a processor.
*
* @throws Exception ex
*/
@Test
public void testReadWriteUserDeleteProcessor() throws Exception {
verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200);
}
/**
* Ensures the WRITE user can delete a processor.
*
* @throws Exception ex
*/
@Test
public void testWriteUserDeleteProcessor() throws Exception {
verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200);
}
/**
* Ensures the NONE user can delete a processor.
*
* @throws Exception ex
*/
@Test
public void testNoneUserDeleteProcessor() throws Exception {
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
}
private ProcessorEntity getRandomProcessor(final NiFiTestUser user) throws Exception {
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
// get the processors
final ClientResponse response = user.testGet(url);
// ensure the response was successful
assertEquals(200, response.getStatus());
// unmarshal
final ProcessGroupFlowEntity flowEntity = response.getEntity(ProcessGroupFlowEntity.class);
final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow();
final Set<ProcessorEntity> processors = flowDto.getProcessors();
// ensure the correct number of processors
assertFalse(processors.isEmpty());
// use the first processor as the target
Iterator<ProcessorEntity> processorIter = processors.iterator();
assertTrue(processorIter.hasNext());
return processorIter.next();
}
private ClientResponse updateProcessor(final NiFiTestUser user, final ProcessorEntity entity) throws Exception {
final String url = helper.getBaseUrl() + "/processors/" + entity.getId();
// perform the request
return user.testPut(url, entity);
}
public static ProcessorEntity createProcessor(final AccessControlHelper ach, final String name) throws Exception {
String url = ach.getBaseUrl() + "/process-groups/root/processors";
// create the processor
ProcessorDTO processor = new ProcessorDTO();
processor.setName(name);
processor.setType(SourceTestProcessor.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
ClientResponse response = ach.getReadWriteUser().testPost(url, entity);
// ensure the request is successful
assertEquals(201, response.getStatus());
// get the entity body
entity = response.getEntity(ProcessorEntity.class);
// verify creation
processor = entity.getComponent();
assertEquals(name, processor.getName());
assertEquals("org.apache.nifi.integration.util.SourceTestProcessor", processor.getType());
// get the processor
return entity;
}
private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception {
final ProcessorEntity entity = createProcessor(helper, "Copy");
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request
ClientResponse response = user.testDelete(entity.getComponent().getUri(), queryParams);
// ensure the request is failed with a forbidden status code
assertEquals(responseCode, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

View File

@ -21,14 +21,26 @@ import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.authorization.AuthorizerInitializationContext;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.resource.ResourceFactory;
/**
*
*/
public class NiFiTestAuthorizer implements Authorizer {
public static final String NO_POLICY_COMPONENT_NAME = "No policies";
public static final String PROXY_DN = "CN=localhost, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
public static final String NONE_USER_DN = "none@nifi";
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 TOKEN_USER = "user@nifi";
/**
* Creates a new FileAuthorizationProvider.
@ -46,9 +58,43 @@ public class NiFiTestAuthorizer implements Authorizer {
@Override
public AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException {
// allow proxy
if (ResourceFactory.getProxyResource().getIdentifier().equals(request.getResource().getIdentifier()) && PROXY_DN.equals(request.getIdentity())) {
return AuthorizationResult.approved();
}
// allow flow
if (ResourceFactory.getFlowResource().getIdentifier().equals(request.getResource().getIdentifier())) {
return AuthorizationResult.approved();
}
// no policy to test inheritance
if (NO_POLICY_COMPONENT_NAME.equals(request.getResource().getName())) {
return AuthorizationResult.resourceNotFound();
}
// allow the token user
if (TOKEN_USER.equals(request.getIdentity())) {
return AuthorizationResult.approved();
}
// read access
if (READ_USER_DN.equals(request.getIdentity()) || READ_WRITE_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 (RequestAction.WRITE.equals(request.getAction())) {
return AuthorizationResult.approved();
}
}
return AuthorizationResult.denied();
}
@Override
public void preDestruction() {
}

View File

@ -16,9 +16,8 @@
*/
package org.apache.nifi.integration.util;
import java.util.HashSet;
import java.util.Set;
import org.apache.nifi.annotation.behavior.Stateful;
import org.apache.nifi.components.state.Scope;
import org.apache.nifi.processor.AbstractSessionFactoryProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSessionFactory;
@ -26,6 +25,10 @@ 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;
@Stateful(scopes = Scope.LOCAL, description = "")
public class SourceTestProcessor extends AbstractSessionFactoryProcessor {
public SourceTestProcessor() {

View File

@ -16,9 +16,9 @@
<!--
This file lists all authority providers to use when running securely.
-->
<authorityProviders>
<provider>
<authorizers>
<authorizer>
<identifier>test-provider</identifier>
<class>org.apache.nifi.integration.util.NiFiTestAuthorizer</class>
</provider>
</authorityProviders>
</authorizer>
</authorizers>

View File

@ -21,7 +21,7 @@ nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.authority.provider.configuration.file=target/test-classes/access-control/authority-providers.xml
nifi.authorizer.configuration.file=target/test-classes/access-control/authorizers.xml
nifi.login.identity.provider.configuration.file=target/test-classes/access-control/login-identity-providers.xml
nifi.templates.directory=target/test-classes/access-control/templates
nifi.ui.banner.text=TEST BANNER
@ -82,7 +82,7 @@ nifi.web.war.directory=target/test-classes/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=
nifi.web.https.port=
nifi.web.https.port=8443
nifi.web.jetty.working.directory=target/test-classes/access-control/jetty
# security properties #
@ -99,7 +99,7 @@ nifi.security.truststoreType=JKS
nifi.security.truststorePasswd=localtest
nifi.security.needClientAuth=true
nifi.security.user.login.identity.provider=test-provider
nifi.security.user.authorizer=
nifi.security.user.authorizer=test-provider
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec

View File

@ -119,7 +119,7 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable
}
private LoginIdentityProviders loadLoginIdentityProvidersConfiguration() throws Exception {
final File loginIdentityProvidersConfigurationFile = properties.getLoginIdentityProviderConfiguraitonFile();
final File loginIdentityProvidersConfigurationFile = properties.getLoginIdentityProviderConfigurationFile();
// load the users from the specified file
if (loginIdentityProvidersConfigurationFile.exists()) {