NIFI-2301: - Ensure all component specific policies are removed when the component is removed. - Allowing snippets to be created if the user has read or write access as we don't know what the intended snippet usage. When used the snippet is still authorized accordingly. - Ensuring actions involving Process Groups correctly authorize encapsulated components. - Not requiring read permissions when showing the delete button for Controller Services and Reporting Tasks.

This closes #757

Signed-off-by: jpercivall <joepercivall@yahoo.com>
This commit is contained in:
Matt Gilman 2016-08-01 10:52:11 -04:00 committed by jpercivall
parent 9338f102cb
commit 1511887a68
15 changed files with 328 additions and 113 deletions

View File

@ -671,6 +671,13 @@ public interface ProcessGroup extends Authorizable, Positionable {
*/ */
void removeFunnel(Funnel funnel); void removeFunnel(Funnel funnel);
/**
* @return a List of all Funnel that are children or descendants of this
* ProcessGroup. This performs a recursive search of all descendant
* ProcessGroups
*/
List<Funnel> findAllFunnels();
/** /**
* Adds the given Controller Service to this group * Adds the given Controller Service to this group
* *

View File

@ -1578,6 +1578,19 @@ public final class StandardProcessGroup implements ProcessGroup {
return allOutputPorts; return allOutputPorts;
} }
@Override
public List<Funnel> findAllFunnels() {
return findAllFunnels(this);
}
private List<Funnel> findAllFunnels(final ProcessGroup start) {
final List<Funnel> allFunnels = new ArrayList<>(start.getFunnels());
for (final ProcessGroup group : start.getProcessGroups()) {
allFunnels.addAll(findAllFunnels(group));
}
return allFunnels;
}
@Override @Override
public Port getInputPortByName(final String name) { public Port getInputPortByName(final String name) {
return getPortByName(name, this, new InputPortRetriever()); return getPortByName(name, this, new InputPortRetriever());

View File

@ -461,6 +461,11 @@ public class MockProcessGroup implements ProcessGroup {
return null; return null;
} }
@Override
public List<Funnel> findAllFunnels() {
return null;
}
@Override @Override
public void removeFunnel(final Funnel funnel) { public void removeFunnel(final Funnel funnel) {

View File

@ -80,7 +80,7 @@ public interface AuthorizableLookup {
* @param id process group id * @param id process group id
* @return authorizable * @return authorizable
*/ */
Authorizable getProcessGroup(String id); ProcessGroupAuthorizable getProcessGroup(String id);
/** /**
* Get the authorizable RemoteProcessGroup. * Get the authorizable RemoteProcessGroup.

View File

@ -0,0 +1,40 @@
/*
* 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 java.util.Set;
/**
* Authorizable for a ProcessGroup and its encapsulated components.
*/
public interface ProcessGroupAuthorizable {
/**
* Returns the authorizable for this ProcessGroup. Non null
*
* @return authorizable
*/
Authorizable getAuthorizable();
/**
* The authorizables for all encapsulated components. Non null
*
* @return all encapsulated authorizables
*/
Set<Authorizable> getEncapsulatedAuthorizables();
}

View File

@ -19,8 +19,8 @@ package org.apache.nifi.authorization;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.resource.AccessPolicyAuthorizable; import org.apache.nifi.authorization.resource.AccessPolicyAuthorizable;
import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
import org.apache.nifi.authorization.resource.DataAuthorizable; import org.apache.nifi.authorization.resource.DataAuthorizable;
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
import org.apache.nifi.authorization.resource.ResourceFactory; import org.apache.nifi.authorization.resource.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;
@ -47,6 +47,10 @@ import org.apache.nifi.web.dao.ReportingTaskDAO;
import org.apache.nifi.web.dao.SnippetDAO; import org.apache.nifi.web.dao.SnippetDAO;
import org.apache.nifi.web.dao.TemplateDAO; import org.apache.nifi.web.dao.TemplateDAO;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
class StandardAuthorizableLookup implements AuthorizableLookup { class StandardAuthorizableLookup implements AuthorizableLookup {
@ -152,8 +156,32 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
} }
@Override @Override
public Authorizable getProcessGroup(final String id) { public ProcessGroupAuthorizable getProcessGroup(final String id) {
return processGroupDAO.getProcessGroup(id); final ProcessGroup processGroup = processGroupDAO.getProcessGroup(id);
final Set<Authorizable> encapsulatedAuthorizables = new HashSet<>();
processGroup.findAllProcessors().forEach(processor -> encapsulatedAuthorizables.add(processor));
processGroup.findAllConnections().forEach(connection -> encapsulatedAuthorizables.add(connection));
processGroup.findAllInputPorts().forEach(inputPort -> encapsulatedAuthorizables.add(inputPort));
processGroup.findAllOutputPorts().forEach(outputPort -> encapsulatedAuthorizables.add(outputPort));
processGroup.findAllFunnels().forEach(funnel -> encapsulatedAuthorizables.add(funnel));
processGroup.findAllLabels().forEach(label -> encapsulatedAuthorizables.add(label));
processGroup.findAllProcessGroups().forEach(childGroup -> encapsulatedAuthorizables.add(childGroup));
processGroup.findAllRemoteProcessGroups().forEach(remoteProcessGroup -> encapsulatedAuthorizables.add(remoteProcessGroup));
processGroup.findAllTemplates().forEach(template -> encapsulatedAuthorizables.add(template));
processGroup.findAllControllerServices().forEach(controllerService -> encapsulatedAuthorizables.add(controllerService));
return new ProcessGroupAuthorizable() {
@Override
public Authorizable getAuthorizable() {
return processGroup;
}
@Override
public Set<Authorizable> getEncapsulatedAuthorizables() {
return Collections.unmodifiableSet(encapsulatedAuthorizables);
}
};
} }
@Override @Override
@ -334,7 +362,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
authorizable = getProcessor(componentId); authorizable = getProcessor(componentId);
break; break;
case ProcessGroup: case ProcessGroup:
authorizable = getProcessGroup(componentId); authorizable = getProcessGroup(componentId).getAuthorizable();
break; break;
case RemoteProcessGroup: case RemoteProcessGroup:
authorizable = getRemoteProcessGroup(componentId); authorizable = getRemoteProcessGroup(componentId);

View File

@ -850,9 +850,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Connection connection = connectionDAO.getConnection(connectionId); final Connection connection = connectionDAO.getConnection(connectionId);
final ConnectionDTO snapshot = deleteComponent( final ConnectionDTO snapshot = deleteComponent(
revision, revision,
connection.getResource().getIdentifier(), connection.getResource(),
() -> connectionDAO.deleteConnection(connectionId), () -> connectionDAO.deleteConnection(connectionId),
false, false, // no policies to remove
dtoFactory.createConnectionDto(connection)); dtoFactory.createConnectionDto(connection));
return entityFactory.createConnectionEntity(snapshot, null, null, null); return entityFactory.createConnectionEntity(snapshot, null, null, null);
@ -884,7 +884,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final ProcessorNode processor = processorDAO.getProcessor(processorId); final ProcessorNode processor = processorDAO.getProcessor(processorId);
final ProcessorDTO snapshot = deleteComponent( final ProcessorDTO snapshot = deleteComponent(
revision, revision,
processor.getResource().getIdentifier(), processor.getResource(),
() -> processorDAO.deleteProcessor(processorId), () -> processorDAO.deleteProcessor(processorId),
true, true,
dtoFactory.createProcessorDto(processor)); dtoFactory.createProcessorDto(processor));
@ -897,7 +897,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Label label = labelDAO.getLabel(labelId); final Label label = labelDAO.getLabel(labelId);
final LabelDTO snapshot = deleteComponent( final LabelDTO snapshot = deleteComponent(
revision, revision,
label.getResource().getIdentifier(), label.getResource(),
() -> labelDAO.deleteLabel(labelId), () -> labelDAO.deleteLabel(labelId),
true, true,
dtoFactory.createLabelDto(label)); dtoFactory.createLabelDto(label));
@ -916,7 +916,17 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final String resourceIdentifier = ResourceFactory.getTenantResource().getIdentifier() + "/" + userId; final String resourceIdentifier = ResourceFactory.getTenantResource().getIdentifier() + "/" + userId;
final UserDTO snapshot = deleteComponent( final UserDTO snapshot = deleteComponent(
revision, revision,
resourceIdentifier, new Resource() {
@Override
public String getIdentifier() {
return resourceIdentifier;
}
@Override
public String getName() {
return resourceIdentifier;
}
},
() -> userDAO.deleteUser(userId), () -> userDAO.deleteUser(userId),
false, // no user specific policies to remove false, // no user specific policies to remove
dtoFactory.createUserDto(user, userGroups, policyEntities)); dtoFactory.createUserDto(user, userGroups, policyEntities));
@ -934,7 +944,17 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final String resourceIdentifier = ResourceFactory.getTenantResource().getIdentifier() + "/" + userGroupId; final String resourceIdentifier = ResourceFactory.getTenantResource().getIdentifier() + "/" + userGroupId;
final UserGroupDTO snapshot = deleteComponent( final UserGroupDTO snapshot = deleteComponent(
revision, revision,
resourceIdentifier, new Resource() {
@Override
public String getIdentifier() {
return resourceIdentifier;
}
@Override
public String getName() {
return resourceIdentifier;
}
},
() -> userGroupDAO.deleteUserGroup(userGroupId), () -> userGroupDAO.deleteUserGroup(userGroupId),
false, // no user group specific policies to remove false, // no user group specific policies to remove
dtoFactory.createUserGroupDto(userGroup, users)); dtoFactory.createUserGroupDto(userGroup, users));
@ -949,7 +969,17 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null; final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null;
final AccessPolicyDTO snapshot = deleteComponent( final AccessPolicyDTO snapshot = deleteComponent(
revision, revision,
accessPolicy.getResource(), new Resource() {
@Override
public String getIdentifier() {
return accessPolicy.getResource();
}
@Override
public String getName() {
return accessPolicy.getResource();
}
},
() -> accessPolicyDAO.deleteAccessPolicy(accessPolicyId), () -> accessPolicyDAO.deleteAccessPolicy(accessPolicyId),
false, // no need to clean up any policies as it's already been removed above false, // no need to clean up any policies as it's already been removed above
dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, dtoFactory.createAccessPolicyDto(accessPolicy, userGroups,
@ -963,7 +993,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Funnel funnel = funnelDAO.getFunnel(funnelId); final Funnel funnel = funnelDAO.getFunnel(funnelId);
final FunnelDTO snapshot = deleteComponent( final FunnelDTO snapshot = deleteComponent(
revision, revision,
funnel.getResource().getIdentifier(), funnel.getResource(),
() -> funnelDAO.deleteFunnel(funnelId), () -> funnelDAO.deleteFunnel(funnelId),
true, true,
dtoFactory.createFunnelDto(funnel)); dtoFactory.createFunnelDto(funnel));
@ -975,50 +1005,30 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
* Deletes a component using the Optimistic Locking Manager * Deletes a component using the Optimistic Locking Manager
* *
* @param revision the current revision * @param revision the current revision
* @param resourceIdentifier the identifier of the resource being removed * @param resource the resource being removed
* @param deleteAction the action that deletes the component via the appropriate DAO object * @param deleteAction the action that deletes the component via the appropriate DAO object
* @param cleanUpPolicies whether or not the policies for this resource should be removed as well - not necessary when there are * @param cleanUpPolicies whether or not the policies for this resource should be removed as well - not necessary when there are
* no component specific policies or if the policies of the component are inherited * no component specific policies or if the policies of the component are inherited
* @return a dto that represents the new configuration * @return a dto that represents the new configuration
*/ */
private <D, C> D deleteComponent(final Revision revision, final String resourceIdentifier, final Runnable deleteAction, final boolean cleanUpPolicies, final D dto) { private <D, C> D deleteComponent(final Revision revision, final Resource resource, final Runnable deleteAction, final boolean cleanUpPolicies, final D dto) {
final RevisionClaim claim = new StandardRevisionClaim(revision); final RevisionClaim claim = new StandardRevisionClaim(revision);
final NiFiUser user = NiFiUserUtils.getNiFiUser(); final NiFiUser user = NiFiUserUtils.getNiFiUser();
return revisionManager.deleteRevision(claim, user, new DeleteRevisionTask<D>() { return revisionManager.deleteRevision(claim, user, new DeleteRevisionTask<D>() {
@Override @Override
public D performTask() { public D performTask() {
logger.debug("Attempting to delete component {} with claim {}", resourceIdentifier, claim); logger.debug("Attempting to delete component {} with claim {}", resource.getIdentifier(), claim);
// run the delete action // run the delete action
deleteAction.run(); deleteAction.run();
// save the flow // save the flow
controllerFacade.save(); controllerFacade.save();
logger.debug("Deletion of component {} was successful", resourceIdentifier); logger.debug("Deletion of component {} was successful", resource.getIdentifier());
// clean up the policy if necessary and configured with a policy based authorizer if (cleanUpPolicies) {
if (cleanUpPolicies && accessPolicyDAO.supportsConfigurableAuthorizer()) { cleanUpPolicies(resource);
try {
// since the component is being deleted, also delete any relevant read access policies
final AccessPolicy readPolicy = accessPolicyDAO.getAccessPolicy(RequestAction.READ, resourceIdentifier);
if (readPolicy != null) {
accessPolicyDAO.deleteAccessPolicy(readPolicy.getIdentifier());
}
} catch (final Exception e) {
logger.warn(String.format("Unable to remove access policy for %s %s after component removal.", RequestAction.READ, resourceIdentifier), e);
}
try {
// since the component is being deleted, also delete any relevant write access policies
final AccessPolicy writePolicy = accessPolicyDAO.getAccessPolicy(RequestAction.WRITE, resourceIdentifier);
if (writePolicy != null) {
accessPolicyDAO.deleteAccessPolicy(writePolicy.getIdentifier());
}
} catch (final ResourceNotFoundException e) {
// no policy exists for this component... no worries
} catch (final Exception e) {
logger.warn(String.format("Unable to remove access policy for %s %s after component removal.", RequestAction.WRITE, resourceIdentifier), e);
}
} }
return dto; return dto;
@ -1026,6 +1036,36 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}); });
} }
/**
* Clean up the policies for the specified component resource.
*
* @param componentResource the resource for the component
*/
private void cleanUpPolicies(final Resource componentResource) {
// ensure the authorizer supports configuration
if (accessPolicyDAO.supportsConfigurableAuthorizer()) {
final List<Resource> resources = new ArrayList<>();
resources.add(componentResource);
resources.add(ResourceFactory.getDataResource(componentResource));
resources.add(ResourceFactory.getDataTransferResource(componentResource));
resources.add(ResourceFactory.getPolicyResource(componentResource));
for (final Resource resource : resources) {
for (final RequestAction action : RequestAction.values()) {
try {
// since the component is being deleted, also delete any relevant access policies
final AccessPolicy readPolicy = accessPolicyDAO.getAccessPolicy(action, resource.getIdentifier());
if (readPolicy != null) {
accessPolicyDAO.deleteAccessPolicy(readPolicy.getIdentifier());
}
} catch (final Exception e) {
logger.warn(String.format("Unable to remove access policy for %s %s after component removal.", action, resource.getIdentifier()), e);
}
}
}
}
}
@Override @Override
public void verifyDeleteSnippet(final String snippetId, final Set<String> affectedComponentIds) { public void verifyDeleteSnippet(final String snippetId, final Set<String> affectedComponentIds) {
snippetDAO.verifyDeleteSnippetComponents(snippetId); snippetDAO.verifyDeleteSnippetComponents(snippetId);
@ -1035,6 +1075,32 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public SnippetEntity deleteSnippet(final Set<Revision> revisions, final String snippetId) { public SnippetEntity deleteSnippet(final Set<Revision> revisions, final String snippetId) {
final Snippet snippet = snippetDAO.getSnippet(snippetId); final Snippet snippet = snippetDAO.getSnippet(snippetId);
// grab the resources in the snippet so we can delete the policies afterwards
final Set<Resource> snippetResources = new HashSet<>();
snippet.getProcessors().keySet().forEach(id -> snippetResources.add(processorDAO.getProcessor(id).getResource()));
snippet.getInputPorts().keySet().forEach(id -> snippetResources.add(inputPortDAO.getPort(id).getResource()));
snippet.getOutputPorts().keySet().forEach(id -> snippetResources.add(outputPortDAO.getPort(id).getResource()));
snippet.getFunnels().keySet().forEach(id -> snippetResources.add(funnelDAO.getFunnel(id).getResource()));
snippet.getLabels().keySet().forEach(id -> snippetResources.add(labelDAO.getLabel(id).getResource()));
snippet.getRemoteProcessGroups().keySet().forEach(id -> snippetResources.add(remoteProcessGroupDAO.getRemoteProcessGroup(id).getResource()));
snippet.getProcessGroups().keySet().forEach(id -> {
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(id);
// add the process group
snippetResources.add(processGroup.getResource());
// add each encapsulated component
processGroup.findAllProcessors().forEach(processor -> snippetResources.add(processor.getResource()));
processGroup.findAllInputPorts().forEach(inputPort -> snippetResources.add(inputPort.getResource()));
processGroup.findAllOutputPorts().forEach(outputPort -> snippetResources.add(outputPort.getResource()));
processGroup.findAllFunnels().forEach(funnel -> snippetResources.add(funnel.getResource()));
processGroup.findAllLabels().forEach(label -> snippetResources.add(label.getResource()));
processGroup.findAllProcessGroups().forEach(childGroup -> snippetResources.add(childGroup.getResource()));
processGroup.findAllRemoteProcessGroups().forEach(remoteProcessGroup -> snippetResources.add(remoteProcessGroup.getResource()));
processGroup.findAllTemplates().forEach(template -> snippetResources.add(template.getResource()));
processGroup.findAllControllerServices().forEach(controllerService -> snippetResources.add(controllerService.getResource()));
});
final NiFiUser user = NiFiUserUtils.getNiFiUser(); final NiFiUser user = NiFiUserUtils.getNiFiUser();
final RevisionClaim claim = new StandardRevisionClaim(revisions); final RevisionClaim claim = new StandardRevisionClaim(revisions);
final SnippetDTO dto = revisionManager.deleteRevision(claim, user, new DeleteRevisionTask<SnippetDTO>() { final SnippetDTO dto = revisionManager.deleteRevision(claim, user, new DeleteRevisionTask<SnippetDTO>() {
@ -1054,6 +1120,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
} }
}); });
// clean up component policies
snippetResources.forEach(resource -> cleanUpPolicies(resource));
return entityFactory.createSnippetEntity(dto); return entityFactory.createSnippetEntity(dto);
} }
@ -1062,7 +1131,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Port port = inputPortDAO.getPort(inputPortId); final Port port = inputPortDAO.getPort(inputPortId);
final PortDTO snapshot = deleteComponent( final PortDTO snapshot = deleteComponent(
revision, revision,
port.getResource().getIdentifier(), port.getResource(),
() -> inputPortDAO.deletePort(inputPortId), () -> inputPortDAO.deletePort(inputPortId),
true, true,
dtoFactory.createPortDto(port)); dtoFactory.createPortDto(port));
@ -1075,7 +1144,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Port port = outputPortDAO.getPort(outputPortId); final Port port = outputPortDAO.getPort(outputPortId);
final PortDTO snapshot = deleteComponent( final PortDTO snapshot = deleteComponent(
revision, revision,
port.getResource().getIdentifier(), port.getResource(),
() -> outputPortDAO.deletePort(outputPortId), () -> outputPortDAO.deletePort(outputPortId),
true, true,
dtoFactory.createPortDto(port)); dtoFactory.createPortDto(port));
@ -1086,13 +1155,29 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override @Override
public ProcessGroupEntity deleteProcessGroup(final Revision revision, final String groupId) { public ProcessGroupEntity deleteProcessGroup(final Revision revision, final String groupId) {
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId);
// grab the resources in the snippet so we can delete the policies afterwards
final Set<Resource> groupResources = new HashSet<>();
processGroup.findAllProcessors().forEach(processor -> groupResources.add(processor.getResource()));
processGroup.findAllInputPorts().forEach(inputPort -> groupResources.add(inputPort.getResource()));
processGroup.findAllOutputPorts().forEach(outputPort -> groupResources.add(outputPort.getResource()));
processGroup.findAllFunnels().forEach(funnel -> groupResources.add(funnel.getResource()));
processGroup.findAllLabels().forEach(label -> groupResources.add(label.getResource()));
processGroup.findAllProcessGroups().forEach(childGroup -> groupResources.add(childGroup.getResource()));
processGroup.findAllRemoteProcessGroups().forEach(remoteProcessGroup -> groupResources.add(remoteProcessGroup.getResource()));
processGroup.findAllTemplates().forEach(template -> groupResources.add(template.getResource()));
processGroup.findAllControllerServices().forEach(controllerService -> groupResources.add(controllerService.getResource()));
final ProcessGroupDTO snapshot = deleteComponent( final ProcessGroupDTO snapshot = deleteComponent(
revision, revision,
processGroup.getResource().getIdentifier(), processGroup.getResource(),
() -> processGroupDAO.deleteProcessGroup(groupId), () -> processGroupDAO.deleteProcessGroup(groupId),
true, true,
dtoFactory.createProcessGroupDto(processGroup)); dtoFactory.createProcessGroupDto(processGroup));
// delete all applicable component policies
groupResources.forEach(groupResource -> cleanUpPolicies(groupResource));
return entityFactory.createProcessGroupEntity(snapshot, null, null, null, null); return entityFactory.createProcessGroupEntity(snapshot, null, null, null, null);
} }
@ -1101,7 +1186,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId); final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId);
final RemoteProcessGroupDTO snapshot = deleteComponent( final RemoteProcessGroupDTO snapshot = deleteComponent(
revision, revision,
remoteProcessGroup.getResource().getIdentifier(), remoteProcessGroup.getResource(),
() -> remoteProcessGroupDAO.deleteRemoteProcessGroup(remoteProcessGroupId), () -> remoteProcessGroupDAO.deleteRemoteProcessGroup(remoteProcessGroupId),
true, true,
dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup)); dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup));
@ -1740,7 +1825,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId); final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId);
final ControllerServiceDTO snapshot = deleteComponent( final ControllerServiceDTO snapshot = deleteComponent(
revision, revision,
controllerService.getResource().getIdentifier(), controllerService.getResource(),
() -> controllerServiceDAO.deleteControllerService(controllerServiceId), () -> controllerServiceDAO.deleteControllerService(controllerServiceId),
true, true,
dtoFactory.createControllerServiceDto(controllerService)); dtoFactory.createControllerServiceDto(controllerService));
@ -1794,7 +1879,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId); final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId);
final ReportingTaskDTO snapshot = deleteComponent( final ReportingTaskDTO snapshot = deleteComponent(
revision, revision,
reportingTask.getResource().getIdentifier(), reportingTask.getResource(),
() -> reportingTaskDAO.deleteReportingTask(reportingTaskId), () -> reportingTaskDAO.deleteReportingTask(reportingTaskId),
true, true,
dtoFactory.createReportingTaskDto(reportingTask)); dtoFactory.createReportingTaskDto(reportingTask));
@ -2693,7 +2778,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
authorizable = authorizableLookup.getOutputPort(sourceId); authorizable = authorizableLookup.getOutputPort(sourceId);
break; break;
case ProcessGroup: case ProcessGroup:
authorizable = authorizableLookup.getProcessGroup(sourceId); authorizable = authorizableLookup.getProcessGroup(sourceId).getAuthorizable();
break; break;
case RemoteProcessGroup: case RemoteProcessGroup:
authorizable = authorizableLookup.getRemoteProcessGroup(sourceId); authorizable = authorizableLookup.getRemoteProcessGroup(sourceId);

