mirror of https://github.com/apache/nifi.git
NIFI-4885:
- Updating the versioning endpoints to account for the granular access restrictions. This closes #2573. Signed-off-by: Bryan Bende <bbende@apache.org>
This commit is contained in:
parent
478e34082d
commit
98cd9ad531
|
@ -17,6 +17,7 @@
|
||||||
package org.apache.nifi.authorization;
|
package org.apache.nifi.authorization;
|
||||||
|
|
||||||
import org.apache.nifi.authorization.resource.Authorizable;
|
import org.apache.nifi.authorization.resource.Authorizable;
|
||||||
|
import org.apache.nifi.components.ConfigurableComponent;
|
||||||
import org.apache.nifi.components.RequiredPermission;
|
import org.apache.nifi.components.RequiredPermission;
|
||||||
import org.apache.nifi.web.api.dto.BundleDTO;
|
import org.apache.nifi.web.api.dto.BundleDTO;
|
||||||
import org.apache.nifi.web.api.dto.FlowSnippetDTO;
|
import org.apache.nifi.web.api.dto.FlowSnippetDTO;
|
||||||
|
@ -41,6 +42,15 @@ public interface AuthorizableLookup {
|
||||||
*/
|
*/
|
||||||
ComponentAuthorizable getConfigurableComponent(String type, BundleDTO bundle);
|
ComponentAuthorizable getConfigurableComponent(String type, BundleDTO bundle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authorizable for the given ConfigurableComponent. This will use a dummy instance of
|
||||||
|
* the component.
|
||||||
|
*
|
||||||
|
* @param configurableComponent the configurable component
|
||||||
|
* @return authorizable
|
||||||
|
*/
|
||||||
|
ComponentAuthorizable getConfigurableComponent(ConfigurableComponent configurableComponent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the authorizable Processor.
|
* Get the authorizable Processor.
|
||||||
*
|
*
|
||||||
|
|
|
@ -181,8 +181,13 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ComponentAuthorizable getConfigurableComponent(final String type, final BundleDTO bundle) {
|
public ComponentAuthorizable getConfigurableComponent(final String type, final BundleDTO bundle) {
|
||||||
try {
|
|
||||||
final ConfigurableComponent configurableComponent = controllerFacade.getTemporaryComponent(type, bundle);
|
final ConfigurableComponent configurableComponent = controllerFacade.getTemporaryComponent(type, bundle);
|
||||||
|
return getConfigurableComponent(configurableComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComponentAuthorizable getConfigurableComponent(ConfigurableComponent configurableComponent) {
|
||||||
|
try {
|
||||||
return new ConfigurableComponentAuthorizable(configurableComponent);
|
return new ConfigurableComponentAuthorizable(configurableComponent);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new AccessDeniedException("Unable to create component to verify if it references any Controller Services.");
|
throw new AccessDeniedException("Unable to create component to verify if it references any Controller Services.");
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
|
|
||||||
package org.apache.nifi.registry.flow;
|
package org.apache.nifi.registry.flow;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.nifi.annotation.behavior.Restricted;
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.bundle.BundleCoordinate;
|
import org.apache.nifi.bundle.BundleCoordinate;
|
||||||
import org.apache.nifi.components.ConfigurableComponent;
|
import org.apache.nifi.components.ConfigurableComponent;
|
||||||
|
@ -28,9 +25,14 @@ import org.apache.nifi.util.Tuple;
|
||||||
import org.apache.nifi.web.NiFiCoreException;
|
import org.apache.nifi.web.NiFiCoreException;
|
||||||
import org.apache.nifi.web.api.dto.BundleDTO;
|
import org.apache.nifi.web.api.dto.BundleDTO;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class FlowRegistryUtils {
|
public class FlowRegistryUtils {
|
||||||
|
|
||||||
public static boolean containsRestrictedComponent(final VersionedProcessGroup group) {
|
public static Set<ConfigurableComponent> getRestrictedComponents(final VersionedProcessGroup group) {
|
||||||
|
final Set<ConfigurableComponent> restrictedComponents = new HashSet<>();
|
||||||
|
|
||||||
final Set<Tuple<String, BundleCoordinate>> componentTypes = new HashSet<>();
|
final Set<Tuple<String, BundleCoordinate>> componentTypes = new HashSet<>();
|
||||||
populateComponentTypes(group, componentTypes);
|
populateComponentTypes(group, componentTypes);
|
||||||
|
|
||||||
|
@ -42,11 +44,11 @@ public class FlowRegistryUtils {
|
||||||
|
|
||||||
final boolean isRestricted = component.getClass().isAnnotationPresent(Restricted.class);
|
final boolean isRestricted = component.getClass().isAnnotationPresent(Restricted.class);
|
||||||
if (isRestricted) {
|
if (isRestricted) {
|
||||||
return true;
|
restrictedComponents.add(component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return restrictedComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void populateComponentTypes(final VersionedProcessGroup group, final Set<Tuple<String, BundleCoordinate>> componentTypes) {
|
private static void populateComponentTypes(final VersionedProcessGroup group, final Set<Tuple<String, BundleCoordinate>> componentTypes) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.nifi.authorization.user.NiFiUserDetails;
|
||||||
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
||||||
import org.apache.nifi.bundle.BundleCoordinate;
|
import org.apache.nifi.bundle.BundleCoordinate;
|
||||||
import org.apache.nifi.cluster.manager.NodeResponse;
|
import org.apache.nifi.cluster.manager.NodeResponse;
|
||||||
|
import org.apache.nifi.components.ConfigurableComponent;
|
||||||
import org.apache.nifi.connectable.ConnectableType;
|
import org.apache.nifi.connectable.ConnectableType;
|
||||||
import org.apache.nifi.controller.ScheduledState;
|
import org.apache.nifi.controller.ScheduledState;
|
||||||
import org.apache.nifi.controller.serialization.FlowEncodingVersion;
|
import org.apache.nifi.controller.serialization.FlowEncodingVersion;
|
||||||
|
@ -1689,10 +1690,11 @@ public class ProcessGroupResource extends ApplicationResource {
|
||||||
// for write access to the RestrictedComponents resource
|
// for write access to the RestrictedComponents resource
|
||||||
final VersionedFlowSnapshot versionedFlowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
|
final VersionedFlowSnapshot versionedFlowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
|
||||||
if (versionedFlowSnapshot != null) {
|
if (versionedFlowSnapshot != null) {
|
||||||
final boolean containsRestrictedComponent = FlowRegistryUtils.containsRestrictedComponent(versionedFlowSnapshot.getFlowContents());
|
final Set<ConfigurableComponent> restrictedComponents = FlowRegistryUtils.getRestrictedComponents(versionedFlowSnapshot.getFlowContents());
|
||||||
if (containsRestrictedComponent) {
|
restrictedComponents.forEach(restrictedComponent -> {
|
||||||
lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
final ComponentAuthorizable restrictedComponentAuthorizable = lookup.getConfigurableComponent(restrictedComponent);
|
||||||
}
|
authorizeRestrictions(authorizer, restrictedComponentAuthorizable);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
|
|
|
@ -17,31 +17,23 @@
|
||||||
|
|
||||||
package org.apache.nifi.web.api;
|
package org.apache.nifi.web.api;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import io.swagger.annotations.Api;
|
||||||
import javax.ws.rs.DELETE;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import javax.ws.rs.DefaultValue;
|
import io.swagger.annotations.ApiParam;
|
||||||
import javax.ws.rs.GET;
|
import io.swagger.annotations.ApiResponse;
|
||||||
import javax.ws.rs.HttpMethod;
|
import io.swagger.annotations.ApiResponses;
|
||||||
import javax.ws.rs.POST;
|
import io.swagger.annotations.Authorization;
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.QueryParam;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.MultivaluedHashMap;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.Response.Status;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.authorization.AccessDeniedException;
|
import org.apache.nifi.authorization.AccessDeniedException;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
|
import org.apache.nifi.authorization.ComponentAuthorizable;
|
||||||
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;
|
||||||
import org.apache.nifi.authorization.user.NiFiUser;
|
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.manager.NodeResponse;
|
import org.apache.nifi.cluster.manager.NodeResponse;
|
||||||
|
import org.apache.nifi.components.ConfigurableComponent;
|
||||||
import org.apache.nifi.controller.FlowController;
|
import org.apache.nifi.controller.FlowController;
|
||||||
import org.apache.nifi.controller.ScheduledState;
|
import org.apache.nifi.controller.ScheduledState;
|
||||||
import org.apache.nifi.controller.service.ControllerServiceState;
|
import org.apache.nifi.controller.service.ControllerServiceState;
|
||||||
|
@ -85,6 +77,21 @@ import org.apache.nifi.web.util.LifecycleManagementException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.MultivaluedHashMap;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
@ -100,13 +107,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import io.swagger.annotations.ApiParam;
|
|
||||||
import io.swagger.annotations.ApiResponse;
|
|
||||||
import io.swagger.annotations.ApiResponses;
|
|
||||||
import io.swagger.annotations.Authorization;
|
|
||||||
|
|
||||||
@Path("/versions")
|
@Path("/versions")
|
||||||
@Api(value = "/versions", description = "Endpoint for managing version control for a flow")
|
@Api(value = "/versions", description = "Endpoint for managing version control for a flow")
|
||||||
public class VersionsResource extends ApplicationResource {
|
public class VersionsResource extends ApplicationResource {
|
||||||
|
@ -1113,10 +1113,11 @@ public class VersionsResource extends ApplicationResource {
|
||||||
authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.WRITE, true, false, true, true);
|
authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.WRITE, true, false, true, true);
|
||||||
|
|
||||||
final VersionedProcessGroup groupContents = flowSnapshot.getFlowContents();
|
final VersionedProcessGroup groupContents = flowSnapshot.getFlowContents();
|
||||||
final boolean containsRestrictedComponents = FlowRegistryUtils.containsRestrictedComponent(groupContents);
|
final Set<ConfigurableComponent> restrictedComponents = FlowRegistryUtils.getRestrictedComponents(groupContents);
|
||||||
if (containsRestrictedComponents) {
|
restrictedComponents.forEach(restrictedComponent -> {
|
||||||
lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
final ComponentAuthorizable restrictedComponentAuthorizable = lookup.getConfigurableComponent(restrictedComponent);
|
||||||
}
|
authorizeRestrictions(authorizer, restrictedComponentAuthorizable);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
// Step 3: Verify that all components in the snapshot exist on all nodes
|
// Step 3: Verify that all components in the snapshot exist on all nodes
|
||||||
|
@ -1269,10 +1270,11 @@ public class VersionsResource extends ApplicationResource {
|
||||||
authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.WRITE, true, false, true, true);
|
authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.WRITE, true, false, true, true);
|
||||||
|
|
||||||
final VersionedProcessGroup groupContents = flowSnapshot.getFlowContents();
|
final VersionedProcessGroup groupContents = flowSnapshot.getFlowContents();
|
||||||
final boolean containsRestrictedComponents = FlowRegistryUtils.containsRestrictedComponent(groupContents);
|
final Set<ConfigurableComponent> restrictedComponents = FlowRegistryUtils.getRestrictedComponents(groupContents);
|
||||||
if (containsRestrictedComponents) {
|
restrictedComponents.forEach(restrictedComponent -> {
|
||||||
lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
final ComponentAuthorizable restrictedComponentAuthorizable = lookup.getConfigurableComponent(restrictedComponent);
|
||||||
}
|
authorizeRestrictions(authorizer, restrictedComponentAuthorizable);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
// Step 3: Verify that all components in the snapshot exist on all nodes
|
// Step 3: Verify that all components in the snapshot exist on all nodes
|
||||||
|
|
Loading…
Reference in New Issue