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">