View File

@ -21,6 +21,8 @@ import com.sun.jersey.api.representation.Form;
import com.sun.jersey.core.util.MultivaluedMapImpl; import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider; import com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AuthorizableLookup;
import org.apache.nifi.authorization.AuthorizeAccess;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
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;
@ -40,10 +42,8 @@ import org.apache.nifi.remote.exception.HandshakeException;
import org.apache.nifi.remote.exception.NotAuthorizedException; import org.apache.nifi.remote.exception.NotAuthorizedException;
import org.apache.nifi.remote.protocol.ResponseCode; import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.remote.protocol.http.HttpHeaders; import org.apache.nifi.remote.protocol.http.HttpHeaders;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.util.ComponentIdGenerator; import org.apache.nifi.util.ComponentIdGenerator;
import org.apache.nifi.authorization.AuthorizableLookup; import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.authorization.AuthorizeAccess;
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.RevisionDTO; import org.apache.nifi.web.api.dto.RevisionDTO;
@ -418,7 +418,13 @@ public abstract class ApplicationResource {
protected void authorizeSnippet(final Snippet snippet, final Authorizer authorizer, final AuthorizableLookup lookup, final RequestAction action) { protected void authorizeSnippet(final Snippet snippet, final Authorizer authorizer, final AuthorizableLookup lookup, final RequestAction action) {
final Consumer<Authorizable> authorize = authorizable -> authorizable.authorize(authorizer, action, NiFiUserUtils.getNiFiUser()); final Consumer<Authorizable> authorize = authorizable -> authorizable.authorize(authorizer, action, NiFiUserUtils.getNiFiUser());
snippet.getProcessGroups().keySet().stream().map(id -> lookup.getProcessGroup(id)).forEach(authorize); snippet.getProcessGroups().keySet().stream().map(id -> lookup.getProcessGroup(id)).forEach(processGroupAuthorizable -> {
// authorize the process group
authorize.accept(processGroupAuthorizable.getAuthorizable());
// authorize the contents of the group
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)).forEach(authorize);
snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize); snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize);
@ -437,7 +443,13 @@ public abstract class ApplicationResource {
protected void authorizeSnippet(final SnippetDTO snippet, final Authorizer authorizer, final AuthorizableLookup lookup, final RequestAction action) { protected void authorizeSnippet(final SnippetDTO snippet, final Authorizer authorizer, final AuthorizableLookup lookup, final RequestAction action) {
final Consumer<Authorizable> authorize = authorizable -> authorizable.authorize(authorizer, action, NiFiUserUtils.getNiFiUser()); final Consumer<Authorizable> authorize = authorizable -> authorizable.authorize(authorizer, action, NiFiUserUtils.getNiFiUser());
snippet.getProcessGroups().keySet().stream().map(id -> lookup.getProcessGroup(id)).forEach(authorize); snippet.getProcessGroups().keySet().stream().map(id -> lookup.getProcessGroup(id)).forEach(processGroupAuthorizable -> {
// authorize the process group
authorize.accept(processGroupAuthorizable.getAuthorizable());
// authorize the contents of the group
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)).forEach(authorize);
snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize); snippet.getInputPorts().keySet().stream().map(id -> lookup.getInputPort(id)).forEach(authorize);

View File

@ -96,9 +96,7 @@ public class ControllerServiceResource extends ApplicationResource {
*/ */
public Set<ControllerServiceEntity> populateRemainingControllerServiceEntitiesContent(final Set<ControllerServiceEntity> controllerServiceEntities) { public Set<ControllerServiceEntity> populateRemainingControllerServiceEntitiesContent(final Set<ControllerServiceEntity> controllerServiceEntities) {
for (ControllerServiceEntity controllerServiceEntity : controllerServiceEntities) { for (ControllerServiceEntity controllerServiceEntity : controllerServiceEntities) {
if (controllerServiceEntity.getComponent() != null) { populateRemainingControllerServiceEntityContent(controllerServiceEntity);
populateRemainingControllerServiceEntityContent(controllerServiceEntity);
}
} }
return controllerServiceEntities; return controllerServiceEntities;
} }

View File

@ -25,13 +25,15 @@ 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.AuthorizableLookup;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
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;
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.cluster.protocol.NodeIdentifier; import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.controller.Snippet; import org.apache.nifi.controller.Snippet;
import org.apache.nifi.authorization.AuthorizableLookup;
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.ConnectionDTO; import org.apache.nifi.web.api.dto.ConnectionDTO;
@ -208,7 +210,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -285,17 +287,17 @@ public class ProcessGroupResource extends ApplicationResource {
// handle expects request (usually from the cluster manager) // handle expects request (usually from the cluster manager)
final Revision revision = getRevision(processGroupEntity, id); final Revision revision = getRevision(processGroupEntity, id);
return withWriteLock( return withWriteLock(
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
Authorizable authorizable = lookup.getProcessGroup(id); Authorizable authorizable = lookup.getProcessGroup(id).getAuthorizable();
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}, },
null, null,
() -> { () -> {
// update the process group // update the process group
final ProcessGroupEntity entity = serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO); final ProcessGroupEntity entity = serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO);
populateRemainingProcessGroupEntityContent(entity); populateRemainingProcessGroupEntityContent(entity);
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
} }
@ -357,16 +359,25 @@ public class ProcessGroupResource extends ApplicationResource {
// handle expects request (usually from the cluster manager) // handle expects request (usually from the cluster manager)
final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); final Revision revision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id);
return withWriteLock( return withWriteLock(
serviceFacade, serviceFacade,
revision, revision,
lookup -> { lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(id); final NiFiUser user = NiFiUserUtils.getNiFiUser();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); final ProcessGroupAuthorizable processGroupAuthorizable = lookup.getProcessGroup(id);
},
() -> serviceFacade.verifyDeleteProcessGroup(id), // ensure write to the process group
() -> { final Authorizable processGroup = processGroupAuthorizable.getAuthorizable();
// delete the process group processGroup.authorize(authorizer, RequestAction.WRITE, user);
final ProcessGroupEntity entity = serviceFacade.deleteProcessGroup(revision, id);
// ensure write to all encapsulated components
processGroupAuthorizable.getEncapsulatedAuthorizables().forEach(encaupsulatedAuthorizable -> {
encaupsulatedAuthorizable.authorize(authorizer, RequestAction.WRITE, user);
});
},
() -> serviceFacade.verifyDeleteProcessGroup(id),
() -> {
// delete the process group
final ProcessGroupEntity entity = serviceFacade.deleteProcessGroup(revision, id);
// create the response // create the response
return clusterContext(generateOkResponse(entity)).build(); return clusterContext(generateOkResponse(entity)).build();
@ -441,7 +452,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -500,7 +511,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -597,7 +608,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -657,7 +668,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -743,7 +754,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -801,7 +812,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -886,7 +897,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -944,7 +955,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -1030,7 +1041,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -1088,7 +1099,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -1174,7 +1185,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -1232,7 +1243,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -1324,7 +1335,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -1407,7 +1418,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -1514,7 +1525,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
// ensure write access to the group // ensure write access to the group
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// ensure write access to the source // ensure write access to the source
@ -1582,7 +1593,7 @@ public class ProcessGroupResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
}); });
@ -1751,7 +1762,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
final Authorizable template = lookup.getTemplate(instantiateTemplateRequestEntity.getTemplateId()); final Authorizable template = lookup.getTemplate(instantiateTemplateRequestEntity.getTemplateId());
@ -1786,7 +1797,7 @@ public class ProcessGroupResource extends ApplicationResource {
private void authorizeSnippetUsage(final AuthorizableLookup lookup, final String groupId, final String snippetId) { private void authorizeSnippetUsage(final AuthorizableLookup lookup, final String groupId, final String snippetId) {
// ensure write access to the target process group // ensure write access to the target process group
lookup.getProcessGroup(groupId).authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); lookup.getProcessGroup(groupId).getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// ensure read permission to every component in the snippet // ensure read permission to every component in the snippet
final Snippet snippet = lookup.getSnippet(snippetId); final Snippet snippet = lookup.getSnippet(snippetId);
@ -2005,7 +2016,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }
@ -2110,7 +2121,7 @@ public class ProcessGroupResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) { if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId); final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
}); });
} }

