NIFI-2307: - Enforcing connection permissions based on the source and destination comonent. - Removing connection specific access policies. NIFI-2265: - Filtering out sensitive details in component status and status history when appropriate. NIFI-1800: - Adding parent process group id to the Controller Services table. NIFI-2077: - Removing some old un-used icons following the UI refresh. NIFI-2242: - Requiring write permissions for all components in a selection. NIFI-2080: - Updating style of the name in the selection context to handle scroll bars and use available width. NIFI-2331: - Addressing issue when removing a user/group which was causing the tenant policy to be removed. NIFI-2335: - Ensuring the flow is saved after starting/stopping a process group. NIFI-2235: - Ensuring we use consistent conditions between the context menu and the operate palette.
- Allowing users with read only access to the tenants page. - Fixing current user integration test. - Ensuring schedule methods are locked appropriately. - Addressing comments from PR. This closes #698 Signed-off-by: jpercivall <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/4a4d60e6 Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/4a4d60e6 Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/4a4d60e6 Branch: refs/heads/master Commit: 4a4d60e6af5014342039f751c7b058079d643f7b Parents: 0dbba81 Author: Matt Gilman <[email protected]> Authored: Thu Jul 21 22:53:00 2016 -0400 Committer: jpercivall <[email protected]> Committed: Thu Jul 21 23:52:01 2016 -0400 ---------------------------------------------------------------------- .../authorization/resource/Authorizable.java | 4 +- .../history/ComponentStatusRepository.java | 12 +- .../dto/status/RemoteProcessGroupStatusDTO.java | 21 +- .../RemoteProcessGroupStatusSnapshotDTO.java | 20 +- .../nifi/web/api/entity/ConnectionEntity.java | 49 ++ .../nifi/web/api/entity/ProcessorEntity.java | 16 + .../authorization/resource/ResourceFactory.java | 45 -- .../authorization/resource/ResourceType.java | 3 +- .../endpoints/GroupStatusEndpointMerger.java | 16 - .../nifi/cluster/manager/StatusMerger.java | 9 - .../nifi/connectable/StandardConnection.java | 55 +- .../apache/nifi/controller/FlowController.java | 191 +++++-- .../VolatileComponentStatusRepository.java | 34 +- .../nifi/authorization/AuthorizableLookup.java | 212 ++++++++ .../nifi/authorization/AuthorizeAccess.java | 21 + .../authorization/ConnectionAuthorizable.java | 54 ++ .../StandardAuthorizableLookup.java | 534 +++++++++++++++++++ .../org/apache/nifi/web/AuthorizableLookup.java | 212 -------- .../org/apache/nifi/web/AuthorizeAccess.java | 21 - .../org/apache/nifi/web/NiFiServiceFacade.java | 1 + .../apache/nifi/web/NiFiServiceFacadeLock.java | 14 +- .../nifi/web/StandardAuthorizableLookup.java | 515 ------------------ .../nifi/web/StandardNiFiServiceFacade.java | 82 ++- .../nifi/web/api/ApplicationResource.java | 10 +- .../apache/nifi/web/api/ConnectionResource.java | 66 ++- .../nifi/web/api/FlowFileQueueResource.java | 72 ++- .../nifi/web/api/ProcessGroupResource.java | 25 +- .../org/apache/nifi/web/api/dto/DtoFactory.java | 12 +- .../apache/nifi/web/api/dto/EntityFactory.java | 4 + .../nifi/web/controller/ControllerFacade.java | 60 ++- .../web/dao/impl/StandardConnectionDAO.java | 16 +- .../src/main/resources/nifi-web-api-context.xml | 2 +- .../accesscontrol/ITFlowAccessControl.java | 2 +- .../WEB-INF/partials/canvas/canvas-header.jsp | 2 +- .../canvas/drop-request-status-dialog.jsp | 2 +- .../WEB-INF/partials/canvas/navigation.jsp | 14 +- .../WEB-INF/partials/users/users-content.jsp | 2 +- .../nifi-web-ui/src/main/webapp/css/graph.css | 2 +- .../src/main/webapp/css/navigation.css | 4 +- .../src/main/webapp/css/policy-management.css | 2 +- .../src/main/webapp/images/bgButton.png | Bin 234 -> 0 bytes .../src/main/webapp/images/bgButtonOver.png | Bin 234 -> 0 bytes .../src/main/webapp/images/bgButtonSelected.png | Bin 166 -> 0 bytes .../main/webapp/images/bgButtonSelectedOver.png | Bin 168 -> 0 bytes .../src/main/webapp/images/bgInputText.png | Bin 139 -> 0 bytes .../src/main/webapp/images/bgShellClose.png | Bin 169 -> 0 bytes .../src/main/webapp/images/bgTabContainer.png | Bin 234 -> 0 bytes .../src/main/webapp/images/bgTableHeader.png | Bin 232 -> 0 bytes .../src/main/webapp/images/buttonRefresh.png | Bin 915 -> 0 bytes .../src/main/webapp/images/iconAlertDialog.png | Bin 1241 -> 0 bytes .../src/main/webapp/images/iconAutoRefresh.png | Bin 3102 -> 0 bytes .../src/main/webapp/images/iconBulletin.png | Bin 1066 -> 0 bytes .../src/main/webapp/images/iconCenterView.png | Bin 338 -> 0 bytes .../src/main/webapp/images/iconChart.png | Bin 510 -> 0 bytes .../src/main/webapp/images/iconClusterSmall.png | Bin 757 -> 0 bytes .../src/main/webapp/images/iconColor.png | Bin 738 -> 0 bytes .../src/main/webapp/images/iconConfigure.png | Bin 696 -> 0 bytes .../src/main/webapp/images/iconConnect.png | Bin 589 -> 0 bytes .../src/main/webapp/images/iconCopy.png | Bin 514 -> 0 bytes .../src/main/webapp/images/iconDisable.png | Bin 764 -> 0 bytes .../src/main/webapp/images/iconDisconnect.png | Bin 569 -> 0 bytes .../src/main/webapp/images/iconEdit.png | Bin 493 -> 0 bytes .../src/main/webapp/images/iconEditButton.png | Bin 915 -> 0 bytes .../src/main/webapp/images/iconEmptyQueue.png | Bin 785 -> 0 bytes .../src/main/webapp/images/iconEnable.png | Bin 472 -> 0 bytes .../src/main/webapp/images/iconExport.png | Bin 453 -> 0 bytes .../src/main/webapp/images/iconFunnel.png | Bin 1223 -> 0 bytes .../src/main/webapp/images/iconGoTo.png | Bin 448 -> 0 bytes .../main/webapp/images/iconInputPortSmall.png | Bin 532 -> 0 bytes .../webapp/images/iconIsolatedProcessor.png | Bin 1781 -> 0 bytes .../src/main/webapp/images/iconLineage.png | Bin 432 -> 0 bytes .../src/main/webapp/images/iconListQueue.png | Bin 1502 -> 0 bytes .../src/main/webapp/images/iconMoveToParent.png | Bin 215 -> 0 bytes .../src/main/webapp/images/iconNotSecure.png | Bin 137 -> 0 bytes .../main/webapp/images/iconOutputPortSmall.png | Bin 459 -> 0 bytes .../src/main/webapp/images/iconPaste.png | Bin 601 -> 0 bytes .../webapp/images/iconPortNotTransmitting.png | Bin 231 -> 0 bytes .../main/webapp/images/iconPortTransmitting.png | Bin 235 -> 0 bytes .../src/main/webapp/images/iconPrimary.png | Bin 647 -> 0 bytes .../src/main/webapp/images/iconProvenance.png | Bin 1104 -> 0 bytes .../src/main/webapp/images/iconRefresh.png | Bin 492 -> 0 bytes .../src/main/webapp/images/iconRemotePorts.png | Bin 456 -> 0 bytes .../src/main/webapp/images/iconResetCounter.png | Bin 304 -> 0 bytes .../src/main/webapp/images/iconRevoke.png | Bin 676 -> 0 bytes .../src/main/webapp/images/iconSecure.png | Bin 133 -> 0 bytes .../main/webapp/images/iconSmallProcessor.png | Bin 647 -> 0 bytes .../webapp/images/iconSmallRelationship.png | Bin 770 -> 0 bytes .../src/main/webapp/images/iconStop.png | Bin 402 -> 0 bytes .../src/main/webapp/images/iconToFront.png | Bin 475 -> 0 bytes .../webapp/images/iconTransmissionActive.png | Bin 1330 -> 0 bytes .../webapp/images/iconTransmissionInactive.png | Bin 1248 -> 0 bytes .../src/main/webapp/images/iconUsage.png | Bin 470 -> 0 bytes .../src/main/webapp/images/iconViewState.png | Bin 1245 -> 0 bytes .../src/main/webapp/images/loadAnimation.gif | Bin 10789 -> 0 bytes .../src/main/webapp/images/panelBg.jpg | Bin 312 -> 0 bytes .../src/main/webapp/images/starburst.png | Bin 190 -> 0 bytes .../src/main/webapp/images/tabBg.jpg | Bin 320 -> 0 bytes .../images/transmissionSwitchDisabled.png | Bin 1240 -> 0 bytes .../webapp/images/transmissionSwitchEnabled.png | Bin 1600 -> 0 bytes .../src/main/webapp/images/ungroup.png | Bin 3409 -> 0 bytes .../nf-ng-canvas-global-menu-controller.js | 2 +- .../nf-ng-canvas-graph-controls-controller.js | 50 ++ .../src/main/webapp/js/nf/canvas/nf-actions.js | 26 +- .../main/webapp/js/nf/canvas/nf-canvas-utils.js | 184 +++++-- .../js/nf/canvas/nf-connection-configuration.js | 70 ++- .../main/webapp/js/nf/canvas/nf-connection.js | 111 ++-- .../main/webapp/js/nf/canvas/nf-context-menu.js | 67 +-- .../js/nf/canvas/nf-controller-services.js | 27 +- .../main/webapp/js/nf/canvas/nf-draggable.js | 31 +- .../webapp/js/nf/canvas/nf-policy-management.js | 4 +- .../webapp/js/nf/canvas/nf-queue-listing.js | 5 +- .../main/webapp/js/nf/nf-connection-details.js | 189 +++++-- .../main/webapp/js/nf/users/nf-users-table.js | 24 +- .../src/main/webapp/js/nf/users/nf-users.js | 13 +- 114 files changed, 1887 insertions(+), 1354 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java ---------------------------------------------------------------------- diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java index 7cb21ae..09829a9 100644 --- a/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java +++ b/nifi-framework-api/src/main/java/org/apache/nifi/authorization/resource/Authorizable.java @@ -97,7 +97,7 @@ public interface Authorizable { if (parent == null) { return AuthorizationResult.denied(); } else { - return parent.checkAuthorization(authorizer, action, user); + return parent.checkAuthorization(authorizer, action, user, resourceContext); } } else { return result; @@ -152,7 +152,7 @@ public interface Authorizable { if (parent == null) { throw new AccessDeniedException("Access is denied"); } else { - parent.authorize(authorizer, action, user); + parent.authorize(authorizer, action, user, resourceContext); } } else if (Result.Denied.equals(result.getResult())) { throw new AccessDeniedException(result.getExplanation()); http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-framework-api/src/main/java/org/apache/nifi/controller/status/history/ComponentStatusRepository.java ---------------------------------------------------------------------- diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/controller/status/history/ComponentStatusRepository.java b/nifi-framework-api/src/main/java/org/apache/nifi/controller/status/history/ComponentStatusRepository.java index d273096..1042c3f 100644 --- a/nifi-framework-api/src/main/java/org/apache/nifi/controller/status/history/ComponentStatusRepository.java +++ b/nifi-framework-api/src/main/java/org/apache/nifi/controller/status/history/ComponentStatusRepository.java @@ -16,16 +16,24 @@ */ package org.apache.nifi.controller.status.history; -import java.util.Date; - import org.apache.nifi.controller.status.ProcessGroupStatus; +import java.util.Date; + /** * A repository for storing and retrieving components' historical status * information */ public interface ComponentStatusRepository { + String COMPONENT_DETAIL_ID = "Id"; + String COMPONENT_DETAIL_GROUP_ID = "Group Id"; + String COMPONENT_DETAIL_NAME = "Name"; + String COMPONENT_DETAIL_TYPE = "Type"; + String COMPONENT_DETAIL_SOURCE_NAME = "Source Name"; + String COMPONENT_DETAIL_DESTINATION_NAME = "Destination Name"; + String COMPONENT_DETAIL_URI = "Uri"; + /** * Captures the status information provided in the given report * http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java index 62685b1..faae6e6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusDTO.java @@ -17,14 +17,13 @@ package org.apache.nifi.web.api.dto.status; -import java.util.Date; -import java.util.List; +import com.wordnik.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.util.TimeAdapter; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import com.wordnik.swagger.annotations.ApiModelProperty; -import org.apache.nifi.web.api.dto.util.TimeAdapter; +import java.util.Date; +import java.util.List; @XmlType(name = "remoteProcessGroupStatus") public class RemoteProcessGroupStatusDTO { @@ -35,8 +34,6 @@ public class RemoteProcessGroupStatusDTO { private String transmissionStatus; private Date statsLastRefreshed; - private List<String> authorizationIssues; - private RemoteProcessGroupStatusSnapshotDTO aggregateSnapshot; private List<NodeRemoteProcessGroupStatusSnapshotDTO> nodeSnapshots; @@ -76,16 +73,6 @@ public class RemoteProcessGroupStatusDTO { this.transmissionStatus = transmissionStatus; } - - @ApiModelProperty("Any remote authorization issues for the remote process group.") - public List<String> getAuthorizationIssues() { - return authorizationIssues; - } - - public void setAuthorizationIssues(List<String> authorizationIssues) { - this.authorizationIssues = authorizationIssues; - } - @ApiModelProperty("The URI of the target system.") public String getTargetUri() { return targetUri; http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java index f0f0d7e..85e3a24 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/status/RemoteProcessGroupStatusSnapshotDTO.java @@ -16,13 +16,10 @@ */ package org.apache.nifi.web.api.dto.status; -import java.util.ArrayList; -import java.util.List; +import com.wordnik.swagger.annotations.ApiModelProperty; import javax.xml.bind.annotation.XmlType; -import com.wordnik.swagger.annotations.ApiModelProperty; - /** * The status of a remote process group in this NiFi. */ @@ -36,8 +33,6 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable { private String transmissionStatus; private Integer activeThreadCount; - private List<String> authorizationIssues; - private Integer flowFilesSent = 0; private Long bytesSent = 0L; private String sent; @@ -119,18 +114,6 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable { } /** - * @return any remote authorization issues for this remote process group - */ - @ApiModelProperty("Any remote authorization issues for the remote process group.") - public List<String> getAuthorizationIssues() { - return authorizationIssues; - } - - public void setAuthorizationIssues(List<String> authorizationIssues) { - this.authorizationIssues = authorizationIssues; - } - - /** * @return Formatted description of the amount of data sent to this remote process group */ @ApiModelProperty("The count/size of the flowfiles sent to the remote process group in the last 5 minutes.") @@ -201,7 +184,6 @@ public class RemoteProcessGroupStatusSnapshotDTO implements Cloneable { other.setTargetUri(getTargetUri()); other.setTransmissionStatus(getTransmissionStatus()); other.setActiveThreadCount(getActiveThreadCount()); - other.setAuthorizationIssues(getAuthorizationIssues() == null ? null : new ArrayList<String>(getAuthorizationIssues())); other.setFlowFilesSent(getFlowFilesSent()); other.setBytesSent(getBytesSent()); other.setFlowFilesReceived(getFlowFilesReceived()); http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java index 1b48ca4..86aa1ee 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ConnectionEntity.java @@ -34,10 +34,13 @@ public class ConnectionEntity extends ComponentEntity { private ConnectionStatusDTO status; private List<PositionDTO> bends; private Integer labelIndex; + private Long zIndex; private String sourceId; private String sourceGroupId; + private String sourceType; private String destinationId; private String destinationGroupId; + private String destinationType; /** * @return RelationshipDTO that is being serialized @@ -93,6 +96,20 @@ public class ConnectionEntity extends ComponentEntity { } /** + * @return z index for this connection + */ + @ApiModelProperty( + value = "The z index of the connection." + ) + public Long getzIndex() { + return zIndex; + } + + public void setzIndex(Long zIndex) { + this.zIndex = zIndex; + } + + /** * @return The identifier of the source of this connection */ @ApiModelProperty( @@ -135,6 +152,22 @@ public class ConnectionEntity extends ComponentEntity { } /** + * @return type of this source connectable component + */ + @ApiModelProperty( + value = "The type of component the source connectable is.", + required = true, + allowableValues = "PROCESSOR, REMOTE_INPUT_PORT, REMOTE_OUTPUT_PORT, INPUT_PORT, OUTPUT_PORT, FUNNEL" + ) + public String getSourceType() { + return sourceType; + } + + public void setSourceType(String sourceType) { + this.sourceType = sourceType; + } + + /** * @return The identifier of the group of the destination of this connection */ @ApiModelProperty( @@ -147,4 +180,20 @@ public class ConnectionEntity extends ComponentEntity { public void setDestinationGroupId(String destinationGroupId) { this.destinationGroupId = destinationGroupId; } + + /** + * @return type of this destination connectable component + */ + @ApiModelProperty( + value = "The type of component the destination connectable is.", + required = true, + allowableValues = "PROCESSOR, REMOTE_INPUT_PORT, REMOTE_OUTPUT_PORT, INPUT_PORT, OUTPUT_PORT, FUNNEL" + ) + public String getDestinationType() { + return destinationType; + } + + public void setDestinationType(String destinationType) { + this.destinationType = destinationType; + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java index 89b784e..cda843c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ProcessorEntity.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.web.api.entity; +import com.wordnik.swagger.annotations.ApiModelProperty; import org.apache.nifi.web.api.dto.ProcessorDTO; import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; @@ -28,6 +29,7 @@ import javax.xml.bind.annotation.XmlRootElement; public class ProcessorEntity extends ComponentEntity { private ProcessorDTO component; + private String inputRequirement; private ProcessorStatusDTO status; /** @@ -55,4 +57,18 @@ public class ProcessorEntity extends ComponentEntity { public void setStatus(ProcessorStatusDTO status) { this.status = status; } + + /** + * @return the input requirement of this processor + */ + @ApiModelProperty( + value = "The input requirement for this processor." + ) + public String getInputRequirement() { + return inputRequirement; + } + + public void setInputRequirement(String inputRequirement) { + this.inputRequirement = inputRequirement; + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java index 004429a..baa58ac 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java @@ -22,18 +22,6 @@ import java.util.Objects; public final class ResourceFactory { - private final static Resource CONNECTION_RESOURCE = new Resource() { - @Override - public String getIdentifier() { - return ResourceType.Connection.getValue(); - } - - @Override - public String getName() { - return "Connection"; - } - }; - private final static Resource CONTROLLER_RESOURCE = new Resource() { @Override public String getIdentifier() { @@ -300,15 +288,6 @@ public final class ResourceFactory { }; /** - * Gets the Resource for accessing Connections. - * - * @return The resource for accessing connections - */ - public static Resource getConnectionResource() { - return CONNECTION_RESOURCE; - } - - /** * Gets the Resource for accessing the Controller. This includes Controller level configuration, bulletins, reporting tasks, and the cluster. * * @return The resource for accessing the Controller @@ -603,30 +582,6 @@ public final class ResourceFactory { } /** - * Gets a Resource fo accessing a flowfile queue for the specified connection. - * - * @param connectionIdentifier The identifier of the connection - * @param connectionName The name of the connection - * @return The resource - */ - public static Resource getFlowFileQueueResource(final String connectionIdentifier, final String connectionName) { - Objects.requireNonNull(connectionIdentifier, "The connection identifier must be specified."); - Objects.requireNonNull(connectionName, "The connection name must be specified."); - - return new Resource() { - @Override - public String getIdentifier() { - return String.format("/flowfile-queue/%s", connectionIdentifier); - } - - @Override - public String getName() { - return connectionName + " queue"; - } - }; - } - - /** * Prevent outside instantiation. */ private ResourceFactory() {} http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java index 177b9a4..bce270a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java @@ -17,11 +17,10 @@ package org.apache.nifi.authorization.resource; public enum ResourceType { - Connection("/connections"), Controller("/controller"), ControllerService("/controller-services"), Counters("/counters"), - Funnel("/funnel"), + Funnel("/funnels"), Flow("/flow"), InputPort("/input-ports"), Label("/labels"), http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java index 9440760..8823902 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/endpoints/GroupStatusEndpointMerger.java @@ -21,14 +21,10 @@ import org.apache.nifi.cluster.manager.StatusMerger; import org.apache.nifi.cluster.protocol.NodeIdentifier; import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; -import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO; -import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO; import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; import java.net.URI; import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.regex.Pattern; @@ -70,18 +66,6 @@ public class GroupStatusEndpointMerger extends AbstractNodeStatusEndpoint<Proces continue; } - final ProcessGroupStatusSnapshotDTO nodeSnapshot = nodeProcessGroupStatus.getAggregateSnapshot(); - for (final RemoteProcessGroupStatusSnapshotDTO remoteProcessGroupStatus : nodeSnapshot.getRemoteProcessGroupStatusSnapshots()) { - final List<String> nodeAuthorizationIssues = remoteProcessGroupStatus.getAuthorizationIssues(); - if (nodeAuthorizationIssues != null && !nodeAuthorizationIssues.isEmpty()) { - for (final ListIterator<String> iter = nodeAuthorizationIssues.listIterator(); iter.hasNext();) { - final String Issue = iter.next(); - iter.set("[" + nodeId.getApiAddress() + ":" + nodeId.getApiPort() + "] -- " + Issue); - } - remoteProcessGroupStatus.setAuthorizationIssues(nodeAuthorizationIssues); - } - } - StatusMerger.merge(mergedProcessGroupStatus, nodeProcessGroupStatus, nodeId.getId(), nodeId.getApiAddress(), nodeId.getApiPort()); } } http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java index 04acbda..c886747 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/StatusMerger.java @@ -378,15 +378,6 @@ public class StatusMerger { target.setActiveThreadCount(target.getActiveThreadCount() + toMerge.getActiveThreadCount()); - final List<String> authIssues = new ArrayList<>(); - if (target.getAuthorizationIssues() != null) { - authIssues.addAll(target.getAuthorizationIssues()); - } - if (toMerge.getAuthorizationIssues() != null) { - authIssues.addAll(toMerge.getAuthorizationIssues()); - } - target.setAuthorizationIssues(authIssues); - target.setFlowFilesSent(target.getFlowFilesSent() + toMerge.getFlowFilesSent()); target.setBytesSent(target.getBytesSent() + toMerge.getBytesSent()); target.setFlowFilesReceived(target.getFlowFilesReceived() + toMerge.getFlowFilesReceived()); http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java index 0843743..3745d7d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/connectable/StandardConnection.java @@ -20,10 +20,14 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.nifi.authorization.AccessDeniedException; +import org.apache.nifi.authorization.AuthorizationResult; +import org.apache.nifi.authorization.AuthorizationResult.Result; +import org.apache.nifi.authorization.Authorizer; +import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.Resource; import org.apache.nifi.authorization.resource.Authorizable; -import org.apache.nifi.authorization.resource.ResourceFactory; -import org.apache.nifi.authorization.resource.ResourceType; +import org.apache.nifi.authorization.user.NiFiUser; import org.apache.nifi.controller.ProcessScheduler; import org.apache.nifi.controller.StandardFlowFileQueue; import org.apache.nifi.controller.queue.FlowFileQueue; @@ -42,6 +46,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -103,23 +108,51 @@ public final class StandardConnection implements Connection { @Override public Authorizable getParentAuthorizable() { - return getSource(); + return null; } @Override public Resource getResource() { - String name = getName(); + return new Resource() { + @Override + public String getIdentifier() { + return "/connections/" + StandardConnection.this.getIdentifier(); + } - final Collection<Relationship> relationships = getRelationships(); - if (name == null && CollectionUtils.isNotEmpty(relationships)) { - name = StringUtils.join(relationships.stream().map(relationship -> relationship.getName()).collect(Collectors.toSet()), ", "); - } + @Override + public String getName() { + String name = StandardConnection.this.getName(); + + final Collection<Relationship> relationships = getRelationships(); + if (name == null && CollectionUtils.isNotEmpty(relationships)) { + name = StringUtils.join(relationships.stream().map(relationship -> relationship.getName()).collect(Collectors.toSet()), ", "); + } - if (name == null) { - name = "Connection"; + if (name == null) { + name = "Connection"; + } + + return name; + } + }; + } + + @Override + public AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) { + // check the source + final AuthorizationResult sourceResult = getSource().checkAuthorization(authorizer, action, user, resourceContext); + if (Result.Denied.equals(sourceResult.getResult())) { + return sourceResult; } - return ResourceFactory.getComponentResource(ResourceType.Connection, getIdentifier(), name); + // check the destination + return getDestination().checkAuthorization(authorizer, action, user, resourceContext); + } + + @Override + public void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) throws AccessDeniedException { + getSource().authorize(authorizer, action, user, resourceContext); + getDestination().authorize(authorizer, action, user, resourceContext); } @Override http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java index 4670605..abe5e27 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java @@ -16,39 +16,8 @@ */ package org.apache.nifi.controller; -import static java.util.Objects.requireNonNull; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.LockSupport; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import javax.net.ssl.SSLContext; - +import com.sun.jersey.api.client.ClientHandlerException; +import org.apache.commons.collections4.Predicate; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.action.Action; import org.apache.nifi.admin.service.AuditService; @@ -59,6 +28,7 @@ import org.apache.nifi.annotation.lifecycle.OnShutdown; import org.apache.nifi.annotation.notification.OnPrimaryNodeStateChange; import org.apache.nifi.annotation.notification.PrimaryNodeState; import org.apache.nifi.authorization.Authorizer; +import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.Resource; import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.authorization.resource.ProvenanceEventAuthorizable; @@ -183,10 +153,10 @@ import org.apache.nifi.processor.Relationship; import org.apache.nifi.processor.SimpleProcessLogger; import org.apache.nifi.processor.StandardProcessorInitializationContext; import org.apache.nifi.processor.StandardValidationContextFactory; -import org.apache.nifi.provenance.ProvenanceRepository; +import org.apache.nifi.provenance.ProvenanceAuthorizableFactory; import org.apache.nifi.provenance.ProvenanceEventRecord; import org.apache.nifi.provenance.ProvenanceEventType; -import org.apache.nifi.provenance.ProvenanceAuthorizableFactory; +import org.apache.nifi.provenance.ProvenanceRepository; import org.apache.nifi.provenance.StandardProvenanceEventRecord; import org.apache.nifi.remote.HttpRemoteSiteListener; import org.apache.nifi.remote.RemoteGroupPort; @@ -236,7 +206,37 @@ import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.sun.jersey.api.client.ClientHandlerException; +import javax.net.ssl.SSLContext; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.LockSupport; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import static java.util.Objects.requireNonNull; public class FlowController implements EventAccess, ControllerServiceProvider, ReportingTaskProvider, QueueProvider, Authorizable, ProvenanceAuthorizableFactory, NodeTypeProvider { @@ -2128,28 +2128,85 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R return root == null ? null : root.findProcessGroup(searchId); } + /** + * Returns the status of all components in the controller. This request is not in the context of a user so the results will be unfiltered. + * + * @return the component status + */ @Override public ProcessGroupStatus getControllerStatus() { return getGroupStatus(getRootGroupId()); } + /** + * Returns the status of all components in the specified group. This request is not in the context of a user so the results will be unfiltered. + * + * @param groupId group id + * @return the component status + */ public ProcessGroupStatus getGroupStatus(final String groupId) { return getGroupStatus(groupId, getProcessorStats()); } + /** + * Returns the status for components in the specified group. This request is made by the specified user so the results will be filtered accordingly. + * + * @param groupId group id + * @param user user making request + * @return the component status + */ + public ProcessGroupStatus getGroupStatus(final String groupId, final NiFiUser user) { + return getGroupStatus(groupId, getProcessorStats(), user); + } + + /** + * Returns the status for the components in the specified group with the specified report. This request is not in the context of a user so the results + * will be unfiltered. + * + * @param groupId group id + * @param statusReport report + * @return the component status + */ public ProcessGroupStatus getGroupStatus(final String groupId, final RepositoryStatusReport statusReport) { final ProcessGroup group = getGroup(groupId); - return getGroupStatus(group, statusReport); + + // this was invoked with no user context so the results will be unfiltered... necessary for aggregating status history + return getGroupStatus(group, statusReport, authorizable -> true); } - public ProcessGroupStatus getGroupStatus(final ProcessGroup group, final RepositoryStatusReport statusReport) { + /** + * Returns the status for the components in the specified group with the specified report. This request is made by the specified user + * so the results will be filtered accordingly. + * + * @param groupId group id + * @param statusReport report + * @param user user making request + * @return the component status + */ + public ProcessGroupStatus getGroupStatus(final String groupId, final RepositoryStatusReport statusReport, final NiFiUser user) { + final ProcessGroup group = getGroup(groupId); + + // on demand status request for a specific user... require authorization per component and filter results as appropriate + return getGroupStatus(group, statusReport, authorizable -> authorizable.isAuthorized(authorizer, RequestAction.READ, user)); + } + + /** + * Returns the status for the components in the specified group with the specified report. The results will be filtered by executing + * the specified predicate. + * + * @param group group id + * @param statusReport report + * @param isAuthorized is authorized check + * @return the component status + */ + public ProcessGroupStatus getGroupStatus(final ProcessGroup group, final RepositoryStatusReport statusReport, final Predicate<Authorizable> isAuthorized) { if (group == null) { return null; } final ProcessGroupStatus status = new ProcessGroupStatus(); status.setId(group.getIdentifier()); - status.setName(group.getName()); + status.setName(isAuthorized.evaluate(group) ? group.getName() : group.getIdentifier()); int activeGroupThreads = 0; long bytesRead = 0L; long bytesWritten = 0L; @@ -2170,7 +2227,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R final Collection<ProcessorStatus> processorStatusCollection = new ArrayList<>(); status.setProcessorStatus(processorStatusCollection); for (final ProcessorNode procNode : group.getProcessors()) { - final ProcessorStatus procStat = getProcessorStatus(statusReport, procNode); + final ProcessorStatus procStat = getProcessorStatus(statusReport, procNode, isAuthorized); processorStatusCollection.add(procStat); activeGroupThreads += procStat.getActiveThreadCount(); bytesRead += procStat.getBytesRead(); @@ -2186,7 +2243,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R final Collection<ProcessGroupStatus> localChildGroupStatusCollection = new ArrayList<>(); status.setProcessGroupStatus(localChildGroupStatusCollection); for (final ProcessGroup childGroup : group.getProcessGroups()) { - final ProcessGroupStatus childGroupStatus = getGroupStatus(childGroup, statusReport); + final ProcessGroupStatus childGroupStatus = getGroupStatus(childGroup, statusReport, isAuthorized); localChildGroupStatusCollection.add(childGroupStatus); activeGroupThreads += childGroupStatus.getActiveThreadCount(); bytesRead += childGroupStatus.getBytesRead(); @@ -2207,7 +2264,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R final Collection<RemoteProcessGroupStatus> remoteProcessGroupStatusCollection = new ArrayList<>(); status.setRemoteProcessGroupStatus(remoteProcessGroupStatusCollection); for (final RemoteProcessGroup remoteGroup : group.getRemoteProcessGroups()) { - final RemoteProcessGroupStatus remoteStatus = createRemoteGroupStatus(remoteGroup, statusReport); + final RemoteProcessGroupStatus remoteStatus = createRemoteGroupStatus(remoteGroup, statusReport, isAuthorized); if (remoteStatus != null) { remoteProcessGroupStatusCollection.add(remoteStatus); @@ -2224,13 +2281,17 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R // get the connection and remote port status for (final Connection conn : group.getConnections()) { + final boolean isConnectionAuthorized = isAuthorized.evaluate(conn); + final boolean isSourceAuthorized = isAuthorized.evaluate(conn.getSource()); + final boolean isDestinationAuthorized = isAuthorized.evaluate(conn.getDestination()); + final ConnectionStatus connStatus = new ConnectionStatus(); connStatus.setId(conn.getIdentifier()); connStatus.setGroupId(conn.getProcessGroup().getIdentifier()); connStatus.setSourceId(conn.getSource().getIdentifier()); - connStatus.setSourceName(conn.getSource().getName()); + connStatus.setSourceName(isSourceAuthorized ? conn.getSource().getName() : conn.getSource().getIdentifier()); connStatus.setDestinationId(conn.getDestination().getIdentifier()); - connStatus.setDestinationName(conn.getDestination().getName()); + connStatus.setDestinationName(isDestinationAuthorized ? conn.getDestination().getName() : conn.getDestination().getIdentifier()); connStatus.setBackPressureDataSizeThreshold(conn.getFlowFileQueue().getBackPressureDataSizeThreshold()); connStatus.setBackPressureObjectThreshold(conn.getFlowFileQueue().getBackPressureObjectThreshold()); @@ -2245,14 +2306,18 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R bytesTransferred += connectionStatusReport.getContentSizeIn() + connectionStatusReport.getContentSizeOut(); } - if (StringUtils.isNotBlank(conn.getName())) { - connStatus.setName(conn.getName()); - } else if (conn.getRelationships() != null && !conn.getRelationships().isEmpty()) { - final Collection<String> relationships = new ArrayList<>(conn.getRelationships().size()); - for (final Relationship relationship : conn.getRelationships()) { - relationships.add(relationship.getName()); + if (isConnectionAuthorized) { + if (StringUtils.isNotBlank(conn.getName())) { + connStatus.setName(conn.getName()); + } else if (conn.getRelationships() != null && !conn.getRelationships().isEmpty()) { + final Collection<String> relationships = new ArrayList<>(conn.getRelationships().size()); + for (final Relationship relationship : conn.getRelationships()) { + relationships.add(relationship.getName()); + } + connStatus.setName(StringUtils.join(relationships, ", ")); } - connStatus.setName(StringUtils.join(relationships, ", ")); + } else { + connStatus.setName(conn.getIdentifier()); } final QueueSize queueSize = conn.getFlowFileQueue().size(); @@ -2285,10 +2350,12 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R final Set<Port> inputPorts = group.getInputPorts(); for (final Port port : inputPorts) { + final boolean isInputPortAuthorized = isAuthorized.evaluate(port); + final PortStatus portStatus = new PortStatus(); portStatus.setId(port.getIdentifier()); portStatus.setGroupId(port.getProcessGroup().getIdentifier()); - portStatus.setName(port.getName()); + portStatus.setName(isInputPortAuthorized ? port.getName() : port.getIdentifier()); portStatus.setActiveThreadCount(processScheduler.getActiveThreadCount(port)); // determine the run status @@ -2343,10 +2410,12 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R final Set<Port> outputPorts = group.getOutputPorts(); for (final Port port : outputPorts) { + final boolean isOutputPortAuthorized = isAuthorized.evaluate(port); + final PortStatus portStatus = new PortStatus(); portStatus.setId(port.getIdentifier()); portStatus.setGroupId(port.getProcessGroup().getIdentifier()); - portStatus.setName(port.getName()); + portStatus.setName(isOutputPortAuthorized ? port.getName() : port.getIdentifier()); portStatus.setActiveThreadCount(processScheduler.getActiveThreadCount(port)); // determine the run status @@ -2419,7 +2488,9 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R return status; } - private RemoteProcessGroupStatus createRemoteGroupStatus(final RemoteProcessGroup remoteGroup, final RepositoryStatusReport statusReport) { + private RemoteProcessGroupStatus createRemoteGroupStatus(final RemoteProcessGroup remoteGroup, final RepositoryStatusReport statusReport, final Predicate<Authorizable> isAuthorized) { + final boolean isRemoteProcessGroupAuthorized = isAuthorized.evaluate(remoteGroup); + int receivedCount = 0; long receivedContentSize = 0L; int sentCount = 0; @@ -2430,8 +2501,8 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R final RemoteProcessGroupStatus status = new RemoteProcessGroupStatus(); status.setGroupId(remoteGroup.getProcessGroup().getIdentifier()); - status.setName(remoteGroup.getName()); - status.setTargetUri(remoteGroup.getTargetUri().toString()); + status.setName(isRemoteProcessGroupAuthorized ? remoteGroup.getName() : remoteGroup.getIdentifier()); + status.setTargetUri(isRemoteProcessGroupAuthorized ? remoteGroup.getTargetUri().toString() : null); long lineageMillis = 0L; int flowFilesRemoved = 0; @@ -2499,12 +2570,14 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R return status; } - private ProcessorStatus getProcessorStatus(final RepositoryStatusReport report, final ProcessorNode procNode) { + private ProcessorStatus getProcessorStatus(final RepositoryStatusReport report, final ProcessorNode procNode, final Predicate<Authorizable> isAuthorized) { + final boolean isProcessorAuthorized = isAuthorized.evaluate(procNode); + final ProcessorStatus status = new ProcessorStatus(); status.setId(procNode.getIdentifier()); status.setGroupId(procNode.getProcessGroup().getIdentifier()); - status.setName(procNode.getName()); - status.setType(procNode.getComponentType()); + status.setName(isProcessorAuthorized ? procNode.getName() : procNode.getIdentifier()); + status.setType(isProcessorAuthorized ? procNode.getComponentType() : "Processor"); final FlowFileEvent entry = report.getReportEntries().get(procNode.getIdentifier()); if (entry == null) { http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java index bbd9210..828bdfe 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/status/history/VolatileComponentStatusRepository.java @@ -16,8 +16,6 @@ */ package org.apache.nifi.controller.status.history; -import java.util.Date; - import org.apache.nifi.controller.status.ConnectionStatus; import org.apache.nifi.controller.status.ProcessGroupStatus; import org.apache.nifi.controller.status.ProcessorStatus; @@ -30,6 +28,8 @@ import org.apache.nifi.util.RingBuffer.ForEachEvaluator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Date; + public class VolatileComponentStatusRepository implements ComponentStatusRepository { public static final String NUM_DATA_POINTS_PROPERTY = "nifi.components.status.repository.buffer.size"; @@ -69,7 +69,7 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit @Override public StatusHistory getProcessorStatusHistory(final String processorId, final Date start, final Date end, final int preferredDataPoints) { final StandardStatusHistory history = new StandardStatusHistory(); - history.setComponentDetail("Id", processorId); + history.setComponentDetail(COMPONENT_DETAIL_ID, processorId); captures.forEach(new ForEachEvaluator<Capture>() { @Override @@ -80,9 +80,9 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit return true; } - history.setComponentDetail("Group Id", status.getGroupId()); - history.setComponentDetail("Name", status.getName()); - history.setComponentDetail("Type", status.getType()); + history.setComponentDetail(COMPONENT_DETAIL_GROUP_ID, status.getGroupId()); + history.setComponentDetail(COMPONENT_DETAIL_NAME, status.getName()); + history.setComponentDetail(COMPONENT_DETAIL_TYPE, status.getType()); final StandardStatusSnapshot snapshot = new StandardStatusSnapshot(); snapshot.setTimestamp(capture.getCaptureDate()); @@ -102,7 +102,7 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit @Override public StatusHistory getConnectionStatusHistory(final String connectionId, final Date start, final Date end, final int preferredDataPoints) { final StandardStatusHistory history = new StandardStatusHistory(); - history.setComponentDetail("Id", connectionId); + history.setComponentDetail(COMPONENT_DETAIL_ID, connectionId); captures.forEach(new ForEachEvaluator<Capture>() { @Override @@ -113,10 +113,10 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit return true; } - history.setComponentDetail("Group Id", status.getGroupId()); - history.setComponentDetail("Name", status.getName()); - history.setComponentDetail("Source Name", status.getSourceName()); - history.setComponentDetail("Destination Name", status.getDestinationName()); + history.setComponentDetail(COMPONENT_DETAIL_GROUP_ID, status.getGroupId()); + history.setComponentDetail(COMPONENT_DETAIL_NAME, status.getName()); + history.setComponentDetail(COMPONENT_DETAIL_SOURCE_NAME, status.getSourceName()); + history.setComponentDetail(COMPONENT_DETAIL_DESTINATION_NAME, status.getDestinationName()); final StandardStatusSnapshot snapshot = new StandardStatusSnapshot(); snapshot.setTimestamp(capture.getCaptureDate()); @@ -136,7 +136,7 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit @Override public StatusHistory getProcessGroupStatusHistory(final String processGroupId, final Date start, final Date end, final int preferredDataPoints) { final StandardStatusHistory history = new StandardStatusHistory(); - history.setComponentDetail("Id", processGroupId); + history.setComponentDetail(COMPONENT_DETAIL_ID, processGroupId); captures.forEach(new ForEachEvaluator<Capture>() { @Override @@ -147,7 +147,7 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit return true; } - history.setComponentDetail("Name", status.getName()); + history.setComponentDetail(COMPONENT_DETAIL_NAME, status.getName()); final StandardStatusSnapshot snapshot = new StandardStatusSnapshot(); snapshot.setTimestamp(capture.getCaptureDate()); @@ -167,7 +167,7 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit @Override public StatusHistory getRemoteProcessGroupStatusHistory(final String remoteGroupId, final Date start, final Date end, final int preferredDataPoints) { final StandardStatusHistory history = new StandardStatusHistory(); - history.setComponentDetail("Id", remoteGroupId); + history.setComponentDetail(COMPONENT_DETAIL_ID, remoteGroupId); captures.forEach(new ForEachEvaluator<Capture>() { @Override @@ -178,9 +178,9 @@ public class VolatileComponentStatusRepository implements ComponentStatusReposit return true; } - history.setComponentDetail("Group Id", status.getGroupId()); - history.setComponentDetail("Name", status.getName()); - history.setComponentDetail("Uri", status.getTargetUri()); + history.setComponentDetail(COMPONENT_DETAIL_GROUP_ID, status.getGroupId()); + history.setComponentDetail(COMPONENT_DETAIL_NAME, status.getName()); + history.setComponentDetail(COMPONENT_DETAIL_URI, status.getTargetUri()); final StandardStatusSnapshot snapshot = new StandardStatusSnapshot(); snapshot.setTimestamp(capture.getCaptureDate()); http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java new file mode 100644 index 0000000..e0faafb --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizableLookup.java @@ -0,0 +1,212 @@ +/* + * 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.controller.Snippet; + +public interface AuthorizableLookup { + + /** + * Get the authorizable Controller. + * + * @return authorizable + */ + Authorizable getController(); + + /** + * Get the authorizable Processor. + * + * @param id processor id + * @return authorizable + */ + Authorizable getProcessor(String id); + + /** + * Get the authorizable for querying Provenance. + * + * @return authorizable + */ + Authorizable getProvenance(); + + /** + * Get the authorizable for viewing/reseting Counters. + * + * @return authorizable + */ + Authorizable getCounters(); + + /** + * Get the authorizable InputPort. + * + * @param id input port id + * @return authorizable + */ + Authorizable getInputPort(String id); + + /** + * Get the authorizable OutputPort. + * + * @param id output port id + * @return authorizable + */ + Authorizable getOutputPort(String id); + + /** + * Get the authorizable Connection. + * + * @param id connection id + * @return authorizable + */ + ConnectionAuthorizable getConnection(String id); + + /** + * Get the authorizable ProcessGroup. + * + * @param id process group id + * @return authorizable + */ + Authorizable getProcessGroup(String id); + + /** + * Get the authorizable RemoteProcessGroup. + * + * @param id remote process group id + * @return authorizable + */ + Authorizable getRemoteProcessGroup(String id); + + /** + * Get the authorizable RemoteProcessGroup input port. + * + * @param remoteProcessGroupId remote process group id + * @param id input port id + * @return authorizable + */ + Authorizable getRemoteProcessGroupInputPort(String remoteProcessGroupId, String id); + + /** + * Get the authorizable RemoteProcessGroup output port. + * + * @param remoteProcessGroupId remote process group id + * @param id output port id + * @return authorizable + */ + Authorizable getRemoteProcessGroupOutputPort(String remoteProcessGroupId, String id); + + /** + * Get the authorizable Label. + * + * @param id label id + * @return authorizable + */ + Authorizable getLabel(String id); + + /** + * Get the authorizable Funnel. + * + * @param id funnel id + * @return authorizable + */ + Authorizable getFunnel(String id); + + /** + * Get the authorizable ControllerService. + * + * @param id controller service id + * @return authorizable + */ + Authorizable getControllerService(String id); + + /** + * Get the authorizable referencing component. + * + * @param controllerSeriveId controller service id + * @param id component id + * @return authorizable + */ + Authorizable getControllerServiceReferencingComponent(String controllerSeriveId, String id); + + /** + * Get the authorizable ReportingTask. + * + * @param id reporting task id + * @return authorizable + */ + Authorizable getReportingTask(String id); + + /** + * Get the authorizable Template. + * + * @param id template id + * @return authorizable + */ + Authorizable getTemplate(String id); + + /** + * Get the authorizable connectable. + * + * @param id connectable id + * @return authorizable + */ + Authorizable getConnectable(String id); + + /** + * Get the snippet of authorizable's. + * + * @param id snippet id + * @return snippet of authorizable's + */ + Snippet getSnippet(String id); + + /** + * Get the {@link Authorizable} that represents the resource of users and user groups. + * @return authorizable + */ + Authorizable getTenant(); + + /** + * Get the authorizable for access all policies. + * + * @return authorizable + */ + Authorizable getPolicies(); + + /** + * Get the authorizable for the policy of the policy id. + * + * @param id id + * @return authorizable + */ + Authorizable getAccessPolicyById(String id); + + /** + * Get the authorizable for the policy of the specified resource. + * + * @param resource resource + * @return authorizable + */ + Authorizable getAccessPolicyByResource(String resource); + + /** + * Get the authorizable of the specified resource. + * + * @param resource resource + * @return authorizable + */ + Authorizable getAuthorizableFromResource(final String resource); +} http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeAccess.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeAccess.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeAccess.java new file mode 100644 index 0000000..4e6661a --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeAccess.java @@ -0,0 +1,21 @@ +/* + * 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; + +public interface AuthorizeAccess { + void authorize(AuthorizableLookup lookup); +} http://git-wip-us.apache.org/repos/asf/nifi/blob/4a4d60e6/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ConnectionAuthorizable.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ConnectionAuthorizable.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ConnectionAuthorizable.java new file mode 100644 index 0000000..76a8833 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/ConnectionAuthorizable.java @@ -0,0 +1,54 @@ +/* + * 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.connectable.Connectable; +import org.apache.nifi.groups.ProcessGroup; + +/** + * Authorizable for a Connection and its Group, Source, and Destination. + */ +public interface ConnectionAuthorizable { + /** + * Returns the authorizable for this connection. Non null + * + * @return authorizable + */ + Authorizable getAuthorizable(); + + /** + * Returns the source. + * + * @return source + */ + Connectable getSource(); + + /** + * Returns the destination. + * + * @return destination + */ + Connectable getDestination(); + + /** + * Returns the parent process group. + * + * @return parent + */ + ProcessGroup getParentGroup(); +}
