NIFI-2849:

- Showing process group name when possible.
- Providing a link to jump to the process group defined in the effective policy.
- Preventing editing an inherited policy.
- When overriding a policy, allowing the user to indicate if the policy should be empty or should copy the user/groups of the inherited policy.

This closes #1090.

Signed-off-by: Andy LoPresto <alopresto@apache.org>
This commit is contained in:
Matt Gilman 2016-10-04 15:30:41 -04:00 committed by Andy LoPresto
parent 540ef63efa
commit 4a4c87fa15
No known key found for this signature in database
GPG Key ID: 3C6EF65B2F7DEF69
7 changed files with 149 additions and 39 deletions

View File

@ -28,7 +28,7 @@ import java.util.Objects;
/**
* A base type for request/response entities.
*/
@XmlRootElement(name = "entity")
@XmlRootElement(name = "componentEntity")
public class ComponentEntity extends Entity {
private RevisionDTO revision;

View File

@ -125,6 +125,7 @@
<jsp:include page="/WEB-INF/partials/canvas/processor-configuration.jsp"/>
<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/override-policy-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/policy-management.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"/>

View File

@ -0,0 +1,26 @@
<%--
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="override-policy-dialog" class="hidden small-dialog">
<div class="dialog-content">
<div>Do you want to override with a copy of the inherited policy or an empty policy?</div>
<div style="margin-top: 10px;">
<label for="copy-policy-radio-button"><input id="copy-policy-radio-button" type="radio" name="emptyOrCopy" value="copy" checked="checked"/> Copy</label>
<label for="empty-policy-radio-button"><input id="empty-policy-radio-button" type="radio" name="emptyOrCopy" value="policy"/> Empty</label>
</div>
</div>
</div>

View File

@ -222,3 +222,12 @@ div.policy-selected-component-type {
font-family: Roboto;
font-size: 13px;
}
/*
override policy dialog
*/
#override-policy-dialog label {
font-family: inherit;
letter-spacing: inherit;
}

View File

@ -81,8 +81,7 @@ nf.ng.TemplateComponent = function (serviceProvider) {
// configure the instantiate template dialog
this.getElement().modal({
scrollableContentStyle: 'scrollable',
headerText: 'Add Template',
overlayBackgroud: false
headerText: 'Add Template'
});
},

View File

