NIFI-2554: - Requiring READ permissions on the referenced controller service when creating/updating processors, controller services, and reporting tasks.

- Preventing client side selection of unauthorized controller services unless they were the previously configured value.

This closes #860.

Signed-off-by: Bryan Bende <bbende@apache.org>
This commit is contained in:
Matt Gilman 2016-08-15 11:49:05 -04:00 committed by Bryan Bende
parent 2a92747046
commit 7d8dd27027
No known key found for this signature in database
GPG Key ID: A0DDA9ED50711C39
16 changed files with 489 additions and 114 deletions

View File

@ -34,7 +34,17 @@ public interface AuthorizableLookup {
* @param id processor id * @param id processor id
* @return authorizable * @return authorizable
*/ */
Authorizable getProcessor(String id); ControllerServiceReferencingComponentAuthorizable getProcessor(String id);
/**
* Get the authorizable for this Processor. This will create a dummy instance of the
* processor. The intent of this method is to provide access to the PropertyDescriptors
* prior to the component being created.
*
* @param type processor type
* @return authorizable
*/
ControllerServiceReferencingComponentAuthorizable getProcessorByType(String type);
/** /**
* Get the authorizable for querying Provenance. * Get the authorizable for querying Provenance.
@ -130,7 +140,17 @@ public interface AuthorizableLookup {
* @param id controller service id * @param id controller service id
* @return authorizable * @return authorizable
*/ */
Authorizable getControllerService(String id); ControllerServiceReferencingComponentAuthorizable getControllerService(String id);
/**
* Get the authorizable for this Controller Service. This will create a dummy instance of the
* controller service. The intent of this method is to provide access to the PropertyDescriptors
* prior to the component being created.
*
* @param type processor type
* @return authorizable
*/
ControllerServiceReferencingComponentAuthorizable getControllerServiceByType(String type);
/** /**
* Get the authorizable referencing component. * Get the authorizable referencing component.
@ -147,7 +167,17 @@ public interface AuthorizableLookup {
* @param id reporting task id * @param id reporting task id
* @return authorizable * @return authorizable
*/ */
Authorizable getReportingTask(String id); ControllerServiceReferencingComponentAuthorizable getReportingTask(String id);
/**
* Get the authorizable for this Reporting Task. This will create a dummy instance of the
* reporting task. The intent of this method is to provide access to the PropertyDescriptors
* prior to the component being created.
*
* @param type processor type
* @return authorizable
*/
ControllerServiceReferencingComponentAuthorizable getReportingTaskByType(String type);
/** /**
* Get the authorizable Template. * Get the authorizable Template.

View File

@ -0,0 +1,74 @@
/*
* 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.authorization;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.components.PropertyDescriptor;
import java.util.Map;
import java.util.Objects;
/**
* Authorizes references to Controller Services. Utilizes when Processors, Controller Services, and Reporting Tasks are created and updated.
*/
public final class AuthorizeControllerServiceReference {
/**
* Authorizes the proposed properties for the specified authorizable.
*
* @param proposedProperties proposed properties
* @param authorizable authorizable that may reference a controller service
* @param authorizer authorizer
* @param lookup lookup
*/
public static void authorizeControllerServiceReferences(final Map<String, String> proposedProperties, final ControllerServiceReferencingComponentAuthorizable authorizable,
final Authorizer authorizer, final AuthorizableLookup lookup) {
// only attempt to authorize if properties are changing
if (proposedProperties != null) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
for (final Map.Entry<String, String> entry : proposedProperties.entrySet()) {
final String propertyName = entry.getKey();
final PropertyDescriptor propertyDescriptor = authorizable.getPropertyDescriptor(propertyName);
// if this descriptor identifies a controller service
if (propertyDescriptor.getControllerServiceDefinition() != null) {
final String currentValue = authorizable.getValue(propertyDescriptor);
final String proposedValue = entry.getValue();
// if the value is changing
if (!Objects.equals(currentValue, proposedValue)) {
// ensure access to the old service
if (currentValue != null) {
final Authorizable currentServiceAuthorizable = lookup.getControllerService(currentValue).getAuthorizable();
currentServiceAuthorizable.authorize(authorizer, RequestAction.READ, user);
}
// ensure access to the new service
if (proposedValue != null) {
final Authorizable newServiceAuthorizable = lookup.getControllerService(proposedValue).getAuthorizable();
newServiceAuthorizable.authorize(authorizer, RequestAction.READ, user);
}
}
}
}
}
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.authorization;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.components.PropertyDescriptor;
/**
* Authorizable for a component that references a ControllerService.
*/
public interface ControllerServiceReferencingComponentAuthorizable {
/**
* Returns the base authorizable for this ControllerServiceReference. Non null
*
* @return authorizable
*/
Authorizable getAuthorizable();
/**
* Returns the property descriptor for the specified property.
*
* @param propertyName property name
* @return property descriptor
*/
PropertyDescriptor getPropertyDescriptor(String propertyName);
/**
* Returns the current value of the specified property.
*
* @param propertyDescriptor property descriptor
* @return value
*/
String getValue(PropertyDescriptor propertyDescriptor);
}

View File

@ -24,9 +24,12 @@ import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
import org.apache.nifi.authorization.resource.ResourceFactory; import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.resource.ResourceType; import org.apache.nifi.authorization.resource.ResourceType;
import org.apache.nifi.authorization.resource.TenantAuthorizable; import org.apache.nifi.authorization.resource.TenantAuthorizable;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.connectable.Connectable; import org.apache.nifi.connectable.Connectable;
import org.apache.nifi.connectable.Connection; import org.apache.nifi.connectable.Connection;
import org.apache.nifi.controller.ConfiguredComponent; import org.apache.nifi.controller.ConfiguredComponent;
import org.apache.nifi.controller.ProcessorNode;
import org.apache.nifi.controller.ReportingTaskNode;
import org.apache.nifi.controller.Snippet; import org.apache.nifi.controller.Snippet;
import org.apache.nifi.controller.service.ControllerServiceNode; import org.apache.nifi.controller.service.ControllerServiceNode;
import org.apache.nifi.controller.service.ControllerServiceReference; import org.apache.nifi.controller.service.ControllerServiceReference;
@ -115,8 +118,49 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
} }
@Override @Override
public Authorizable getProcessor(final String id) { public ControllerServiceReferencingComponentAuthorizable getProcessor(final String id) {
return processorDAO.getProcessor(id); final ProcessorNode processorNode = processorDAO.getProcessor(id);
return new ControllerServiceReferencingComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return processorNode;
}
@Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return processorNode.getProperty(propertyDescriptor);
}
@Override
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return processorNode.getPropertyDescriptor(propertyName);
}
};
}
@Override
public ControllerServiceReferencingComponentAuthorizable getProcessorByType(String type) {
try {
final ProcessorNode processorNode = controllerFacade.createTemporaryProcessor(type);
return new ControllerServiceReferencingComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return processorNode;
}
@Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return processorNode.getProperty(propertyDescriptor);
}
@Override
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return processorNode.getPropertyDescriptor(propertyName);
}
};
} catch (final Exception e) {
throw new AccessDeniedException("Unable to create processor to verify if it references any Controller Services.");
}
} }
@Override @Override
@ -212,8 +256,49 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
} }
@Override @Override
public Authorizable getControllerService(final String id) { public ControllerServiceReferencingComponentAuthorizable getControllerService(final String id) {
return controllerServiceDAO.getControllerService(id); final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(id);
return new ControllerServiceReferencingComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return controllerService;
}
@Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return controllerService.getProperty(propertyDescriptor);
}
@Override
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return controllerService.getControllerServiceImplementation().getPropertyDescriptor(propertyName);
}
};
}
@Override
public ControllerServiceReferencingComponentAuthorizable getControllerServiceByType(String type) {
try {
final ControllerServiceNode controllerService = controllerFacade.createTemporaryControllerService(type);
return new ControllerServiceReferencingComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return controllerService;
}
@Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return controllerService.getProperty(propertyDescriptor);
}
@Override
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return controllerService.getControllerServiceImplementation().getPropertyDescriptor(propertyName);
}
};
} catch (final Exception e) {
throw new AccessDeniedException("Unable to create controller service to verify if it references any Controller Services.");
}
} }
@Override @Override
@ -260,8 +345,49 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
} }
@Override @Override
public Authorizable getReportingTask(final String id) { public ControllerServiceReferencingComponentAuthorizable getReportingTask(final String id) {
return reportingTaskDAO.getReportingTask(id); final ReportingTaskNode reportingTaskNode = reportingTaskDAO.getReportingTask(id);
return new ControllerServiceReferencingComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return reportingTaskNode;
}
@Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return reportingTaskNode.getProperty(propertyDescriptor);
}
@Override
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return reportingTaskNode.getReportingTask().getPropertyDescriptor(propertyName);
}
};
}
@Override
public ControllerServiceReferencingComponentAuthorizable getReportingTaskByType(String type) {
try {
final ReportingTaskNode reportingTask = controllerFacade.createTemporaryReportingTask(type);
return new ControllerServiceReferencingComponentAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return reportingTask;
}
@Override
public String getValue(PropertyDescriptor propertyDescriptor) {
return reportingTask.getProperty(propertyDescriptor);
}
@Override
public PropertyDescriptor getPropertyDescriptor(String propertyName) {
return reportingTask.getReportingTask().getPropertyDescriptor(propertyName);
}
};
} catch (final Exception e) {
throw new AccessDeniedException("Unable to create reporting to verify if it references any Controller Services.");
}
} }
@Override @Override
@ -357,7 +483,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
Authorizable authorizable = null; Authorizable authorizable = null;
switch (resourceType) { switch (resourceType) {
case ControllerService: case ControllerService:
authorizable = getControllerService(componentId); authorizable = getControllerService(componentId).getAuthorizable();
break; break;
case Funnel: case Funnel:
authorizable = getFunnel(componentId); authorizable = getFunnel(componentId);
@ -372,7 +498,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
authorizable = getOutputPort(componentId); authorizable = getOutputPort(componentId);
break; break;
case Processor: case Processor:
authorizable = getProcessor(componentId); authorizable = getProcessor(componentId).getAuthorizable();
break; break;
case ProcessGroup: case ProcessGroup:
authorizable = getProcessGroup(componentId).getAuthorizable(); authorizable = getProcessGroup(componentId).getAuthorizable();
@ -381,7 +507,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
authorizable = getRemoteProcessGroup(componentId); authorizable = getRemoteProcessGroup(componentId);
break; break;
case ReportingTask: case ReportingTask:
authorizable = getReportingTask(componentId); authorizable = getReportingTask(componentId).getAuthorizable();
break; break;
case Template: case Template:
authorizable = getTemplate(componentId); authorizable = getTemplate(componentId);

View File

@ -2275,13 +2275,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
try { try {
switch (type) { switch (type) {
case PROCESSOR: case PROCESSOR:
authorizable = authorizableLookup.getProcessor(sourceId); authorizable = authorizableLookup.getProcessor(sourceId).getAuthorizable();
break; break;
case REPORTING_TASK: case REPORTING_TASK:
authorizable = authorizableLookup.getReportingTask(sourceId); authorizable = authorizableLookup.getReportingTask(sourceId).getAuthorizable();
break; break;
case CONTROLLER_SERVICE: case CONTROLLER_SERVICE:
authorizable = authorizableLookup.getControllerService(sourceId); authorizable = authorizableLookup.getControllerService(sourceId).getAuthorizable();
break; break;
case FLOW_CONTROLLER: case FLOW_CONTROLLER:
authorizable = controllerFacade; authorizable = controllerFacade;
@ -2465,7 +2465,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final List<Bulletin> authorizedControllerServiceBulletins = new ArrayList<>(); final List<Bulletin> authorizedControllerServiceBulletins = new ArrayList<>();
for (final Bulletin bulletin : allControllerServiceBulletins) { for (final Bulletin bulletin : allControllerServiceBulletins) {
try { try {
final Authorizable controllerServiceAuthorizable = authorizableLookup.getControllerService(bulletin.getSourceId()); final Authorizable controllerServiceAuthorizable = authorizableLookup.getControllerService(bulletin.getSourceId()).getAuthorizable();
if (controllerServiceAuthorizable.isAuthorized(authorizer, RequestAction.READ, user)) { if (controllerServiceAuthorizable.isAuthorized(authorizer, RequestAction.READ, user)) {
authorizedControllerServiceBulletins.add(bulletin); authorizedControllerServiceBulletins.add(bulletin);
} }
@ -2481,7 +2481,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final List<Bulletin> authorizedReportingTaskBulletins = new ArrayList<>(); final List<Bulletin> authorizedReportingTaskBulletins = new ArrayList<>();
for (final Bulletin bulletin : allReportingTaskBulletins) { for (final Bulletin bulletin : allReportingTaskBulletins) {
try { try {
final Authorizable reportingTaskAuthorizable = authorizableLookup.getReportingTask(bulletin.getSourceId()); final Authorizable reportingTaskAuthorizable = authorizableLookup.getReportingTask(bulletin.getSourceId()).getAuthorizable();
if (reportingTaskAuthorizable.isAuthorized(authorizer, RequestAction.READ, user)) { if (reportingTaskAuthorizable.isAuthorized(authorizer, RequestAction.READ, user)) {
authorizedReportingTaskBulletins.add(bulletin); authorizedReportingTaskBulletins.add(bulletin);
} }
@ -2957,13 +2957,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
try { try {
switch (type) { switch (type) {
case Processor: case Processor:
authorizable = authorizableLookup.getProcessor(sourceId); authorizable = authorizableLookup.getProcessor(sourceId).getAuthorizable();
break; break;
case ReportingTask: case ReportingTask:
authorizable = authorizableLookup.getReportingTask(sourceId); authorizable = authorizableLookup.getReportingTask(sourceId).getAuthorizable();
break; break;
case ControllerService: case ControllerService:
authorizable = authorizableLookup.getControllerService(sourceId); authorizable = authorizableLookup.getControllerService(sourceId).getAuthorizable();
break; break;
case Controller: case Controller:
authorizable = controllerFacade; authorizable = controllerFacade;

View File

@ -29,7 +29,9 @@ import org.apache.nifi.authorization.AccessDeniedException;
import org.apache.nifi.authorization.AuthorizationRequest; import org.apache.nifi.authorization.AuthorizationRequest;
import org.apache.nifi.authorization.AuthorizationResult; import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.AuthorizationResult.Result; import org.apache.nifi.authorization.AuthorizationResult.Result;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.UserContextKeys; import org.apache.nifi.authorization.UserContextKeys;
import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.authorization.resource.Authorizable;
@ -145,7 +147,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
case ProcessorConfiguration: case ProcessorConfiguration:
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getProcessor(requestContext.getId()); final Authorizable authorizable = lookup.getProcessor(requestContext.getId()).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
@ -154,7 +156,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
case ControllerServiceConfiguration: case ControllerServiceConfiguration:
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getControllerService(requestContext.getId()); final Authorizable authorizable = lookup.getControllerService(requestContext.getId()).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
@ -163,7 +165,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
case ReportingTaskConfiguration: case ReportingTaskConfiguration:
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getReportingTask(requestContext.getId()); final Authorizable authorizable = lookup.getReportingTask(requestContext.getId()).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
@ -336,7 +338,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getProcessor(id); final Authorizable authorizable = lookup.getProcessor(id).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -387,8 +389,12 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getProcessor(id); // authorize the processor
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessor(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced service
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
}); });
final ProcessorDTO processor; final ProcessorDTO processor;
@ -516,7 +522,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getControllerService(id); final Authorizable authorizable = lookup.getControllerService(id).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -574,8 +580,12 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getControllerService(id); // authorize the controller service
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerService(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced service
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
}); });
final ControllerServiceDTO controllerService; final ControllerServiceDTO controllerService;
@ -677,7 +687,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getReportingTask(id); final Authorizable authorizable = lookup.getReportingTask(id).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); authorizable.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -735,8 +745,12 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable authorizable = lookup.getReportingTask(id); // authorize the reporting task
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTask(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced service
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
}); });
final ReportingTaskDTO reportingTask; final ReportingTaskDTO reportingTask;

View File

@ -426,7 +426,7 @@ public abstract class ApplicationResource {
processGroupAuthorizable.getEncapsulatedAuthorizables().forEach(authorize); processGroupAuthorizable.getEncapsulatedAuthorizables().forEach(authorize);
}); });
snippet.getRemoteProcessGroups().keySet().stream().map(id -> lookup.getRemoteProcessGroup(id)).forEach(authorize); snippet.getRemoteProcessGroups().keySet().stream().map(id -> lookup.getRemoteProcessGroup(id)).forEach(authorize);
snippet.getProcessors().keySet().stream().map(id -> lookup.getProcessor(id)).forEach(authorize); snippet.getProcessors().keySet().stream().map(id -> lookup.getProcessor(id).getAuthorizable()).forEach(authorize);
snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize); snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize);
snippet.getOutputPorts().keySet().stream().map(id -> lookup.getOutputPort(id)).forEach(authorize); snippet.getOutputPorts().keySet().stream().map(id -> lookup.getOutputPort(id)).forEach(authorize);
snippet.getConnections().keySet().stream().map(id -> lookup.getConnection(id)).forEach(connAuth -> authorize.accept(connAuth.getAuthorizable())); snippet.getConnections().keySet().stream().map(id -> lookup.getConnection(id)).forEach(connAuth -> authorize.accept(connAuth.getAuthorizable()));
@ -451,7 +451,7 @@ public abstract class ApplicationResource {
processGroupAuthorizable.getEncapsulatedAuthorizables().forEach(authorize); processGroupAuthorizable.getEncapsulatedAuthorizables().forEach(authorize);
}); });
snippet.getRemoteProcessGroups().keySet().stream().map(id -> lookup.getRemoteProcessGroup(id)).forEach(authorize); snippet.getRemoteProcessGroups().keySet().stream().map(id -> lookup.getRemoteProcessGroup(id)).forEach(authorize);
snippet.getProcessors().keySet().stream().map(id -> lookup.getProcessor(id)).forEach(authorize); snippet.getProcessors().keySet().stream().map(id -> lookup.getProcessor(id).getAuthorizable()).forEach(authorize);
snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize); snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize);
snippet.getOutputPorts().keySet().stream().map(id -> lookup.getOutputPort(id)).forEach(authorize); snippet.getOutputPorts().keySet().stream().map(id -> lookup.getOutputPort(id)).forEach(authorize);
snippet.getConnections().keySet().stream().map(id -> lookup.getConnection(id)).forEach(connAuth -> authorize.accept(connAuth.getAuthorizable())); snippet.getConnections().keySet().stream().map(id -> lookup.getConnection(id)).forEach(connAuth -> authorize.accept(connAuth.getAuthorizable()));