View File

@ -84,9 +84,7 @@ public class ReportingTaskResource extends ApplicationResource {
*/ */
public Set<ReportingTaskEntity> populateRemainingReportingTaskEntitiesContent(final Set<ReportingTaskEntity> reportingTaskEntities) { public Set<ReportingTaskEntity> populateRemainingReportingTaskEntitiesContent(final Set<ReportingTaskEntity> reportingTaskEntities) {
for (ReportingTaskEntity reportingTaskEntity : reportingTaskEntities) { for (ReportingTaskEntity reportingTaskEntity : reportingTaskEntities) {
if (reportingTaskEntity.getComponent() != null) { populateRemainingReportingTaskEntityContent(reportingTaskEntity);
populateRemainingReportingTaskEntityContent(reportingTaskEntity);
}
} }
return reportingTaskEntities; return reportingTaskEntities;
} }

View File

@ -22,6 +22,7 @@ import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse; 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.nifi.authorization.AccessDeniedException;
import org.apache.nifi.authorization.Authorizer; import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.user.NiFiUserUtils; import org.apache.nifi.authorization.user.NiFiUserUtils;
@ -141,7 +142,18 @@ public class SnippetResource extends ApplicationResource {
// authorize access // authorize access
serviceFacade.authorizeAccess(lookup -> { serviceFacade.authorizeAccess(lookup -> {
final SnippetDTO snippet = snippetEntity.getSnippet(); final SnippetDTO snippet = snippetEntity.getSnippet();
authorizeSnippet(snippet, authorizer, lookup, RequestAction.READ);
// the snippet being created may be used later for batch component modifications,
// copy/paste, or template creation. during those subsequent actions, the snippet
// will again be authorized accordingly (read or write). at this point we do not
// know what the snippet will be used for so we need to attempt to authorize as
// read OR write
try {
authorizeSnippet(snippet, authorizer, lookup, RequestAction.READ);
} catch (final AccessDeniedException e) {
authorizeSnippet(snippet, authorizer, lookup, RequestAction.WRITE);
}
}); });
} }
if (validationPhase) { if (validationPhase) {
@ -218,13 +230,13 @@ public class SnippetResource extends ApplicationResource {
// get the revision from this snippet // get the revision from this snippet
final Set<Revision> revisions = serviceFacade.getRevisionsFromSnippet(snippetId); final Set<Revision> revisions = serviceFacade.getRevisionsFromSnippet(snippetId);
return withWriteLock( return withWriteLock(
serviceFacade, serviceFacade,
revisions, revisions,
lookup -> { lookup -> {
// ensure write access to the target process group // ensure write access to the target process group
if (requestSnippetDTO.getParentGroupId() != null) { if (requestSnippetDTO.getParentGroupId() != null) {
lookup.getProcessGroup(requestSnippetDTO.getParentGroupId()).authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); lookup.getProcessGroup(requestSnippetDTO.getParentGroupId()).getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
} }
// ensure write permission to every component in the snippet // ensure write permission to every component in the snippet
final Snippet snippet = lookup.getSnippet(snippetId); final Snippet snippet = lookup.getSnippet(snippetId);

View File

@ -2019,7 +2019,9 @@ nf.ControllerService = (function () {
controllerServiceData.deleteItem(controllerServiceEntity.id); controllerServiceData.deleteItem(controllerServiceEntity.id);
// reload the as necessary // reload the as necessary
reloadControllerServiceReferences(serviceTable, controllerServiceEntity.component); if (controllerServiceEntity.permissions.canRead) {
reloadControllerServiceReferences(serviceTable, controllerServiceEntity.component);
}
}).fail(nf.Common.handleAjaxError); }).fail(nf.Common.handleAjaxError);
} }
}; };