@ -229,9 +229,52 @@ nf.PolicyManagement = (function () {
};
var initPolicyTable = function () {
// create/override a policy
$('#create-policy-link, #override-policy-link, #add-local-admin-link').on('click', function () {
createPolicy();
$('#override-policy-dialog').modal({
headerText: 'Override Policy',
buttons: [{
buttonText: 'Override',
color: {
base: '#728E9B',
hover: '#004849',
text: '#ffffff'
},
handler: {
click: function () {
// create the policy, copying if appropriate
createPolicy($('#copy-policy-radio-button').is(':checked'));
$(this).modal('hide');
}
}
}, {
buttonText: 'Cancel',
color: {
base: '#E3E8EB',
hover: '#C7D2D7',
text: '#004849'
},
handler: {
click: function () {
$(this).modal('hide');
}
}
}],
handler: {
close: function () {
// reset the radio button
$('#copy-policy-radio-button').prop('checked', true);
}
}
});
// create/add a policy
$('#create-policy-link, #add-local-admin-link').on('click', function () {
createPolicy(false);
});
// override a policy
$('#override-policy-link').on('click', function () {
$('#override-policy-dialog').modal('show');
});
// policy type listing
@ -413,7 +456,9 @@ nf.PolicyManagement = (function () {
// see if the user has permissions for the current policy
var currentEntity = $('#policy-table').data('policy');
if (currentEntity.permissions.canWrite === true) {
var resourceComponentId = nf.Common.substringAfterLast(currentEntity.component.resource, '/');
var selectedComponentId = $('#selected-policy-component-id').text();
if (currentEntity.permissions.canWrite === true && resourceComponentId === selectedComponentId) {
markup += '<div title="Remove" class="pointer delete-user fa fa-trash"></div>';
}
@ -659,13 +704,30 @@ nf.PolicyManagement = (function () {
*
* @param resource
*/
var convertToHumanReadableResource = function (resource) {
var getResourceMessage = function (resource) {
if (resource === '/policies') {
return 'all policies';
return $('<span>Showing effective policy inherited from all policies.</span>');
} else if (resource === '/controller') {
return 'the controller';
return $('<span>Showing effective policy inherited from the controller.</span>');
} else {
return 'Process Group ' + nf.Common.substringAfterLast(resource, '/');
// extract the group id
var processGroupId = nf.Common.substringAfterLast(resource, '/');
var processGroupName = processGroupId;
// attempt to resolve the group name
var breadcrumbs = nf.ng.Bridge.injector.get('breadcrumbsCtrl').getBreadcrumbs();
$.each(breadcrumbs, function (_, breadcrumbEntity) {
if (breadcrumbEntity.id === processGroupId) {
processGroupName = breadcrumbEntity.label;
return false;
}
});
// build the mark up
return $('<span>Showing effective policy inherited from Process Group </span>').append($('<span class="link"></span>').text(processGroupName).on('click', function () {
$('#shell-close-button').click();
nf.CanvasUtils.enterGroup(processGroupId);
})).append('<span>.</span>');
}
};
@ -686,21 +748,22 @@ nf.PolicyManagement = (function () {
// store the current policy version
$('#policy-table').data('policy', policyEntity);
// allow modification if allowed
$('#new-policy-user-button').prop('disabled', policyEntity.permissions.canWrite === false);
// see if the policy is for this resource
if (resourceAndAction.resource === policy.resource) {
// allow remove when policy is not inherited
$('#delete-policy-button').prop('disabled', policyEntity.permissions.canWrite === false);
// allow modification if allowed
$('#new-policy-user-button').prop('disabled', policyEntity.permissions.canWrite === false);
} else {
$('#policy-message').text('Showing effective policy inherited from ' + convertToHumanReadableResource(policy.resource) + '. ');
$('#policy-message').append(getResourceMessage(policy.resource));
// policy is inherited, we do not know if the user has permissions to modify the desired policy... show button and let server decide
$('#override-policy-message').show();
// to not support policy deletion
// do not support policy deletion/modification
$('#delete-policy-button').prop('disabled', true);
$('#new-policy-user-button').prop('disabled', true);
}
// populate the table
@ -732,8 +795,6 @@ nf.PolicyManagement = (function () {
// if the return policy is for the desired policy (not inherited, show it)
if (resourceAndAction.resource === policy.resource) {
$('#policy-message').text(policy.resource);
// populate the policy details
populatePolicy(policyEntity);
} else {
@ -803,10 +864,6 @@ nf.PolicyManagement = (function () {
// ensure appropriate actions for the loaded policy
if (policyEntity.permissions.canRead === true) {
var policy = policyEntity.component;
$('#policy-message').text(policy.resource);
// populate the policy details
populatePolicy(policyEntity);
} else {
@ -856,10 +913,33 @@ nf.PolicyManagement = (function () {
/**
* Creates a new policy for the current selection.
*
* @param copyInheritedPolicy Whether or not to copy the inherited policy
*/
var createPolicy = function () {
var createPolicy = function (copyInheritedPolicy) {
var resourceAndAction = getSelectedResourceAndAction();
var users = [];
var userGroups = [];
if (copyInheritedPolicy === true) {
var policyGrid = $('#policy-table').data('gridInstance');
var policyData = policyGrid.getData();
var items = policyData.getItems();
$.each(items, function (_, item) {
var itemCopy = $.extend({}, item);
if (itemCopy.type === 'user') {
users.push(itemCopy);
} else {
userGroups.push(itemCopy);
}
// remove the type as it was added client side to render differently and is not part of the actual schema
delete itemCopy.type;
});
}
var entity = {
'revision': nf.Client.getRevision({
'revision': {
@ -868,7 +948,9 @@ nf.PolicyManagement = (function () {
}),
'component': {
'action': resourceAndAction.action,
'resource': resourceAndAction.resource
'resource': resourceAndAction.resource,
'users': users,
'userGroups': userGroups
}
};
@ -881,10 +963,6 @@ nf.PolicyManagement = (function () {
}).done(function (policyEntity) {
// ensure appropriate actions for the loaded policy
if (policyEntity.permissions.canRead === true) {
var policy = policyEntity.component;
$('#policy-message').text(policy.resource);
// populate the policy details
populatePolicy(policyEntity);
} else {
@ -907,14 +985,16 @@ nf.PolicyManagement = (function () {
var items = policyData.getItems();
$.each(items, function (_, item) {
if (item.type === 'user') {
users.push(item);
var itemCopy = $.extend({}, item);
if (itemCopy.type === 'user') {
users.push(itemCopy);
} else {
userGroups.push(item);
userGroups.push(itemCopy);
}
// remove the type as it was added client side to render differently
delete item.type;
// remove the type as it was added client side to render differently and is not part of the actual schema
delete itemCopy.type;
});
var currentEntity = $('#policy-table').data('policy');
@ -937,10 +1017,6 @@ nf.PolicyManagement = (function () {
}).done(function (policyEntity) {
// ensure appropriate actions for the loaded policy
if (policyEntity.permissions.canRead === true) {
var policy = policyEntity.component;
$('#policy-message').text(policy.resource);
// populate the policy details
populatePolicy(policyEntity);
} else {
@ -982,7 +1058,7 @@ nf.PolicyManagement = (function () {
* Reset the policy message.
*/
var resetPolicyMessage = function () {
$('#policy-message').text('');
$('#policy-message').text('').empty();
$('#new-policy-message').hide();
$('#override-policy-message').hide();
$('#add-local-admin-message').hide();

View File

@ -94,7 +94,6 @@ nf.Dialog = (function () {
options = $.extend({
headerText: '',
dialogContent: '',
overlayBackgrond: true,
yesText: 'Yes',
noText: 'No'
}, options);