View File

@ -28,7 +28,9 @@ import org.apache.nifi.authorization.AccessDeniedException;
import org.apache.nifi.authorization.AuthorizationRequest; import org.apache.nifi.authorization.AuthorizationRequest;
import org.apache.nifi.authorization.AuthorizationResult; import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.AuthorizationResult.Result; import org.apache.nifi.authorization.AuthorizationResult.Result;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.UserContextKeys; import org.apache.nifi.authorization.UserContextKeys;
import org.apache.nifi.authorization.resource.ResourceFactory; import org.apache.nifi.authorization.resource.ResourceFactory;
@ -39,7 +41,9 @@ import org.apache.nifi.web.IllegalClusterResourceRequestException;
import org.apache.nifi.web.NiFiServiceFacade; import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision; import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.ClusterDTO; import org.apache.nifi.web.api.dto.ClusterDTO;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.NodeDTO; import org.apache.nifi.web.api.dto.NodeDTO;
import org.apache.nifi.web.api.dto.ReportingTaskDTO;
import org.apache.nifi.web.api.entity.ClusterEntity; import org.apache.nifi.web.api.entity.ClusterEntity;
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity; import org.apache.nifi.web.api.entity.ControllerServiceEntity;
@ -230,7 +234,8 @@ public class ControllerResource extends ApplicationResource {
value = "Creates a new reporting task", value = "Creates a new reporting task",
response = ReportingTaskEntity.class, response = ReportingTaskEntity.class,
authorizations = { authorizations = {
@Authorization(value = "Write - /controller", type = "") @Authorization(value = "Write - /controller", type = ""),
@Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
} }
) )
@ApiResponses( @ApiResponses(
@ -256,11 +261,12 @@ public class ControllerResource extends ApplicationResource {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Reporting task."); throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Reporting task.");
} }
if (reportingTaskEntity.getComponent().getId() != null) { final ReportingTaskDTO requestReportingTask = reportingTaskEntity.getComponent();
if (requestReportingTask.getId() != null) {
throw new IllegalArgumentException("Reporting task ID cannot be specified."); throw new IllegalArgumentException("Reporting task ID cannot be specified.");
} }
if (StringUtils.isBlank(reportingTaskEntity.getComponent().getType())) { if (StringUtils.isBlank(requestReportingTask.getType())) {
throw new IllegalArgumentException("The type of reporting task to create must be specified."); throw new IllegalArgumentException("The type of reporting task to create must be specified.");
} }
@ -274,6 +280,11 @@ public class ControllerResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
authorizeController(RequestAction.WRITE); authorizeController(RequestAction.WRITE);
if (requestReportingTask.getProperties() != null) {
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTaskByType(requestReportingTask.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTask.getProperties(), authorizable, authorizer, lookup);
}
}); });
} }
if (validationPhase) { if (validationPhase) {
@ -281,11 +292,11 @@ public class ControllerResource extends ApplicationResource {
} }
// set the processor id as appropriate // set the processor id as appropriate
reportingTaskEntity.getComponent().setId(generateUuid()); requestReportingTask.setId(generateUuid());
// create the reporting task and generate the json // create the reporting task and generate the json
final Revision revision = getRevision(reportingTaskEntity, reportingTaskEntity.getComponent().getId()); final Revision revision = getRevision(reportingTaskEntity, requestReportingTask.getId());
final ReportingTaskEntity entity = serviceFacade.createReportingTask(revision, reportingTaskEntity.getComponent()); final ReportingTaskEntity entity = serviceFacade.createReportingTask(revision, requestReportingTask);
reportingTaskResource.populateRemainingReportingTaskEntityContent(entity); reportingTaskResource.populateRemainingReportingTaskEntityContent(entity);
// build the response // build the response
@ -311,7 +322,8 @@ public class ControllerResource extends ApplicationResource {
value = "Creates a new controller service", value = "Creates a new controller service",
response = ControllerServiceEntity.class, response = ControllerServiceEntity.class,
authorizations = { authorizations = {
@Authorization(value = "Write - /controller", type = "") @Authorization(value = "Write - /controller", type = ""),
@Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
} }
) )
@ApiResponses( @ApiResponses(
@ -337,11 +349,16 @@ public class ControllerResource extends ApplicationResource {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Controller service."); throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Controller service.");
} }
if (controllerServiceEntity.getComponent().getId() != null) { final ControllerServiceDTO requestControllerService = controllerServiceEntity.getComponent();
if (requestControllerService.getId() != null) {
throw new IllegalArgumentException("Controller service ID cannot be specified."); throw new IllegalArgumentException("Controller service ID cannot be specified.");
} }
if (StringUtils.isBlank(controllerServiceEntity.getComponent().getType())) { if (requestControllerService.getParentGroupId() != null) {
throw new IllegalArgumentException("Parent process group ID cannot be specified.");
}
if (StringUtils.isBlank(requestControllerService.getType())) {
throw new IllegalArgumentException("The type of controller service to create must be specified."); throw new IllegalArgumentException("The type of controller service to create must be specified.");
} }
@ -355,6 +372,11 @@ public class ControllerResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
authorizeController(RequestAction.WRITE); authorizeController(RequestAction.WRITE);
if (requestControllerService.getProperties() != null) {
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerServiceByType(requestControllerService.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
}
}); });
} }
if (validationPhase) { if (validationPhase) {
@ -362,11 +384,11 @@ public class ControllerResource extends ApplicationResource {
} }
// set the processor id as appropriate // set the processor id as appropriate
controllerServiceEntity.getComponent().setId(generateUuid()); requestControllerService.setId(generateUuid());
// create the controller service and generate the json // create the controller service and generate the json
final Revision revision = getRevision(controllerServiceEntity, controllerServiceEntity.getComponent().getId()); final Revision revision = getRevision(controllerServiceEntity, requestControllerService.getId());
final ControllerServiceEntity entity = serviceFacade.createControllerService(revision, null, controllerServiceEntity.getComponent()); final ControllerServiceEntity entity = serviceFacade.createControllerService(revision, null, requestControllerService);
controllerServiceResource.populateRemainingControllerServiceEntityContent(entity); controllerServiceResource.populateRemainingControllerServiceEntityContent(entity);
// build the response // build the response

View File

@ -23,7 +23,9 @@ import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses; import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization; import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUserUtils; import org.apache.nifi.authorization.user.NiFiUserUtils;
@ -175,7 +177,7 @@ public class ControllerServiceResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable controllerService = lookup.getControllerService(id); final Authorizable controllerService = lookup.getControllerService(id).getAuthorizable();
controllerService.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); controllerService.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -236,7 +238,7 @@ public class ControllerServiceResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable controllerService = lookup.getControllerService(id); final Authorizable controllerService = lookup.getControllerService(id).getAuthorizable();
controllerService.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); controllerService.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -290,7 +292,7 @@ public class ControllerServiceResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable controllerService = lookup.getControllerService(id); final Authorizable controllerService = lookup.getControllerService(id).getAuthorizable();
controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
@ -348,7 +350,7 @@ public class ControllerServiceResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable controllerService = lookup.getControllerService(id); final Authorizable controllerService = lookup.getControllerService(id).getAuthorizable();
controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -406,7 +408,7 @@ public class ControllerServiceResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable controllerService = lookup.getControllerService(id); final Authorizable controllerService = lookup.getControllerService(id).getAuthorizable();
controllerService.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); controllerService.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -545,7 +547,8 @@ public class ControllerServiceResource extends ApplicationResource {
value = "Updates a controller service", value = "Updates a controller service",
response = ControllerServiceEntity.class, response = ControllerServiceEntity.class,
authorizations = { authorizations = {
@Authorization(value = "Write - /controller-services/{uuid}", type = "") @Authorization(value = "Write - /controller-services/{uuid}", type = ""),
@Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
} }
) )
@ApiResponses( @ApiResponses(
@ -594,8 +597,12 @@ public class ControllerServiceResource extends ApplicationResource {
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
Authorizable authorizable = lookup.getControllerService(id); // authorize the service
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerService(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced services
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerServiceDTO.getProperties(), authorizable, authorizer, lookup);
}, },
() -> serviceFacade.verifyUpdateControllerService(requestControllerServiceDTO), () -> serviceFacade.verifyUpdateControllerService(requestControllerServiceDTO),
() -> { () -> {
@ -668,7 +675,7 @@ public class ControllerServiceResource extends ApplicationResource {
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
final Authorizable controllerService = lookup.getControllerService(id); final Authorizable controllerService = lookup.getControllerService(id).getAuthorizable();
controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); controllerService.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}, },
() -> serviceFacade.verifyDeleteControllerService(id), () -> serviceFacade.verifyDeleteControllerService(id),

View File

@ -26,7 +26,9 @@ import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization; import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizableLookup; import org.apache.nifi.authorization.AuthorizableLookup;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
import org.apache.nifi.authorization.ProcessGroupAuthorizable; import org.apache.nifi.authorization.ProcessGroupAuthorizable;
import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.authorization.resource.Authorizable;
@ -38,7 +40,10 @@ import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.ResourceNotFoundException; import org.apache.nifi.web.ResourceNotFoundException;
import org.apache.nifi.web.Revision; import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.ConnectionDTO; import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO; import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
import org.apache.nifi.web.api.dto.ProcessorDTO;
import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
import org.apache.nifi.web.api.dto.TemplateDTO; import org.apache.nifi.web.api.dto.TemplateDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO; import org.apache.nifi.web.api.dto.flow.FlowDTO;
@ -553,7 +558,8 @@ public class ProcessGroupResource extends ApplicationResource {
value = "Creates a new processor", value = "Creates a new processor",
response = ProcessorEntity.class, response = ProcessorEntity.class,
authorizations = { authorizations = {
@Authorization(value = "Write - /process-groups/{uuid}", type = "") @Authorization(value = "Write - /process-groups/{uuid}", type = ""),
@Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
} }
) )
@ApiResponses( @ApiResponses(
@ -585,19 +591,20 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Processor."); throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Processor.");
} }
if (processorEntity.getComponent().getId() != null) { final ProcessorDTO requestProcessor = processorEntity.getComponent();
if (requestProcessor.getId() != null) {
throw new IllegalArgumentException("Processor ID cannot be specified."); throw new IllegalArgumentException("Processor ID cannot be specified.");
} }
if (StringUtils.isBlank(processorEntity.getComponent().getType())) { if (StringUtils.isBlank(requestProcessor.getType())) {
throw new IllegalArgumentException("The type of processor to create must be specified."); throw new IllegalArgumentException("The type of processor to create must be specified.");
} }
if (processorEntity.getComponent().getParentGroupId() != null && !groupId.equals(processorEntity.getComponent().getParentGroupId())) { if (requestProcessor.getParentGroupId() != null && !groupId.equals(requestProcessor.getParentGroupId())) {
throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s",
processorEntity.getComponent().getParentGroupId(), groupId)); requestProcessor.getParentGroupId(), groupId));
} }
processorEntity.getComponent().setParentGroupId(groupId); requestProcessor.setParentGroupId(groupId);
if (isReplicateRequest()) { if (isReplicateRequest()) {
return replicate(HttpMethod.POST, processorEntity); return replicate(HttpMethod.POST, processorEntity);
@ -610,6 +617,12 @@ public class ProcessGroupResource extends ApplicationResource {
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable(); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
final ProcessorConfigDTO config = requestProcessor.getConfig();
if (config != null && config.getProperties() != null) {
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessorByType(requestProcessor.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(), authorizable, authorizer, lookup);
}
}); });
} }
if (validationPhase) { if (validationPhase) {
@ -617,11 +630,11 @@ public class ProcessGroupResource extends ApplicationResource {
} }
// set the processor id as appropriate // set the processor id as appropriate
processorEntity.getComponent().setId(generateUuid()); requestProcessor.setId(generateUuid());
// create the new processor // create the new processor
final Revision revision = getRevision(processorEntity, processorEntity.getComponent().getId()); final Revision revision = getRevision(processorEntity, requestProcessor.getId());
final ProcessorEntity entity = serviceFacade.createProcessor(revision, groupId, processorEntity.getComponent()); final ProcessorEntity entity = serviceFacade.createProcessor(revision, groupId, requestProcessor);
processorResource.populateRemainingProcessorEntityContent(entity); processorResource.populateRemainingProcessorEntityContent(entity);
// generate a 201 created response // generate a 201 created response
@ -2074,7 +2087,8 @@ public class ProcessGroupResource extends ApplicationResource {
value = "Creates a new controller service", value = "Creates a new controller service",
response = ControllerServiceEntity.class, response = ControllerServiceEntity.class,
authorizations = { authorizations = {
@Authorization(value = "Write - /process-groups/{uuid}", type = "") @Authorization(value = "Write - /process-groups/{uuid}", type = ""),
@Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
} }
) )
@ApiResponses( @ApiResponses(
@ -2105,19 +2119,20 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Controller service."); throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Controller service.");
} }
if (controllerServiceEntity.getComponent().getId() != null) { final ControllerServiceDTO requestControllerService = controllerServiceEntity.getComponent();
if (requestControllerService.getId() != null) {
throw new IllegalArgumentException("Controller service ID cannot be specified."); throw new IllegalArgumentException("Controller service ID cannot be specified.");
} }
if (StringUtils.isBlank(controllerServiceEntity.getComponent().getType())) { if (StringUtils.isBlank(requestControllerService.getType())) {
throw new IllegalArgumentException("The type of controller service to create must be specified."); throw new IllegalArgumentException("The type of controller service to create must be specified.");
} }
if (controllerServiceEntity.getComponent().getParentGroupId() != null && !groupId.equals(controllerServiceEntity.getComponent().getParentGroupId())) { if (requestControllerService.getParentGroupId() != null && !groupId.equals(requestControllerService.getParentGroupId())) {
throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s",
controllerServiceEntity.getComponent().getParentGroupId(), groupId)); requestControllerService.getParentGroupId(), groupId));
} }
controllerServiceEntity.getComponent().setParentGroupId(groupId); requestControllerService.setParentGroupId(groupId);
if (isReplicateRequest()) { if (isReplicateRequest()) {
return replicate(HttpMethod.POST, controllerServiceEntity); return replicate(HttpMethod.POST, controllerServiceEntity);
@ -2130,6 +2145,11 @@ public class ProcessGroupResource extends ApplicationResource {
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable(); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
if (requestControllerService.getProperties() != null) {
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerServiceByType(requestControllerService.getType());
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
}
}); });
} }
if (validationPhase) { if (validationPhase) {
@ -2137,11 +2157,11 @@ public class ProcessGroupResource extends ApplicationResource {
} }
// set the processor id as appropriate // set the processor id as appropriate
controllerServiceEntity.getComponent().setId(generateUuid()); requestControllerService.setId(generateUuid());
// create the controller service and generate the json // create the controller service and generate the json
final Revision revision = getRevision(controllerServiceEntity, controllerServiceEntity.getComponent().getId()); final Revision revision = getRevision(controllerServiceEntity, requestControllerService.getId());
final ControllerServiceEntity entity = serviceFacade.createControllerService(revision, groupId, controllerServiceEntity.getComponent()); final ControllerServiceEntity entity = serviceFacade.createControllerService(revision, groupId, requestControllerService);
controllerServiceResource.populateRemainingControllerServiceEntityContent(entity); controllerServiceResource.populateRemainingControllerServiceEntityContent(entity);
// build the response // build the response

View File

@ -23,9 +23,12 @@ import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses; import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization; import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils; import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.ui.extension.UiExtension; import org.apache.nifi.ui.extension.UiExtension;
import org.apache.nifi.ui.extension.UiExtensionMapping; import org.apache.nifi.ui.extension.UiExtensionMapping;
@ -173,7 +176,7 @@ public class ProcessorResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processor = lookup.getProcessor(id); final Authorizable processor = lookup.getProcessor(id).getAuthorizable();
processor.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processor.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -241,7 +244,7 @@ public class ProcessorResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processor = lookup.getProcessor(id); final Authorizable processor = lookup.getProcessor(id).getAuthorizable();
processor.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processor.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -296,7 +299,7 @@ public class ProcessorResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processor = lookup.getProcessor(id); final Authorizable processor = lookup.getProcessor(id).getAuthorizable();
processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
@ -355,7 +358,7 @@ public class ProcessorResource extends ApplicationResource {
if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processor = lookup.getProcessor(id); final Authorizable processor = lookup.getProcessor(id).getAuthorizable();
processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -391,7 +394,8 @@ public class ProcessorResource extends ApplicationResource {
value = "Updates a processor", value = "Updates a processor",
response = ProcessorEntity.class, response = ProcessorEntity.class,
authorizations = { authorizations = {
@Authorization(value = "Write - /processors/{uuid}", type = "") @Authorization(value = "Write - /processors/{uuid}", type = ""),
@Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
} }
) )
@ApiResponses( @ApiResponses(
@ -440,8 +444,15 @@ public class ProcessorResource extends ApplicationResource {
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
Authorizable authorizable = lookup.getProcessor(id); final NiFiUser user = NiFiUserUtils.getNiFiUser();
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessor(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
final ProcessorConfigDTO config = requestProcessorDTO.getConfig();
if (config != null) {
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(), authorizable, authorizer, lookup);
}
}, },
() -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO), () -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO),
() -> { () -> {
@ -511,7 +522,7 @@ public class ProcessorResource extends ApplicationResource {
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
final Authorizable processor = lookup.getProcessor(id); final Authorizable processor = lookup.getProcessor(id).getAuthorizable();
processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}, },
() -> serviceFacade.verifyDeleteProcessor(id), () -> serviceFacade.verifyDeleteProcessor(id),

View File

@ -23,7 +23,9 @@ import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses; import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization; import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUserUtils; import org.apache.nifi.authorization.user.NiFiUserUtils;
@ -162,7 +164,7 @@ public class ReportingTaskResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable reportingTask = lookup.getReportingTask(id); final Authorizable reportingTask = lookup.getReportingTask(id).getAuthorizable();
reportingTask.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); reportingTask.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -223,7 +225,7 @@ public class ReportingTaskResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable reportingTask = lookup.getReportingTask(id); final Authorizable reportingTask = lookup.getReportingTask(id).getAuthorizable();
reportingTask.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); reportingTask.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -277,7 +279,7 @@ public class ReportingTaskResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable reportingTask = lookup.getReportingTask(id); final Authorizable reportingTask = lookup.getReportingTask(id).getAuthorizable();
reportingTask.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); reportingTask.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
@ -335,7 +337,7 @@ public class ReportingTaskResource extends ApplicationResource {
if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processor = lookup.getReportingTask(id); final Authorizable processor = lookup.getReportingTask(id).getAuthorizable();
processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processor.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -370,7 +372,8 @@ public class ReportingTaskResource extends ApplicationResource {
value = "Updates a reporting task", value = "Updates a reporting task",
response = ReportingTaskEntity.class, response = ReportingTaskEntity.class,
authorizations = { authorizations = {
@Authorization(value = "Write - /reporting-tasks/{uuid}", type = "") @Authorization(value = "Write - /reporting-tasks/{uuid}", type = ""),
@Authorization(value = "Read - any referenced Controller Services - /controller-services/{uuid}", type = "")
} }
) )
@ApiResponses( @ApiResponses(
@ -419,8 +422,12 @@ public class ReportingTaskResource extends ApplicationResource {
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
Authorizable authorizable = lookup.getReportingTask(id); // authorize reporting task
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTask(id);
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// authorize any referenced services
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTaskDTO.getProperties(), authorizable, authorizer, lookup);
}, },
() -> serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO), () -> serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO),
() -> { () -> {
@ -493,7 +500,7 @@ public class ReportingTaskResource extends ApplicationResource {
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
final Authorizable reportingTask = lookup.getReportingTask(id); final Authorizable reportingTask = lookup.getReportingTask(id).getAuthorizable();
reportingTask.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); reportingTask.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}, },
() -> serviceFacade.verifyDeleteReportingTask(id), () -> serviceFacade.verifyDeleteReportingTask(id),

