From c0a253568ed0dabae42ecd14f8dfee7cec87667f Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Thu, 4 Aug 2016 17:43:52 -0400 Subject: [PATCH] NIFI-2486: - Authorizing individual bulletins being returned through the bulletin board. This closes #792 Signed-off-by: jpercivall --- .../nifi/web/StandardNiFiServiceFacade.java | 54 +++++++++++- .../org/apache/nifi/web/api/FlowResource.java | 8 +- .../js/nf/bulletin-board/nf-bulletin-board.js | 84 ++++++++++--------- 3 files changed, 102 insertions(+), 44 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index 8ce1f3e4ad..a9124794a8 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -2184,6 +2184,47 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { return controllerFacade.getProcessorStatusHistory(id); } + private boolean authorizeBulletin(final Bulletin bulletin) { + final String sourceId = bulletin.getSourceId(); + final ComponentType type = bulletin.getSourceType(); + + final Authorizable authorizable; + try { + switch (type) { + case PROCESSOR: + authorizable = authorizableLookup.getProcessor(sourceId); + break; + case REPORTING_TASK: + authorizable = authorizableLookup.getReportingTask(sourceId); + break; + case CONTROLLER_SERVICE: + authorizable = authorizableLookup.getControllerService(sourceId); + break; + case FLOW_CONTROLLER: + authorizable = controllerFacade; + break; + case INPUT_PORT: + authorizable = authorizableLookup.getInputPort(sourceId); + break; + case OUTPUT_PORT: + authorizable = authorizableLookup.getOutputPort(sourceId); + break; + case REMOTE_PROCESS_GROUP: + authorizable = authorizableLookup.getRemoteProcessGroup(sourceId); + break; + default: + throw new WebApplicationException(Response.serverError().entity("An unexpected type of component is the source of this bulletin.").build()); + } + } catch (final ResourceNotFoundException e) { + // if the underlying component is gone, disallow + return false; + } + + // perform the authorization + final AuthorizationResult result = authorizable.checkAuthorization(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); + return Result.Approved.equals(result.getResult()); + } + @Override public BulletinBoardDTO getBulletinBoard(final BulletinQueryDTO query) { // build the query @@ -2203,7 +2244,18 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { // exact results we want but in reverse order final List bulletins = new ArrayList<>(); for (final ListIterator bulletinIter = results.listIterator(results.size()); bulletinIter.hasPrevious(); ) { - bulletins.add(dtoFactory.createBulletinDto(bulletinIter.previous())); + final Bulletin bulletin = bulletinIter.previous(); + + if (authorizeBulletin(bulletin)) { + bulletins.add(dtoFactory.createBulletinDto(bulletin)); + } else { + final BulletinDTO bulletinDTO = new BulletinDTO(); + bulletinDTO.setTimestamp(bulletin.getTimestamp()); + bulletinDTO.setId(bulletin.getId()); + bulletinDTO.setSourceId(bulletin.getSourceId()); + bulletinDTO.setGroupId(bulletin.getGroupId()); + bulletins.add(bulletinDTO); + } } // create the bulletin board diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java index e48bdc3a69..151a9c82a3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java @@ -820,7 +820,10 @@ public class FlowResource extends ApplicationResource { value = "Retrieves Controller level bulletins", response = ControllerBulletinsEntity.class, authorizations = { - @Authorization(value = "Read - /flow", type = "") + @Authorization(value = "Read - /flow", type = ""), + @Authorization(value = "Read - /controller - For controller bulletins", type = ""), + @Authorization(value = "Read - /controller-services/{uuid} - For controller service bulletins", type = ""), + @Authorization(value = "Read - /reporting-tasks/{uuid} - For reporting task bulletins", type = "") } ) @ApiResponses( @@ -1113,7 +1116,8 @@ public class FlowResource extends ApplicationResource { value = "Gets current bulletins", response = BulletinBoardEntity.class, authorizations = { - @Authorization(value = "Read - /flow", type = "") + @Authorization(value = "Read - /flow", type = ""), + @Authorization(value = "Read - /{component-type}/{uuid} - For component specific bulletins", type = "") } ) @ApiResponses( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/bulletin-board/nf-bulletin-board.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/bulletin-board/nf-bulletin-board.js index c7ee9de5c8..88f6c22ce2 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/bulletin-board/nf-bulletin-board.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/bulletin-board/nf-bulletin-board.js @@ -355,50 +355,52 @@ nf.ng.BulletinBoardCtrl = function (serviceProvider) { // append each bulletin $.each(bulletins, function (i, bulletin) { - // format the severity - var severityStyle = 'bulletin-normal'; - if (bulletin.level === 'ERROR') { - severityStyle = 'bulletin-error'; - } else if (bulletin.level === 'WARN' || bulletin.level === 'WARNING') { - severityStyle = 'bulletin-warn'; - } - - // format the source id - var source; - if (nf.Common.isDefinedAndNotNull(bulletin.sourceId) && nf.Common.isDefinedAndNotNull(bulletin.groupId) && top !== window) { - source = $('').text(bulletin.sourceId).on('click', function () { - goToSource(bulletin.groupId, bulletin.sourceId); - }); - } else { - var sourceId = bulletin.sourceId; - if (nf.Common.isUndefined(sourceId) || nf.Common.isNull(sourceId)) { - sourceId = ''; + if (!nf.Common.isBlank(bulletin.level)) { + // format the severity + var severityStyle = 'bulletin-normal'; + if (bulletin.level === 'ERROR') { + severityStyle = 'bulletin-error'; + } else if (bulletin.level === 'WARN' || bulletin.level === 'WARNING') { + severityStyle = 'bulletin-warn'; } - source = $('
').text(sourceId); + + // format the source id + var source; + if (nf.Common.isDefinedAndNotNull(bulletin.sourceId) && nf.Common.isDefinedAndNotNull(bulletin.groupId) && top !== window) { + source = $('').text(bulletin.sourceId).on('click', function () { + goToSource(bulletin.groupId, bulletin.sourceId); + }); + } else { + var sourceId = bulletin.sourceId; + if (nf.Common.isUndefined(sourceId) || nf.Common.isNull(sourceId)) { + sourceId = ''; + } + source = $('
').text(sourceId); + } + + // build the markup for this bulletin + var bulletinMarkup = $('
'); + + // build the markup for this bulletins info + var bulletinInfoMarkup = $('
').appendTo(bulletinMarkup); + $('
').text(bulletin.timestamp).appendTo(bulletinInfoMarkup); + $('
').addClass(severityStyle).text(bulletin.level).appendTo(bulletinInfoMarkup); + source.appendTo(bulletinInfoMarkup); + $('
').appendTo(bulletinInfoMarkup); + + // format the node address if applicable + if (nf.Common.isDefinedAndNotNull(bulletin.nodeAddress)) { + $('
').text(bulletin.nodeAddress).appendTo(bulletinMarkup); + } + + // add the bulletin message (treat as text) + $('
').text(bulletin.message).appendTo(bulletinMarkup);
+                            $('
').appendTo(bulletinMarkup); + + // append the content + content.push(bulletinMarkup.get(0)); } - // build the markup for this bulletin - var bulletinMarkup = $('
'); - - // build the markup for this bulletins info - var bulletinInfoMarkup = $('
').appendTo(bulletinMarkup); - $('
').text(bulletin.timestamp).appendTo(bulletinInfoMarkup); - $('
').addClass(severityStyle).text(bulletin.level).appendTo(bulletinInfoMarkup); - source.appendTo(bulletinInfoMarkup); - $('
').appendTo(bulletinInfoMarkup); - - // format the node address if applicable - if (nf.Common.isDefinedAndNotNull(bulletin.nodeAddress)) { - $('
').text(bulletin.nodeAddress).appendTo(bulletinMarkup); - } - - // add the bulletin message (treat as text) - $('
').text(bulletin.message).appendTo(bulletinMarkup);
-                        $('
').appendTo(bulletinMarkup); - - // append the content - content.push(bulletinMarkup.get(0)); - // record the id of the last bulletin in this request if (i + 1 === bulletins.length) { lastBulletin = bulletin.id;