You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2019/03/25 21:30:14 UTC
[ranger] branch master updated: RANGER-2354: Add custom condition
at policy level
This is an automated email from the ASF dual-hosted git repository.
rmani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 9ea9cc9 RANGER-2354: Add custom condition at policy level
9ea9cc9 is described below
commit 9ea9cc9a09b224d495b7131b87f36f709ac0cfae
Author: Nitin Galave <ni...@apache.org>
AuthorDate: Mon Mar 25 12:29:01 2019 +0530
RANGER-2354: Add custom condition at policy level
Signed-off-by: rmani <rm...@hortonworks.com>
---
.../webapp/scripts/modules/globalize/message/en.js | 6 +-
.../src/main/webapp/scripts/utils/XAUtils.js | 11 ++
.../views/policies/RangerPolicyConditions.js | 114 +++++++++++++++++++++
.../scripts/views/policies/RangerPolicyForm.js | 99 +++++++++++++++---
.../scripts/views/policies/RangerPolicyRO.js | 3 +
security-admin/src/main/webapp/styles/xa.css | 33 ++++++
.../src/main/webapp/templates/helpers/XAHelpers.js | 13 +++
.../policies/PolicyConditionsItem_tmpl.html | 20 ++++
.../templates/policies/RangerPolicyForm_tmpl.html | 63 +++++++++---
.../templates/policies/RangerPolicyRO_tmpl.html | 16 ++-
10 files changed, 344 insertions(+), 34 deletions(-)
diff --git a/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js b/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
index 03412d5..d4d87d7 100644
--- a/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
+++ b/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
@@ -261,10 +261,12 @@ define(function(require) {
groupSearchFilter : 'Group search filter',
startDate : 'Start Date',
endDate : 'End Date',
- addValidityPeriod : 'Add Validity Period',
- editValidityPeriod : 'Edit Validity Period',
+ addValidityPeriod : ' Add Validity Period',
+ editValidityPeriod : ' Edit Validity Period',
totalUsersSynced : 'Total number of users synced',
totalGroupsSynced : 'Total number of groups synced',
+ addPolicyCondition : 'Add Policy Condition',
+ editPolicyCondition : 'Edit Policy Condition'
},
btn : {
diff --git a/security-admin/src/main/webapp/scripts/utils/XAUtils.js b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
index 57e72ba..b14f4b9 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
@@ -1486,5 +1486,16 @@ define(function(require) {
return opts;
}
+
+ //get policy conditions details
+ XAUtils.getPolicyConditionDetails = function(policyCondtions, serviceDef){
+ var condtionsDetails = [];
+ _.each(policyCondtions, function(val){
+ var conditionsVal = serviceDef.get('policyConditions').find(function(m){return m.name == val.type});
+ condtionsDetails.push({'name' : conditionsVal.label, 'values' : val.values});
+ })
+ return condtionsDetails;
+ }
+
return XAUtils;
});
\ No newline at end of file
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyConditions.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyConditions.js
new file mode 100644
index 0000000..d6c5295
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyConditions.js
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+define(function(require){
+ 'use strict';
+
+ var Backbone = require('backbone');
+ var App = require('App');
+ var XAUtil = require('utils/XAUtils');
+ var XAEnums = require('utils/XAEnums');
+ var XALinks = require('modules/XALinks');
+ var PolicyConditionsItem = require('hbs!tmpl/policies/PolicyConditionsItem_tmpl');
+
+ var PolicyConditionsItem = Backbone.Marionette.ItemView.extend({
+ _msvName : 'PolicyConditionsItem',
+ template : require('hbs!tmpl/policies/PolicyConditionsItem_tmpl'),
+ templateHelpers : function(){
+ return {
+ policyConditions : this.rangerServiceDefModel.get('policyConditions')
+ }
+ },
+
+ ui : {},
+
+ events : function(){
+ var events = {};
+ return events;
+ },
+
+ initialize : function(options) {
+ _.extend(this, _.pick(options,'rangerServiceDefModel','model'));
+ },
+
+ onRender : function() {
+ var that = this;
+ if(this.model && this.model.get('conditions') && !_.isEmpty(this.model.get('conditions'))){
+ var that = this;
+ _.each(this.$el.find('[data-id="textAreaContainer"]'), function(e, context){
+ var inputFieldName = e.name;
+ that.model.get('conditions').find(function(m){
+ if(m.type == inputFieldName){
+ e.value = m.values;
+ }
+ })
+ });
+ that.$el.find('[data-id="inputField"]').val([" "]);
+ }
+ _.each(this.$el.find('[data-id="inputField"]'), function(e, context){
+ var inputFieldName = e.name , tag= [], option = {};
+ var isSingleValueInput = XAUtil.isSinglevValueInput(that.rangerServiceDefModel.get('policyConditions').find(function(e)
+ {return e.name == inputFieldName}));
+ if(that.model && that.model.get('conditions') && !_.isEmpty(that.model.get('conditions'))){
+ that.model.get('conditions').find(function(m){
+ if(m.type == inputFieldName){
+ tag = _.map(m.values.filter(Boolean), function(val){
+ if(!_.isEmpty(val)){
+ return{'id':_.escape(val), 'text':_.escape(val)}
+ }
+ });
+ }
+ })
+ }
+ option = {
+ closeOnSelect : true,
+ data:[],
+ width :'450px',
+ allowClear: true,
+ tokenSeparators: ["," , " "],
+ minimumInputLength: 1,
+ multiple: true,
+ initSelection : function (element, callback) {
+ callback(tag);
+ },
+ createSearchChoice: function(term, data) {
+ term = _.escape(term);
+ if ($(data).filter(function() {
+ return this.text.localeCompare(term) === 0;
+ }).length === 0) {
+ if($.inArray(term, this.val()) >= 0){
+ return null;
+ }else{
+ return {
+ id : term,
+ text: term
+ };
+ }
+ }
+ },
+ }
+ if(isSingleValueInput){
+ option['maximumSelectionSize'] = 1;
+ }
+ that.$el.find('[name='+inputFieldName+']').select2(option);
+ });
+ }
+ });
+ return PolicyConditionsItem;
+});
\ No newline at end of file
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
index 931babf..a1a1311 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
@@ -33,10 +33,11 @@ define(function(require){
var VXAuditMapList = require('collections/VXAuditMapList');
var VXUserList = require('collections/VXUserList');
var PermissionList = require('views/policies/PermissionList');
- var vPolicyTimeList = require('views/policies/PolicyTimeList');
+ var vPolicyTimeList = require('views/policies/PolicyTimeList');
var RangerPolicyResource = require('models/RangerPolicyResource');
var BackboneFormDataType = require('models/BackboneFormDataType');
var App = require('App');
+ var vPolicyCondition = require('views/policies/RangerPolicyConditions');
require('backbone-forms.list');
require('backbone-forms.templates');
@@ -65,9 +66,14 @@ define(function(require){
}
return { 'id' : this.model.id,
'policyType' : policyType.label,
- 'conditionType' : conditionType,
- 'policyTimeBtnLabel': (this.model.has('validitySchedules') && this.model.get('validitySchedules').length > 0) ? localization.tt('lbl.editValidityPeriod')
- : localization.tt('lbl.addValidityPeriod')
+ 'conditionType' : conditionType,
+ 'policyTimeBtnLabel': (this.model.has('validitySchedules') && this.model.get('validitySchedules').length > 0) ? localization.tt('lbl.editValidityPeriod')
+ : localization.tt('lbl.addValidityPeriod'),
+ 'policyConditionHideShow' : (this.rangerServiceDefModel.has('policyConditions') && !_.isEmpty(this.rangerServiceDefModel.get('policyConditions'))) ?
+ true : false,
+ 'policyConditionIconClass': (this.model.has('conditions') && this.model.get('conditions').length > 0) ? 'icon-pencil' : 'icon-plus',
+ 'conditionsData': (this.model.has('conditions') && this.model.get('conditions').length > 0) ?
+ XAUtil.getPolicyConditionDetails(this.model.get('conditions'), this.rangerServiceDefModel) : [],
};
},
initialize: function(options) {
@@ -105,7 +111,9 @@ define(function(require){
ui : {
'denyConditionItems' : '[data-js="denyConditionItems"]',
'allowExcludePerm' : '[data-js="allowExcludePerm"]',
- 'policyTimeBtn' : '[data-js="policyTimeBtn"]'
+ 'policyTimeBtn' : '[data-js="policyTimeBtn"]',
+ 'policyConditions' : '[data-js="customPolicyConditions"]',
+ 'conditionData' : '[data-id="conditionData"]'
},
/** fields for the form
*/
@@ -142,15 +150,16 @@ define(function(require){
this.renderParentChildHideShow();
//to show error msg on below the field(only for policy name)
- if(this.fields.isEnabled){
- this.fields.isEnabled.$el.find('.control-label').removeClass();
- }
- if(this.fields.name){
- this.fields.name.$el.find('.help-inline').removeClass('help-inline').addClass('help-block margin-left-5');
- }
- this.initializePlugins();
- this.setPolicyValidityTime();
- },
+ if(this.fields.isEnabled){
+ this.fields.isEnabled.$el.find('.control-label').removeClass();
+ }
+ if(this.fields.name){
+ this.fields.name.$el.find('.help-inline').removeClass('help-inline').addClass('help-block margin-left-5');
+ }
+ this.initializePlugins();
+ this.setPolicyValidityTime();
+ this.setPolicyCondition();
+ },
setPolicyValidityTime : function(){
var that = this;
this.$el.find(this.ui.policyTimeBtn).on('click', function(e){
@@ -193,6 +202,68 @@ define(function(require){
});
});
},
+
+ setPolicyCondition : function(){
+ var that = this;
+ this.$el.find(this.ui.policyConditions).on('click', function(e){
+ var view = new vPolicyCondition({
+ rangerServiceDefModel : that.rangerServiceDefModel,
+ model : that.model
+ });
+ var modal = new Backbone.BootstrapModal({
+ content : view,
+ title : 'Policy Conditions',
+ okText :"Save",
+ animate : true,
+ focusOk:false,
+ escape:false,
+ modalOptions:{
+ backdrop: 'static',
+ },
+ }).open();
+ modal.$el.addClass('modal-policy-conditions');
+ $('body').addClass('hideBodyScroll')
+ //To prevent modal being close by click out of modal
+ modal.$el.find('.cancel, .close').on('click', function(e){
+ modal._preventClose = false;
+ $('body').removeClass('hideBodyScroll');
+ $('[data-js="customPolicyConditions"]').addClass('dirtyField');
+ });
+ modal.$el.find('.ok').on('click', function(e){
+ modal._preventClose = false;
+ $('body').removeClass('hideBodyScroll');
+ $('[data-js="customPolicyConditions"]').addClass('dirtyField');
+ var conditions = [], $data = [];
+ _.each(modal.$el.find('[data-id="inputField"],[data-id="textAreaContainer"]'), function(m, context){
+ var inputFieldName = m.name;
+ if(m.value !== " " && !_.isEmpty(m.value)){
+ conditions.push({type : inputFieldName, values : (m.value.split(',')).filter(Boolean)});
+ }
+ });
+ that.model.set('conditions',conditions);
+ if(conditions.length > 0){
+ that.$el.find('[data-id="policyCondIcon"]').removeClass('icon-plus').addClass('icon-pencil');
+ } else {
+ that.$el.find('[data-id="policyCondIcon"]').removeClass('icon-pencil').addClass('icon-plus');
+ }
+ _.each(that.model.get('conditions'), function(val){
+ console.log(that);
+ var conditionName = that.rangerServiceDefModel.get('policyConditions').find(function(m){return m.name == val.type});
+ $data.push('<tr><td width="40%">'+_.escape(conditionName.label)+'</td><td width="60%">'+(val.values).toString()+'</td></tr>')
+ });
+ if($data.length > 0){
+ that.$el.find(that.ui.conditionData).html($data);
+ }else{
+ that.$el.find(that.ui.conditionData).html('<tr><td> No Conditions </td></tr>');
+ }
+ });
+ modal.on('shown', function(a){
+ this.preventClose();
+ });
+
+ })
+ },
+
initializePlugins : function() {
var that = this;
this.$(".wrap-header").each(function(i, ele) {
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js
index e6634cc..1af54e1 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js
@@ -174,6 +174,9 @@ define(function(require) {
if(this.policy.has('validitySchedules')){
details.validitySchedules = this.policy.get('validitySchedules');
}
+ if(this.policy.has('conditions') && this.policy.get('conditions').length > 0){
+ details.conditions = XAUtils.getPolicyConditionDetails(this.policy.get('conditions'), self.rangerService);
+ }
//get policyItems
this.createPolicyItems();
diff --git a/security-admin/src/main/webapp/styles/xa.css b/security-admin/src/main/webapp/styles/xa.css
index a09e3be..f90f21b 100644
--- a/security-admin/src/main/webapp/styles/xa.css
+++ b/security-admin/src/main/webapp/styles/xa.css
@@ -2435,6 +2435,14 @@ textarea:read-only{
margin-top:5px;
}
+.m-r-xs{
+ margin-right:5px;
+}
+
+.m-b-md{
+ margin-bottom:15px;
+}
+
.w3-bar-item {
width: 100%;
display: block;
@@ -2660,4 +2668,29 @@ textarea:read-only{
}
.select2-container.select2-container-disabled .select2-choice {
cursor: not-allowed;
+}
+.modal-policy-conditions{
+ width: 500px;
+}
+.multiline-condition{
+ width: 437px;
+ height: 170px;
+}
+.display-block{
+ display:block !important;
+}
+
+.condition-group-table th{
+ background-color: #eeeeef;
+}
+
+.condition-group-table.table th,
+.condition-group-table.table td{
+ word-break: break-all;
+}
+
+.condition-group-table.table tbody{
+ max-height: 400px;
+ overflow: auto;
+ display: block;
}
\ No newline at end of file
diff --git a/security-admin/src/main/webapp/templates/helpers/XAHelpers.js b/security-admin/src/main/webapp/templates/helpers/XAHelpers.js
index 1d4f04e..4b64d01 100644
--- a/security-admin/src/main/webapp/templates/helpers/XAHelpers.js
+++ b/security-admin/src/main/webapp/templates/helpers/XAHelpers.js
@@ -582,5 +582,18 @@
return _.isUndefined(context) || _.isEmpty(context) ? '--' : context;
});
+ Handlebars.registerHelper('getPolicyConditionTmpl', function(obj) {
+ if(!_.isUndefined(obj.evaluatorOptions) && !_.isUndefined(obj.evaluatorOptions['ui.isMultiline']) && Boolean(obj.evaluatorOptions['ui.isMultiline'])){
+ return '<div class="margin-bottom-5">\
+ <label class="display-block">\
+ <span>'+obj.label+' : </span>\
+ <i title="'+localization.tt('validationMessages.jsValidationMsg')+'" class="icon-info-sign pull-right margin-top-6"></i>\
+ </label>\
+ <textarea class="multiline-condition" data-id="textAreaContainer" name="'+obj.name+'" placeholder="Please enter condition.."></textarea>\
+ </div>'
+ }
+ return '<div class="margin-bottom-5 display-block"><label><span>'+obj.label+' : </span></label><input type="input" data-id="inputField" name="'+obj.name+'" ></div>'
+ });
+
return HHelpers;
});
diff --git a/security-admin/src/main/webapp/templates/policies/PolicyConditionsItem_tmpl.html b/security-admin/src/main/webapp/templates/policies/PolicyConditionsItem_tmpl.html
new file mode 100644
index 0000000..ea9813d
--- /dev/null
+++ b/security-admin/src/main/webapp/templates/policies/PolicyConditionsItem_tmpl.html
@@ -0,0 +1,20 @@
+{{!--
+ 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.
+--}}
+
+{{#each policyConditions}}
+ {{#getPolicyConditionTmpl this}} {{/getPolicyConditionTmpl}}
+{{/each}}
\ No newline at end of file
diff --git a/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html b/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html
index 1d683ad..7436829 100644
--- a/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html
+++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html
@@ -13,27 +13,56 @@ language governing permissions and limitations under the License. --}}
<form class="form-horizontal">
<fieldset>
<p class="formHeader">
- Policy Details :
+ Policy Details :
</p>
- {{#if policyType}}
- <div class="control-group field-id">
- <label class="control-label" for="c1836_id">Policy Type</label>
- <div class="controls">
- <label class="label label-ranger" style="margin-top: 5px; margin-left: 9px;">{{policyType}}</label>
- <a href="javascript:void(0);" data-js="policyTimeBtn" data-id="1" class="btn btn-primary pull-right" title="set time for policy"><i class="icon-time icon-large"></i> {{policyTimeBtnLabel}} </a>
- </div>
-
+ <div class="row-fluid">
+ <div class="span8">
+ {{#if policyType}}
+ <div class="control-group field-id">
+ <label class="control-label" for="c1836_id">Policy Type</label>
+ <div class="controls">
+ <label class="label label-ranger" style="margin-top: 5px; margin-left: 9px;">{{policyType}}</label>
+ </div>
+ </div>
+ {{/if}}
+ {{#if id}}
+ <div class="control-group field-id">
+ <label class="control-label" for="c1836_id">Policy ID</label>
+ <div class="controls">
+ <label class="label label-ranger"
+ style="margin-top: 5px; margin-left: 9px;">{{id}}</label>
+ </div>
+ </div>
+ {{/if}}
+ <div data-fieldsets class="policy-form"></div>
</div>
- {{/if}}
- {{#if id}}
- <div class="control-group field-id">
- <label class="control-label" for="c1836_id">Policy ID</label>
- <div class="controls">
- <label class="label label-ranger"
- style="margin-top: 5px; margin-left: 9px;">{{id}}</label>
+ <div class="policy-form span4">
+ <a href="javascript:void(0);" data-js="policyTimeBtn" data-id="1" class="btn btn-primary pull-right m-b-md" title="set time for policy"><i class="icon-time icon-large"></i>{{policyTimeBtnLabel}}</a>
+ {{#if policyConditionHideShow}}
+ <div class="">
+ <table class="table table-bordered condition-group-table">
+ <thead>
+ <tr>
+ <th colspan="2">Policy Conditions <a href="javascript:void(0);" data-js="customPolicyConditions" class="btn btn-mini pull-right" title="set conditions for policy"><i class={{policyConditionIconClass}} data-id="policyCondIcon"></i></a></th>
+ </tr>
+ </thead>
+ <tbody data-id="conditionData">
+ {{#if conditionsData}}
+ {{#each conditionsData}}
+ <tr>
+ <td width="40%">{{this.name}}</td>
+ <td width="60%">{{this.values}}</td>
+ </tr>
+ {{/each}}
+ {{else}}
+ <tr><td><center> No Conditions </center></td></tr>
+ {{/if}}
+ </tbody>
+ </table>
+ </div>
+ {{/if}}
</div>
</div>
- {{/if}} <div data-fieldsets class="policy-form"></div>
</fieldset>
<fieldset>
<p class="wrap-header bold formHeader">
diff --git a/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html b/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html
index a50903c..e76ad21 100644
--- a/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html
+++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html
@@ -160,7 +160,21 @@
</table>
</div>
{{/if}}
-
+{{#if PolicyDetails.conditions}}
+ <div class="row-fluid">
+ <p class="formHeader">Policy Conditions :</p>
+ <table class="table table-bordered condition-group-table" style="width: 100%">
+ <tbody>
+ {{#each PolicyDetails.conditions}}
+ <tr colspan="2">
+ <td width="40%">{{this.name}}</td>
+ <td width="60%">{{this.values}}</td>
+ </tr>
+ {{/each}}
+ </tbody>
+ </table>
+ </div>
+{{/if}}
{{#each PolicyDetails.policyItemsCond}}
<div id="policyItems" class="row-fluid">
<p class="formHeader">