View File

@ -43,9 +43,11 @@ import org.apache.nifi.controller.ProcessorNode;
import org.apache.nifi.controller.ReportingTaskNode; import org.apache.nifi.controller.ReportingTaskNode;
import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.controller.ScheduledState;
import org.apache.nifi.controller.Template; import org.apache.nifi.controller.Template;
import org.apache.nifi.controller.exception.ProcessorInstantiationException;
import org.apache.nifi.controller.label.Label; import org.apache.nifi.controller.label.Label;
import org.apache.nifi.controller.queue.FlowFileQueue; import org.apache.nifi.controller.queue.FlowFileQueue;
import org.apache.nifi.controller.queue.QueueSize; import org.apache.nifi.controller.queue.QueueSize;
import org.apache.nifi.controller.reporting.ReportingTaskInstantiationException;
import org.apache.nifi.controller.repository.ContentNotFoundException; import org.apache.nifi.controller.repository.ContentNotFoundException;
import org.apache.nifi.controller.repository.claim.ContentDirection; import org.apache.nifi.controller.repository.claim.ContentDirection;
import org.apache.nifi.controller.service.ControllerServiceNode; import org.apache.nifi.controller.service.ControllerServiceNode;
@ -126,6 +128,7 @@ import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -189,6 +192,38 @@ public class ControllerFacade implements Authorizable {
flowController.setComments(comments); flowController.setComments(comments);
} }
/**
* Create a temporary Processor used for extracting PropertyDescriptor's for ControllerService reference authorization.
*
* @param type type of processor
* @return processor
* @throws ProcessorInstantiationException when unable to instantiate the processor
*/
public ProcessorNode createTemporaryProcessor(String type) throws ProcessorInstantiationException {
return flowController.createProcessor(type, UUID.randomUUID().toString(), false);
}
/**
* Create a temporary ReportingTask used for extracting PropertyDescriptor's for ControllerService reference authorization.
*
* @param type type of reporting task
* @return reporting task
* @throws ReportingTaskInstantiationException when unable to instantiate the reporting task
*/
public ReportingTaskNode createTemporaryReportingTask(String type) throws ReportingTaskInstantiationException {
return flowController.createReportingTask(type, UUID.randomUUID().toString(), false);
}
/**
* Create a temporary ControllerService used for extracting PropertyDescriptor's for ControllerService reference authorization.
*
* @param type type of controller service
* @return controller service
*/
public ControllerServiceNode createTemporaryControllerService(String type) {
return flowController.createControllerService(type, UUID.randomUUID().toString(), false);
}
/** /**
* Sets the max timer driven thread count of this controller. * Sets the max timer driven thread count of this controller.
* *

View File

@ -77,6 +77,10 @@ div.selected-disabled-option {
padding: 0px 10px; padding: 0px 10px;
} }
.combo-options ul > li.disabled {
font-style: italic;
}
.combo-option-text { .combo-option-text {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;

View File

@ -118,30 +118,6 @@
}; };
var setDisabled = function (combo, optionElement, option, disabled) {
// reset the option element
optionElement.removeClass('unset').off('click');
if (disabled === true) {
optionElement.addClass('unset');
} else {
optionElement.on('click', function () {
//remove active styles
$('.combo').removeClass('combo-open');
// select the option
selectOption(combo, option.text, option.value);
// click the glass pane which will hide the options
$('.combo-glass-pane').click();
}).hover(function () {
$(this).addClass('pointer').css('background', '#eaeef0');
}, function () {
$(this).removeClass('pointer').css('background', '#ffffff');
});
}
};
var methods = { var methods = {
/** /**
@ -212,7 +188,7 @@
// this is option is enabled register appropriate listeners // this is option is enabled register appropriate listeners
if (option.disabled === true) { if (option.disabled === true) {
optionElement.addClass('unset'); optionElement.addClass('unset disabled');
} else { } else {
optionElement.click(function () { optionElement.click(function () {
//remove active styles //remove active styles

View File

@ -530,6 +530,7 @@
options.push({ options.push({
text: allowableValue.displayName, text: allowableValue.displayName,
value: allowableValue.value, value: allowableValue.value,
disabled: allowableValueEntity.canRead === false && allowableValue.value !== args.item['previousValue'],
description: nf.Common.escapeHtml(allowableValue.description) description: nf.Common.escapeHtml(allowableValue.description)
}); });
}); });