View File

@ -596,8 +596,6 @@ nf.ControllerServices = (function () {
if (nf.Common.isEmpty(dataContext.component.validationErrors)) { if (nf.Common.isEmpty(dataContext.component.validationErrors)) {
markup += '<div class="pointer enable-controller-service fa fa-flash" title="Enable" style="margin-top: 2px; margin-right: 3px;"></div>'; markup += '<div class="pointer enable-controller-service fa fa-flash" title="Enable" style="margin-top: 2px; margin-right: 3px;"></div>';
} }
markup += '<div class="pointer delete-controller-service fa fa-trash" title="Remove" style="margin-top: 2px; margin-right: 3px;" ></div>';
} }
if (dataContext.component.persistsState === true) { if (dataContext.component.persistsState === true) {
@ -605,6 +603,10 @@ nf.ControllerServices = (function () {
} }
} }
if (dataContext.permissions.canWrite) {
markup += '<div class="pointer delete-controller-service fa fa-trash" title="Remove" style="margin-top: 2px; margin-right: 3px;" ></div>';
}
// allow policy configuration conditionally // allow policy configuration conditionally
if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) { if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) {
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>'; markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';

View File

@ -673,8 +673,6 @@ nf.Settings = (function () {
if (dataContext.component.state === 'STOPPED' && nf.Common.isEmpty(dataContext.component.validationErrors)) { if (dataContext.component.state === 'STOPPED' && nf.Common.isEmpty(dataContext.component.validationErrors)) {
markup += '<div title="Start" class="pointer start-reporting-task fa fa-play" style="margin-top: 2px; margin-right: 3px;"></div>'; markup += '<div title="Start" class="pointer start-reporting-task fa fa-play" style="margin-top: 2px; margin-right: 3px;"></div>';
} }
markup += '<div title="Remove" class="pointer delete-reporting-task fa fa-trash" style="margin-top: 2px; margin-right: 3px;" ></div>';
} }
if (dataContext.component.persistsState === true) { if (dataContext.component.persistsState === true) {
@ -682,6 +680,10 @@ nf.Settings = (function () {
} }
} }
if (dataContext.permissions.canWrite) {
markup += '<div title="Remove" class="pointer delete-reporting-task fa fa-trash" style="margin-top: 2px; margin-right: 3px;" ></div>';
}
// allow policy configuration conditionally // allow policy configuration conditionally
if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) { if (nf.Canvas.isConfigurableAuthorizer() && nf.Common.canAccessTenants()) {
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>'; markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';