mirror of https://github.com/apache/nifi.git
NIFI-2501: - Ensuring users can access the controller service list regardless of permissions on the corresponding process group or controller. - Better handling the case where the user had write permissions but no read permissions. - Returning to the appropriate controller service listing after going to the usage page.
This closes #835 Signed-off-by: jpercivall <joepercivall@yahoo.com>
This commit is contained in:
parent
51c566ffc8
commit
d45114e48d
|
@ -20,11 +20,8 @@ import com.wordnik.swagger.annotations.ApiModelProperty;
|
|||
import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
|
||||
import org.apache.nifi.web.api.dto.PermissionsDTO;
|
||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||
import org.apache.nifi.web.api.dto.util.TimeAdapter;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ControllerConfigurationDTO.
|
||||
|
@ -32,7 +29,6 @@ import java.util.Date;
|
|||
@XmlRootElement(name = "controllerConfigurationEntity")
|
||||
public class ControllerConfigurationEntity extends Entity implements Permissible<ControllerConfigurationDTO> {
|
||||
|
||||
private Date currentTime;
|
||||
private ControllerConfigurationDTO controllerConfiguration;
|
||||
private RevisionDTO revision;
|
||||
private PermissionsDTO permissions;
|
||||
|
@ -87,18 +83,4 @@ public class ControllerConfigurationEntity extends Entity implements Permissible
|
|||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current time on the server
|
||||
*/
|
||||
@XmlJavaTypeAdapter(TimeAdapter.class)
|
||||
@ApiModelProperty(
|
||||
value = "The current time on the system."
|
||||
)
|
||||
public Date getCurrentTime() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
public void setCurrentTime(Date currentTime) {
|
||||
this.currentTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,12 @@
|
|||
*/
|
||||
package org.apache.nifi.web.api.entity;
|
||||
|
||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.web.api.dto.util.TimeAdapter;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -25,6 +30,7 @@ import java.util.Set;
|
|||
@XmlRootElement(name = "controllerServicesEntity")
|
||||
public class ControllerServicesEntity extends Entity {
|
||||
|
||||
private Date currentTime;
|
||||
private Set<ControllerServiceEntity> controllerServices;
|
||||
|
||||
/**
|
||||
|
@ -38,4 +44,19 @@ public class ControllerServicesEntity extends Entity {
|
|||
this.controllerServices = controllerServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current time on the server
|
||||
*/
|
||||
@XmlJavaTypeAdapter(TimeAdapter.class)
|
||||
@ApiModelProperty(
|
||||
value = "The current time on the system."
|
||||
)
|
||||
public Date getCurrentTime() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
public void setCurrentTime(Date currentTime) {
|
||||
this.currentTime = currentTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,11 +19,8 @@ package org.apache.nifi.web.api.entity;
|
|||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
|
||||
import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.util.TimeAdapter;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessGroupDTO.
|
||||
|
@ -34,7 +31,6 @@ public class ProcessGroupEntity extends ComponentEntity implements Permissible<P
|
|||
private ProcessGroupDTO component;
|
||||
private ProcessGroupStatusDTO status;
|
||||
|
||||
private Date currentTime;
|
||||
private Integer runningCount;
|
||||
private Integer stoppedCount;
|
||||
private Integer invalidCount;
|
||||
|
@ -184,18 +180,4 @@ public class ProcessGroupEntity extends ComponentEntity implements Permissible<P
|
|||
this.inactiveRemotePortCount = inactiveRemotePortCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current time on the server
|
||||
*/
|
||||
@XmlJavaTypeAdapter(TimeAdapter.class)
|
||||
@ApiModelProperty(
|
||||
value = "The current time on the system."
|
||||
)
|
||||
public Date getCurrentTime() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
public void setCurrentTime(Date currentTime) {
|
||||
this.currentTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -417,6 +417,7 @@ public class FlowResource extends ApplicationResource {
|
|||
|
||||
// create the response entity
|
||||
final ControllerServicesEntity entity = new ControllerServicesEntity();
|
||||
entity.setCurrentTime(new Date());
|
||||
entity.setControllerServices(controllerServices);
|
||||
|
||||
// generate the response
|
||||
|
@ -467,6 +468,7 @@ public class FlowResource extends ApplicationResource {
|
|||
|
||||
// create the response entity
|
||||
final ControllerServicesEntity entity = new ControllerServicesEntity();
|
||||
entity.setCurrentTime(new Date());
|
||||
entity.setControllerServices(controllerServices);
|
||||
|
||||
// generate the response
|
||||
|
|
|
@ -152,7 +152,6 @@ public final class EntityFactory {
|
|||
public ControllerConfigurationEntity createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
|
||||
final ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
|
||||
entity.setRevision(revision);
|
||||
entity.setCurrentTime(new Date());
|
||||
if (dto != null) {
|
||||
entity.setPermissions(permissions);
|
||||
if (permissions != null && permissions.getCanRead()) {
|
||||
|
@ -209,7 +208,6 @@ public final class EntityFactory {
|
|||
final ProcessGroupStatusDTO status, final List<BulletinDTO> bulletins) {
|
||||
final ProcessGroupEntity entity = new ProcessGroupEntity();
|
||||
entity.setRevision(revision);
|
||||
entity.setCurrentTime(new Date());
|
||||
if (dto != null) {
|
||||
entity.setPermissions(permissions);
|
||||
entity.setStatus(status);
|
||||
|
|
|
@ -127,7 +127,6 @@
|
|||
<jsp:include page="/WEB-INF/partials/processor-details.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/process-group-configuration.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/policy-management.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/process-group-details.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/remote-process-group-configuration.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/remote-process-group-details.jsp"/>
|
||||
<jsp:include page="/WEB-INF/partials/canvas/remote-process-group-ports.jsp"/>
|
||||
|
|
|
@ -128,8 +128,7 @@
|
|||
<md-menu-divider></md-menu-divider>
|
||||
<md-menu-item layout-align="space-around center">
|
||||
<a id="flow-settings-link"
|
||||
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.controllerSettings.shell.launch();"
|
||||
ng-class="{disabled: !appCtrl.nf.Common.canAccessController()}">
|
||||
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.controllerSettings.shell.launch();">
|
||||
<i class="fa fa-wrench"></i>Controller Settings
|
||||
</a>
|
||||
</md-menu-item>
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<%--
|
||||
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.
|
||||
--%>
|
||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||
<div id="process-group-details" class="hidden medium-dialog">
|
||||
<div class="dialog-content">
|
||||
<div class="setting">
|
||||
<div class="setting-name">Name</div>
|
||||
<div class="setting-field">
|
||||
<span id="read-only-process-group-name"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Id</div>
|
||||
<div class="setting-field">
|
||||
<span id="read-only-process-group-id"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Comments</div>
|
||||
<div class="setting-field">
|
||||
<div id="read-only-process-group-comments"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -123,11 +123,9 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
|
|||
* Launch the settings shell.
|
||||
*/
|
||||
launch: function () {
|
||||
if (nf.Common.canAccessController()) {
|
||||
nf.Settings.showSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -294,7 +294,7 @@ nf.ng.Canvas.GraphControlsCtrl = function (serviceProvider, navigateCtrl, operat
|
|||
var selection = nf.CanvasUtils.getSelection();
|
||||
|
||||
if (selection.empty()) {
|
||||
return nf.Canvas.canRead() || nf.Canvas.canWrite();
|
||||
return true;
|
||||
}
|
||||
|
||||
return nf.CanvasUtils.isConfigurable(selection) || nf.CanvasUtils.hasDetails(selection);
|
||||
|
|
|
@ -936,6 +936,10 @@ nf.CanvasUtils = (function () {
|
|||
if (selection.size() !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nf.CanvasUtils.isProcessGroup(selection)) {
|
||||
return true;
|
||||
}
|
||||
if (nf.CanvasUtils.canRead(selection) === false || nf.CanvasUtils.canModify(selection) === false) {
|
||||
return false;
|
||||
}
|
||||
|
@ -956,16 +960,19 @@ nf.CanvasUtils = (function () {
|
|||
if (selection.size() !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nf.CanvasUtils.isProcessGroup(selection)) {
|
||||
return true;
|
||||
}
|
||||
if (nf.CanvasUtils.canRead(selection) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nf.CanvasUtils.canModify(selection)) {
|
||||
if (nf.CanvasUtils.isProcessor(selection) || nf.CanvasUtils.isInputPort(selection) || nf.CanvasUtils.isOutputPort(selection) || nf.CanvasUtils.isRemoteProcessGroup(selection) || nf.CanvasUtils.isConnection(selection)) {
|
||||
return !nf.CanvasUtils.isConfigurable(selection);
|
||||
}
|
||||
} else {
|
||||
return nf.CanvasUtils.isProcessor(selection) || nf.CanvasUtils.isConnection(selection) || nf.CanvasUtils.isProcessGroup(selection) || nf.CanvasUtils.isInputPort(selection) || nf.CanvasUtils.isOutputPort(selection) || nf.CanvasUtils.isRemoteProcessGroup(selection);
|
||||
return nf.CanvasUtils.isProcessor(selection) || nf.CanvasUtils.isConnection(selection) || nf.CanvasUtils.isInputPort(selection) || nf.CanvasUtils.isOutputPort(selection) || nf.CanvasUtils.isRemoteProcessGroup(selection);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -668,7 +668,20 @@ nf.ControllerServices = (function () {
|
|||
nf.Shell.showPage('../nifi-docs/documentation?' + $.param({
|
||||
select: nf.Common.substringAfterLast(controllerServiceEntity.component.type, '.')
|
||||
})).done(function() {
|
||||
if (nf.Common.isDefinedAndNotNull(controllerServiceEntity.component.parentGroupId)) {
|
||||
var groupId;
|
||||
var processGroup = nf.ProcessGroup.get(controllerServiceEntity.component.parentGroupId);
|
||||
if (nf.Common.isDefinedAndNotNull(processGroup)) {
|
||||
groupId = processGroup.id;
|
||||
} else {
|
||||
groupId = nf.Canvas.getGroupId();
|
||||
}
|
||||
|
||||
// reload the corresponding group
|
||||
nf.ProcessGroupConfiguration.showConfiguration(groupId);
|
||||
} else {
|
||||
nf.Settings.showSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,9 +122,6 @@ nf.ProcessGroupConfiguration = (function () {
|
|||
// store the process group
|
||||
$('#process-group-configuration').data('process-group', response);
|
||||
|
||||
// update the current time
|
||||
$('#process-group-configuration-last-refreshed').text(response.currentTime);
|
||||
|
||||
if (response.permissions.canWrite) {
|
||||
var processGroup = response.component;
|
||||
|
||||
|
@ -153,6 +150,17 @@ nf.ProcessGroupConfiguration = (function () {
|
|||
deferred.resolve();
|
||||
}).fail(function (xhr, status, error) {
|
||||
if (xhr.status === 403) {
|
||||
if (groupId === nf.Canvas.getGroupId()) {
|
||||
$('#process-group-configuration').data('process-group', {
|
||||
'permissions': {
|
||||
canRead: false,
|
||||
canWrite: nf.Canvas.canWrite()
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#process-group-configuration').data('process-group', nf.ProcessGroup.get(groupId));
|
||||
}
|
||||
|
||||
setUnauthorizedText();
|
||||
setEditable(false);
|
||||
deferred.resolve();
|
||||
|
@ -167,7 +175,12 @@ nf.ProcessGroupConfiguration = (function () {
|
|||
var controllerServices = nf.ControllerServices.loadControllerServices(controllerServicesUri, getControllerServicesTable());
|
||||
|
||||
// wait for everything to complete
|
||||
return $.when(processGroup, controllerServices).fail(nf.Common.handleAjaxError);
|
||||
return $.when(processGroup, controllerServices).done(function (processGroupResult, controllerServicesResult) {
|
||||
var controllerServicesResponse = controllerServicesResult[0];
|
||||
|
||||
// update the current time
|
||||
$('#process-group-configuration-last-refreshed').text(controllerServicesResponse.currentTime);
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -855,9 +855,6 @@ nf.Settings = (function () {
|
|||
url: config.urls.controllerConfig,
|
||||
dataType: 'json'
|
||||
}).done(function (response) {
|
||||
// update the current time
|
||||
$('#settings-last-refreshed').text(response.currentTime);
|
||||
|
||||
if (response.permissions.canWrite) {
|
||||
// populate the settings
|
||||
$('#maximum-timer-driven-thread-count-field').removeClass('unset').val(response.component.maxTimerDrivenThreadCount);
|
||||
|
@ -900,7 +897,12 @@ nf.Settings = (function () {
|
|||
var reportingTasks = loadReportingTasks();
|
||||
|
||||
// return a deferred for all parts of the settings
|
||||
return $.when(settings, controllerServices, reportingTasks).fail(nf.Common.handleAjaxError);
|
||||
return $.when(settings, controllerServices, reportingTasks).done(function (settingsResult, controllerServicesResult) {
|
||||
var controllerServicesResponse = controllerServicesResult[0];
|
||||
|
||||
// update the current time
|
||||
$('#settings-last-refreshed').text(controllerServicesResponse.currentTime);
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -983,7 +985,13 @@ nf.Settings = (function () {
|
|||
$('#new-service-or-task').hide();
|
||||
$('#settings-save').show();
|
||||
} else {
|
||||
if (nf.Common.canModifyController()) {
|
||||
var canModifyController = false;
|
||||
if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
|
||||
// only consider write permissions for creating new controller services/reporting tasks
|
||||
canModifyController = nf.Common.currentUser.controllerPermissions.canWrite === true;
|
||||
}
|
||||
|
||||
if (canModifyController) {
|
||||
$('#new-service-or-task').show();
|
||||
$('div.controller-settings-table').css('top', '32px');
|
||||
|
||||
|
|
Loading…
Reference in New Issue