Repository: incubator-ranger Updated Branches: refs/heads/master 2c7f617be -> 19c3744b1
RANGER-912 : Ranger Admin UI to support datamask & row-filter policies Signed-off-by: Madhan Neethiraj <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/19c3744b Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/19c3744b Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/19c3744b Branch: refs/heads/master Commit: 19c3744b1ece45be9b33a6075472bfc37bc9bd28 Parents: 2c7f617 Author: Gautam Borad <[email protected]> Authored: Tue Apr 5 15:57:02 2016 +0530 Committer: Madhan Neethiraj <[email protected]> Committed: Tue Apr 5 11:51:26 2016 -0700 ---------------------------------------------------------------------- .../webapp/scripts/controllers/Controller.js | 13 +- .../scripts/models/BackboneFormDataType.js | 118 ++++++++++------ .../src/main/webapp/scripts/modules/XALinks.js | 3 +- .../main/webapp/scripts/modules/XAOverrides.js | 86 +++++++++++- .../scripts/modules/globalize/message/en.js | 9 +- .../src/main/webapp/scripts/routers/Router.js | 6 +- .../src/main/webapp/scripts/utils/XAEnums.js | 6 + .../src/main/webapp/scripts/utils/XAUtils.js | 27 +++- .../scripts/views/policies/PermissionList.js | 135 ++++++++++++++++++- .../views/policies/RangerPolicyCreate.js | 39 ++++-- .../scripts/views/policies/RangerPolicyForm.js | 125 +++++++++++------ .../views/policies/RangerPolicyTableLayout.js | 81 ++++++----- .../webapp/scripts/views/service/ServiceForm.js | 2 +- .../main/webapp/templates/helpers/XAHelpers.js | 14 +- .../templates/policies/PermissionItem.html | 18 ++- .../policies/RangerPolicyForm_tmpl.html | 10 +- .../policies/RangerPolicyTableLayout_tmpl.html | 15 ++- 17 files changed, 546 insertions(+), 161 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/controllers/Controller.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/controllers/Controller.js b/security-admin/src/main/webapp/scripts/controllers/Controller.js index 54ebcd7..4af460c 100755 --- a/security-admin/src/main/webapp/scripts/controllers/Controller.js +++ b/security-admin/src/main/webapp/scripts/controllers/Controller.js @@ -270,7 +270,7 @@ define(function(require) { }); }, - policyManageAction :function(serviceId){ + policyManageAction : function(serviceId,policyType){ MAppState.set({ 'currentTab' : XAGlobals.AppTabs.AccessManager.value }); var XAUtil = require('utils/XAUtils'); var view = require('views/policies/RangerPolicyTableLayout'); @@ -278,18 +278,19 @@ define(function(require) { var RangerPolicyList = require('collections/RangerPolicyList'); var rangerService = new RangerService({id : serviceId}); - + var rangerPolicyList = new RangerPolicyList(); + rangerPolicyList.queryParams['policyType'] = policyType; + rangerService.fetch({ cache : false, async : false }); App.rContent.show(new view({ rangerService : rangerService, - collection : new RangerPolicyList() - + collection : rangerPolicyList })); }, - RangerPolicyCreateAction :function(serviceId){ + RangerPolicyCreateByTypeAction :function(serviceId, policyType){ MAppState.set({ 'currentTab' : XAGlobals.AppTabs.AccessManager.value }); var view = require('views/policies/RangerPolicyCreate'); @@ -301,7 +302,7 @@ define(function(require) { cache : false, }).done(function(){ App.rContent.show(new view({ - model : new RangerPolicy(), + model : new RangerPolicy({'policyType' : policyType}), rangerService : rangerService, })); }); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/models/BackboneFormDataType.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/models/BackboneFormDataType.js b/security-admin/src/main/webapp/scripts/models/BackboneFormDataType.js index a776f69..283e626 100644 --- a/security-admin/src/main/webapp/scripts/models/BackboneFormDataType.js +++ b/security-admin/src/main/webapp/scripts/models/BackboneFormDataType.js @@ -20,13 +20,32 @@ define(function(require) { 'use strict'; - var Backbone = require('backbone'); - var XAUtils = require('utils/XAUtils'); + var Backbone = require('backbone'); + var XAUtils = require('utils/XAUtils'); + var XAEnums = require('utils/XAEnums'); var FormDataType = Backbone.Model.extend({ type : [ 'string', 'boolean', 'int' ], - getFormElements : function(configs, enums, attrs, form) { + getFormElements : function(configs, enums, attrs, form, isPolicyForm) { //Helpers + + //Get configs for perticular policy type + var getResourceConfigs = function(configs){ + if(XAUtils.isMaskingPolicy(form.model.get('policyType'))){ + if(XAUtils.isRenderMasking(form.rangerServiceDefModel.get('dataMaskDef'))){ + configs = form.rangerServiceDefModel.get('dataMaskDef').resources; + configs = _.map(configs, function(obj){ obj.type = 'string'; return obj; }); + return configs; + } + }else if(XAUtils.isRowFilterPolicy(form.model.get('policyType'))){ + if(XAUtils.isRenderRowFilter(form.rangerServiceDefModel.get('rowFilterDef'))){ + configs = form.rangerServiceDefModel.get('rowFilterDef').resources; + configs = _.map(configs, function(obj){ obj.type = 'string'; return obj; }); + return configs; + } + } + return configs; + }; var getValidators = function(formObj, v){ formObj.validators = []; if (_.has(v, 'mandatory') && v.mandatory && v.type != 'bool') { @@ -45,55 +64,74 @@ define(function(require) { return form; }; + //Get configs for perticular policy type + configs = getResourceConfigs(configs) var samelevelFieldCreated = []; _.each(configs, function(v, k,config) { if (v != null) { - var formObj = {}, fieldName; + var formObj = {}, fieldName, supportedResource = []; switch (v.type) { case 'string': + if(!isPolicyForm) { + formObj.type = 'Text'; + break; + } if($.inArray(v.level, samelevelFieldCreated) >= 0){ return; } - if(! XAUtils.isSinglevValueInput(v) ){ - if(v.excludesSupported || v.recursiveSupported || v.lookupSupported ){ - var resourceOpts = {}; - formObj.type = 'Resource'; - formObj['excludeSupport']= v.excludesSupported; - formObj['recursiveSupport'] = v.recursiveSupported; - formObj.name = v.name; + + if( isPolicyForm ){ + var resourceOpts = {}; + formObj.type = 'Resource'; + formObj['excludeSupport']= v.excludesSupported; + formObj['recursiveSupport'] = v.recursiveSupported; + formObj.name = v.name; // formObj.level = v.level; - //checkParentHideShow field - formObj.fieldAttrs = { 'data-name' : 'field-'+v.name, 'parent' : v.parent }; - formObj['resourceOpts'] = {'data-placeholder': v.label }; - - if(!_.isUndefined(v.lookupSupported) && v.lookupSupported ){ - var opts = { - 'type' : v.name, - 'lookupURL' : "service/plugins/services/lookupResource/"+form.rangerService.get('name') - }; - if(_.has(v, 'validationRegEx') && !_.isEmpty(v.validationRegEx)){ - opts['regExpValidation'] = {'type': 'regexp', 'regexp':new RegExp(v.validationRegEx), 'message' : v.validationMessage}; - } - resourceOpts['select2Opts'] = form.getPlugginAttr(true, opts); - formObj['resourceOpts'] = resourceOpts; - } - //same level resources check - var optionsAttrs = _.filter(config,function(field){ if(field.level == v.level) return field;}) - if(optionsAttrs.length > 1){ - var optionsTitle = _.map(optionsAttrs,function(field){ return field.name;}); - formObj['sameLevelOpts'] = optionsTitle; - samelevelFieldCreated.push(v.level); - fieldName = 'sameLevel'+v.level; - formObj['title'] = ''; - formObj['resourcesAtSameLevel'] = true; - - // formView is used to listen form events - formObj['formView'] = form; + //checkParentHideShow field + formObj.fieldAttrs = { 'data-name' : 'field-'+v.name, 'parent' : v.parent }; + formObj['resourceOpts'] = {'data-placeholder': v.label }; + + if(!_.isUndefined(v.lookupSupported) && v.lookupSupported ){ + var opts = { + 'type' : v.name, + 'lookupURL' : "service/plugins/services/lookupResource/"+form.rangerService.get('name') + }; + if(_.has(v, 'validationRegEx') && !_.isEmpty(v.validationRegEx)){ + opts['regExpValidation'] = {'type': 'regexp', 'regexp':new RegExp(v.validationRegEx), 'message' : v.validationMessage}; } + //To support single value input + if( XAUtils.isSinglevValueInput(v) ){ + opts['singleValueInput'] = true; + } + resourceOpts['select2Opts'] = form.getPlugginAttr(true, opts); + formObj['resourceOpts'] = resourceOpts; + } + //same level resources check + var optionsAttrs = []; + if(!_.isUndefined(v.level)){ + optionsAttrs = _.filter(config,function(field){ if(field.level == v.level) return field;}) + } + //TODO + //if policyType is masking then check for supported resources +// if( XAUtils.isMaskingPolicy(form.model.get('policyType')) && optionsAttrs.length > 1 ){ +// var allResourceNames = _.map(optionsAttrs, function(m){ return m.name}); +// var rscNames = allResourceNames.splice(allResourceNames.indexOf(v.name), 1); +// if(_.intersection(allResourceNames, rscNames) != rscNames){ +// optionsAttrs = _.filter(optionsAttrs, function(m){ return $.inArray(m.name, allResourceNames) >= 0;}) +// } +// } + if(optionsAttrs.length > 1){ + var optionsTitle = _.map(optionsAttrs,function(field){ return field.name;}); + formObj['sameLevelOpts'] = optionsTitle; + samelevelFieldCreated.push(v.level); + fieldName = 'sameLevel'+v.level; + formObj['title'] = ''; + formObj['resourcesAtSameLevel'] = true; + + // formView is used to listen form events + formObj['formView'] = form; } - }else{ - formObj.type = 'Text'; } break; case 'bool': http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/modules/XALinks.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/modules/XALinks.js b/security-admin/src/main/webapp/scripts/modules/XALinks.js index 5fec205..060ab36 100755 --- a/security-admin/src/main/webapp/scripts/modules/XALinks.js +++ b/security-admin/src/main/webapp/scripts/modules/XALinks.js @@ -26,6 +26,7 @@ define(function(require) { 'use strict'; var XALinks = {}; + var XAEnums = require('utils/XAEnums'); var defaults = { href : 'javascript:void(0)', text : '', @@ -204,7 +205,7 @@ define(function(require) { ManagePolicies : function(options){ var href = "javascript:void(0);"; if(_.has(options,'model')){ - href = '#!/service/'+options.model.id+"/policies"; + href = '#!/service/'+options.model.id+"/policies/"+XAEnums.RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value; } return { href : href, http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js index 6f0a48d..24f9bc2 100644 --- a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js +++ b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js @@ -569,8 +569,10 @@ }); // bootstrap-editable ============================================ - /** - ********************** custom type created for tag based policies + (function ($) { + "use strict"; + /** + ********************** custom type created for tag based policies List of taglistcheck. Internally value stored as javascript array of values. @@ -579,9 +581,7 @@ @final @example <a href="#" id="options" data-type="tagchecklist" data-pk="1" data-url="/post" data-title="Select options"></a> - **/ - (function ($) { - "use strict"; + **/ var TagChecklist = function (options) { this.init('tagchecklist', options, TagChecklist.defaults); @@ -855,7 +855,81 @@ separator: ',' }); - $.fn.editabletypes.tagchecklist = TagChecklist; + $.fn.editabletypes.tagchecklist = TagChecklist; + + + /** + + radiolist + Internally value stored as javascript array of values. + + @class radiolist + @extends list + @final + @example + <a href="#" id="options" data-type="radiolist" data-pk="1" data-url="/post" data-title="Select options"></a> + **/ + + + var Radiolist = function(options) { + this.init('radiolist', options, Radiolist.defaults); + }; + $.fn.editableutils.inherit(Radiolist, $.fn.editabletypes.checklist); + + $.extend(Radiolist.prototype, { + renderList : function() { + var $label; + this.$tpl.empty(); + if (!$.isArray(this.sourceData)) { + return; + } + + for (var i = 0; i < this.sourceData.length; i++) { + $label = $('<label>', {'class':this.options.inputclass}).append($('<input>', { + type : 'radio', + name : this.options.name, + value : this.sourceData[i].value + })).append($('<span>').text(this.sourceData[i].text)); + + // Add radio buttons to template + this.$tpl.append($('<div>').append($label)); + } + + this.$input = this.$tpl.find('input[type="radio"]'); + }, + input2value : function() { + return this.$input.filter(':checked').val(); + }, + str2value: function(str) { + return str || null; + }, + + value2input: function(value) { + this.$input.val([value]); + }, + value2str: function(value) { + return value || ''; + }, + }); + + Radiolist.defaults = $.extend({}, $.fn.editabletypes.list.defaults, { + /** + @property tpl + @default <div></div> + **/ + tpl : '<div class="editable-radiolist"></div>', + + /** + @property inputclass, attached to the <label> wrapper instead of the input element + @type string + @default null + **/ + inputclass : '', + + name : 'defaultname' + }); + + $.fn.editabletypes.radiolist = Radiolist; }(window.jQuery)); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js ---------------------------------------------------------------------- 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 604c6be..070b3ea 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 @@ -230,7 +230,10 @@ define(function(require) { serviceName : 'Service Name', PolicyType_ALLOW : 'Allow', PolicyType_DENY : 'Deny', - componentPermissions : 'Component Permissions' + componentPermissions : 'Component Permissions', + selectDataMaskTypes : 'Select Data Mask Types', + accessTypes : 'Access Types', + rowLevelFilter : 'Row Level Filter' }, btn : { add : 'Add', @@ -307,9 +310,9 @@ define(function(require) { policyDeleteMsg : 'Policy deleted successfully', policyNotAddedMsg : 'Policy not added!', addGroupPermission : 'Please add permission(s) for the selected Group, else group will not be added.', - addGroup : 'Please select group for the selected permission, else group will not be added.', + addGroup : 'Please select group for the selected permission(s), else group will not be added.', addUserPermission : 'Please add permission(s) for the selected User, else User will not be added.', - addUser : 'Please select User for the selected permission, else User will not be added.', + addUser : 'Please select User for the selected permission(s), else User will not be added.', enterAlteastOneCharactere : 'Enter alteast one character.', permsAlreadyExistForSelectedUser : 'Permission already exists for selected user.', permsAlreadyExistForSelectedGroup : 'Permission already exists for selected group.', http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/routers/Router.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/routers/Router.js b/security-admin/src/main/webapp/scripts/routers/Router.js index d8aea1b..b508e64 100644 --- a/security-admin/src/main/webapp/scripts/routers/Router.js +++ b/security-admin/src/main/webapp/scripts/routers/Router.js @@ -55,9 +55,9 @@ function(Backbone, Marionette, localization, MAppState, XAUtil){ "!/service/:serviceType/create" : "serviceCreateAction", "!/service/:serviceType/edit/:id" : "serviceEditAction", - "!/service/:serviceId/policies" : "policyManageAction", - "!/service/:serviceId/policies/create" : "RangerPolicyCreateAction", - "!/service/:serviceId/policies/:id/edit": "RangerPolicyEditAction", + "!/service/:serviceId/policies/:policyType" : "policyManageAction", + "!/service/:serviceId/policies/create/:policyType" : "RangerPolicyCreateByTypeAction", + "!/service/:serviceId/policies/:id/edit" : "RangerPolicyEditAction", /************PERMISSIONS VIEWS *****************************************/ "!/permissions" : "modulePermissionsAction", http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/utils/XAEnums.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/utils/XAEnums.js b/security-admin/src/main/webapp/scripts/utils/XAEnums.js index cb10f08..bebb02c 100644 --- a/security-admin/src/main/webapp/scripts/utils/XAEnums.js +++ b/security-admin/src/main/webapp/scripts/utils/XAEnums.js @@ -47,6 +47,12 @@ define(function(require) { XA_GROUP:{value:1, label:'Denied', rbkey:'xa.enum.AccessResult.ACCESS_RESULT_DENIED', tt: 'lbl.AccessResult_ACCESS_RESULT_DENIED'} }); + XAEnums.RangerPolicyType = mergeParams(XAEnums.RangerPolicyType, { + RANGER_ACCESS_POLICY_TYPE:{value:0, label:'Access', rbkey:'xa.enum.AccessResult.ACCESS_RESULT_ALLOWED', tt: 'lbl.AccessResult_ACCESS_RESULT_ALLOWED'}, + RANGER_MASKING_POLICY_TYPE:{value:1, label:'Masking', rbkey:'xa.enum.AccessResult.ACCESS_RESULT_DENIED', tt: 'lbl.AccessResult_ACCESS_RESULT_DENIED'}, + RANGER_ROW_FILTER_POLICY_TYPE:{value:2, label:'Row Level Filter', rbkey:'xa.enum.AccessResult.ACCESS_RESULT_DENIED', tt: 'lbl.AccessResult_ACCESS_RESULT_DENIED'} + }); + XAEnums.UserRoles = mergeParams(XAEnums.UserRoles, { ROLE_SYS_ADMIN:{value:0, label:'Admin', rbkey:'xa.enum.AccessResult.ACCESS_RESULT_ALLOWED', tt: 'lbl.AccessResult_ACCESS_RESULT_ALLOWED'}, ROLE_USER:{value:1, label:'User', rbkey:'xa.enum.AccessResult.ACCESS_RESULT_DENIED', tt: 'lbl.AccessResult_ACCESS_RESULT_DENIED'}, http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/utils/XAUtils.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/utils/XAUtils.js b/security-admin/src/main/webapp/scripts/utils/XAUtils.js index 7bf7bdb..6611fa6 100644 --- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js +++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js @@ -467,7 +467,7 @@ define(function(require) { }; XAUtils.showGroupsOrUsersForPolicy = function(rawValue, model, showGroups) { var showMoreLess = false, groupArr = [], items = []; - var itemList = ['policyItems','allowExceptions','denyPolicyItems','denyExceptions'] + var itemList = ['policyItems','allowExceptions','denyPolicyItems','denyExceptions','dataMaskPolicyItems'] var type = _.isUndefined(showGroups) ? 'groups' : 'users'; _.each(itemList, function(item){ if(!_.isUndefined(model.get(item)) && !_.isEmpty(model.get(item))) { @@ -583,6 +583,7 @@ define(function(require) { XAUtils.makeCollForGroupPermission = function(model, listName) { var XAEnums = require('utils/XAEnums'); var formInputColl = new Backbone.Collection(); + var that = this; // permMapList = [ {id: 18, groupId : 1, permType :5}, {id: 18, groupId // : 1, permType :4}, {id: 18, groupId : 2, permType :5} ] // [1] => [ {id: 18, groupId : 1, permType :5}, {id: 18, groupId : 1, @@ -608,6 +609,12 @@ define(function(require) { delegateAdmin : obj.delegateAdmin, editMode : true, }); + if(that.isMaskingPolicy(model.get('policyType'))){ + m.set('dataMaskInfo', obj.dataMaskInfo) + } + if(that.isRowFilterPolicy(model.get('policyType'))){ + m.set('rowFilterInfo', obj.rowFilterInfo) + } formInputColl.add(m); }); @@ -1171,5 +1178,23 @@ define(function(require) { return singleValue; }; + XAUtils.isMaskingPolicy = function(type){ + return type == XAEnums.RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value ? true : false; + }; + XAUtils.isRenderMasking = function(dataMaskDef){ + return (!_.isUndefined(dataMaskDef) && !_.isUndefined(dataMaskDef.resources) + && dataMaskDef.resources.length > 0) ? true : false; + }; + XAUtils.isAccessPolicy = function(type){ + return type == XAEnums.RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value ? true : false; + }; + XAUtils.isRowFilterPolicy = function(type){ + return type == XAEnums.RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value ? true : false; + }; + XAUtils.isRenderRowFilter = function(rowFilterDef){ + return (!_.isUndefined(rowFilterDef) && !_.isUndefined(rowFilterDef.resources) + && rowFilterDef.resources.length > 0) ? true : false; + }; + return XAUtils; }); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js index fb4808e..326c84c 100644 --- a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js +++ b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js @@ -48,16 +48,24 @@ define(function(require) { policyConditions: this.policyConditions, isModelNew : !this.model.has('editMode'), perms : this.permsIds.length == 14 ? _.union(this.permsIds,[-1]) : this.permsIds, + isMaskingPolicy : XAUtil.isMaskingPolicy(this.rangerPolicyType), + isAccessPolicy : XAUtil.isAccessPolicy(this.rangerPolicyType), + isRowFilterPolicy : XAUtil.isRowFilterPolicy(this.rangerPolicyType), }; }, ui : { selectGroups : '[data-js="selectGroups"]', selectUsers : '[data-js="selectUsers"]', addPerms : 'a[data-js="permissions"]', + maskingType : 'a[data-js="maskingType"]', + rowLeveFilter : 'a[data-js="rowLeveFilter"]', conditionsTags : '[class=tags1]', delegatedAdmin : 'input[data-js="delegatedAdmin"]', addPermissionsSpan : '.add-permissions', - addConditionsSpan : '.add-conditions', + addConditionsSpan : '.add-conditions', + addMaskingTypeSpan : '.add-masking-type', + addRowFilterSpan : '.add-row-filter', + }, events : { 'click [data-action="delete"]' : 'evDelete', @@ -68,7 +76,7 @@ define(function(require) { }, initialize : function(options) { - _.extend(this, _.pick(options, 'groupList','accessTypes','policyConditions','userList','rangerServiceDefModel')); + _.extend(this, _.pick(options, 'groupList','accessTypes','policyConditions','userList','rangerServiceDefModel','rangerPolicyType')); this.setupPermissionsAndConditions(); }, @@ -90,9 +98,18 @@ define(function(require) { this.renderPerms(); } this.renderPolicyCondtion(); + if(XAUtil.isMaskingPolicy(this.rangerPolicyType)){ + this.renderMaskingType(); + } + if(XAUtil.isRowFilterPolicy(this.rangerPolicyType)){ + this.renderRowLevelFilter(); + } + }, setupFormForEditMode : function() { - this.accessItems = _.map(this.accessTypes, function(perm){ + var permTypes = this.accessTypes; + + this.accessItems = _.map(permTypes, function(perm){ if(!_.isUndefined(perm)) return {'type':perm.name, isAllowed : false} }); if(this.model.has('editMode') && this.model.get('editMode')){ @@ -118,6 +135,9 @@ define(function(require) { if(!_.isUndefined(this.model.get('delegateAdmin')) && this.model.get('delegateAdmin')){ this.ui.delegatedAdmin.attr('checked', 'checked'); } + if(!_.isUndefined(this.model.get('rowFilterInfo')) && !_.isUndefined(this.model.get('rowFilterInfo').filterExpr)){ + this.rowFilterExprVal = this.model.get('rowFilterInfo').filterExpr + } } }, setupPermissionsAndConditions : function() { @@ -579,6 +599,80 @@ define(function(require) { groupIdList = this.model.get('groupId').split(','); XAUtil.checkDirtyField(groupIdList, e.val, $(e.currentTarget)); }, + renderMaskingType :function(){ + var that = this, maskingTypes = []; + this.maskTypeIds = []; + if(!_.isUndefined(this.model.get('dataMaskInfo')) && !_.isUndefined(this.model.get('dataMaskInfo').dataMaskType)){ + this.maskTypeIds = this.model.get('dataMaskInfo').dataMaskType + } + + if(!_.isUndefined(this.rangerServiceDefModel.get('dataMaskDef')) && !_.isUndefined(this.rangerServiceDefModel.get('dataMaskDef').maskTypes)){ + maskingTypes = this.rangerServiceDefModel.get('dataMaskDef').maskTypes; + } + this.maskTypes = _.map(maskingTypes, function(m){return {text:m.label, value : m.name };}); + //create x-editable for permissions + this.ui.maskingType.editable({ + emptytext : 'Select Masking Type', + source: this.maskTypes, + value : this.maskTypeIds, + display: function(value,srcData) { + if(_.isNull(value) || _.isEmpty(value)){ + $(this).empty(); + that.model.unset('dataMaskInfo'); + that.ui.addMaskingTypeSpan.find('i').attr('class', 'icon-plus'); + that.ui.addMaskingTypeSpan.attr('title','add'); + return; + } + + var obj = _.findWhere(srcData, {'value' : value } ); + // Save form data to model + that.model.set('dataMaskInfo', {'dataMaskType': value }); + + $(this).html("<span class='label label-info'>" + obj.text + "</span>"); + that.ui.addMaskingTypeSpan.find('i').attr('class', 'icon-pencil'); + that.ui.addMaskingTypeSpan.attr('title','edit'); + }, + }).on('click', function(e) { + e.stopPropagation(); + e.preventDefault(); +// that.clickOnMaskingType(that); + }); + that.ui.addMaskingTypeSpan.click(function(e) { + e.stopPropagation(); + that.$('a[data-js="maskingType"]').editable('toggle'); +// that.clickOnMaskingType(that); + }); + }, + renderRowLevelFilter :function(){ + var that = this; + //create x-editable for permissions + this.ui.rowLeveFilter.editable({ + emptytext : 'Add Row Filter', + placeholder : 'enter expression', + value : this.rowFilterExprVal, + display: function(value,srcData) { + if(_.isNull(value) || _.isEmpty(value)){ + $(this).empty(); + that.model.unset('rowFilterInfo'); + that.ui.addRowFilterSpan.find('i').attr('class', 'icon-plus'); + that.ui.addRowFilterSpan.attr('title','add'); + return; + } + that.model.set('rowFilterInfo', {'filterExpr': value }); + $(this).html("<span class='label label-info'>" + value + "</span>"); + that.ui.addRowFilterSpan.find('i').attr('class', 'icon-pencil'); + that.ui.addRowFilterSpan.attr('title','edit'); + }, + }).on('click', function(e) { + e.stopPropagation(); + e.preventDefault(); + }); + that.ui.addRowFilterSpan.click(function(e) { + e.stopPropagation(); + that.$('a[data-js="rowLeveFilter"]').editable('toggle'); + }); + + }, }); @@ -601,20 +695,23 @@ define(function(require) { }, itemViewContainer : ".js-formInput", itemViewOptions : function() { + //set access type by policy type + this.setAccessTypeByPolicyType(); return { 'collection' : this.collection, 'groupList' : this.groupList, 'userList' : this.userList, 'accessTypes' : this.accessTypes, 'policyConditions' : this.rangerServiceDefModel.get('policyConditions'), - 'rangerServiceDefModel' : this.rangerServiceDefModel + 'rangerServiceDefModel' : this.rangerServiceDefModel, + 'rangerPolicyType' : this.rangerPolicyType }; }, events : { 'click [data-action="addGroup"]' : 'addNew' }, initialize : function(options) { - _.extend(this, _.pick(options, 'groupList','accessTypes','rangerServiceDefModel','userList', 'headerTitle')); + _.extend(this, _.pick(options, 'groupList','accessTypes','rangerServiceDefModel','userList', 'headerTitle','rangerPolicyType')); this.listenTo(this.groupList, 'sync', this.render, this); if(this.collection.length == 0) this.collection.add(new Backbone.Model()); @@ -647,11 +744,22 @@ define(function(require) { getPermHeaders : function(){ var permList = []; if(this.rangerServiceDefModel.get('name') != XAEnums.ServiceType.SERVICE_TAG.label){ - permList.unshift(localization.tt('lbl.delegatedAdmin')); - permList.unshift(localization.tt('lbl.permissions')); + if(XAUtil.isAccessPolicy(this.rangerPolicyType)){ + permList.unshift(localization.tt('lbl.delegatedAdmin')); + } + if(XAUtil.isRowFilterPolicy(this.rangerPolicyType)){ + permList.unshift(localization.tt('lbl.rowLevelFilter')); + permList.unshift(localization.tt('lbl.accessTypes')); + }else if(XAUtil.isMaskingPolicy(this.rangerPolicyType)){ + permList.unshift(localization.tt('lbl.selectDataMaskTypes')); + permList.unshift(localization.tt('lbl.accessTypes')); + }else{ + permList.unshift(localization.tt('lbl.permissions')); + } } else { permList.unshift(localization.tt('lbl.componentPermissions')); } + if(!_.isEmpty(this.rangerServiceDefModel.get('policyConditions'))){ permList.unshift(localization.tt('h.policyCondition')); } @@ -660,6 +768,19 @@ define(function(require) { permList.push(""); return permList; }, + setAccessTypeByPolicyType : function(){ + if(XAUtil.isMaskingPolicy(this.rangerPolicyType) && XAUtil.isRenderMasking(this.rangerServiceDefModel.get('dataMaskDef'))){ + var dataMaskDef = this.rangerServiceDefModel.get('dataMaskDef'); + if(!_.isUndefined(dataMaskDef) && !_.isUndefined(dataMaskDef.accessTypes)){ + this.accessTypes = _.map(dataMaskDef.accessTypes, function(m){return _.findWhere(this.accessTypes, {'name' : m.name });}, this); + } + }else if(XAUtil.isRowFilterPolicy(this.rangerPolicyType) && XAUtil.isRenderRowFilter(this.rangerServiceDefModel.get('rowFilterDef'))){ + var rowFilterDef = this.rangerServiceDefModel.get('rowFilterDef'); + if(!_.isUndefined(rowFilterDef) && !_.isUndefined(rowFilterDef.accessTypes)){ + this.accessTypes = _.map(rowFilterDef.accessTypes, function(m){return _.findWhere(this.accessTypes, {'name' : m.name });}, this); + } + } + } }); }); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js index ceeac67..eac992d 100644 --- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js +++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js @@ -93,7 +93,7 @@ define(function(require){ template : require('hbs!tmpl/policies/RangerPolicyForm_tmpl'), model : this.model, rangerServiceDefModel : this.rangerServiceDefModel, - rangerService : this.rangerService + rangerService : this.rangerService, }); this.editPolicy = this.model.has('id') ? true : false; @@ -107,7 +107,28 @@ define(function(require){ this.rangerServiceDefModel.fetch({ cache : false, async : false - }) + }); +// if(this.rangerServiceDefModel.get('name') == "hive"){ +// this.rangerServiceDefModel.set("dataMaskDef",{ "accessTypes": [ { "name": "select" } ], +// "resources": [ +// { "lookupSupported" :true, "name": "database", "matcherOptions": { "wildCard": "false" }, "uiHint":"{ \"singleValue\":true }" }, +// { "name": "table", "matcherOptions": { "wildCard": "false" }, "uiHint":"{ \"singleValue\":true }" }, +// { "name": "column", "matcherOptions": { "wildCard": "false" }, "uiHint":"{ \"singleValue\":true }" } +// ], +// "maskTypes": [ { "itemId": 1, "name": "MASK", "label": "Mask", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "dataMaskOptions": { } }, { "itemId": 2, "name": "SHUFFLE", "label": "Shuffle", "description": "Shuffle the value of the column", "dataMaskOptions": { } }, { "itemId": 3, "name": "MASK_x_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "dataMaskOptions": { } }, { "itemId": 4, "name": "MASK_x_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "dataMaskOptions": { } }, { "itemId": 10, "name": "NULL", "label": "NULL", "description": "Replace with NULL", "dataMaskOptions": { } } ] }); +// +// this.rangerServiceDefModel.set("rowFilterDef", +// { +// "accessTypes":[ +// {"name":"select","label":"Select"} +// ], +// "resources":[ +// {"name":"database","matcherOptions":{"wildCard":false}}, +// {"name":"table","matcherOptions":{"wildCard":false}} +// ] +// }); +// } + }, /** all events binding here */ @@ -124,6 +145,9 @@ define(function(require){ XAUtil.preventNavigation(localization.tt('dialogMsg.preventNavPolicyForm'),this.rForm.$el); }, popupCallBack : function(msg,validateObj){ + if(XAUtil.isMaskingPolicy(this.model.get('policyType'))){ + msg = msg.replace('permission','access type') + } XAUtil.alertPopup({ msg :msg, }); @@ -209,12 +233,7 @@ define(function(require){ var msg = that.editPolicy ? 'Policy updated successfully' :'Policy created successfully'; XAUtil.notifySuccess('Success', msg); XAUtil.allowNavigation(); - if(that.editPolicy){ - App.appRouter.navigate("#!/service/"+that.rangerService.id+"/policies",{trigger: true}); - return; - } - App.appRouter.navigate("#!/service/"+that.rangerService.id+"/policies",{trigger: true}); - console.log("success"); + App.appRouter.navigate("#!/service/"+that.rangerService.id+"/policies/"+ that.model.get('policyType'),{trigger: true}); }, error : function(model, response, options) { XAUtil.blockUI('unblock'); @@ -229,7 +248,7 @@ define(function(require){ }, onCancel : function(){ XAUtil.allowNavigation(); - App.appRouter.navigate("#!/service/"+this.rangerService.id+"/policies",{trigger: true}); + App.appRouter.navigate("#!/service/"+this.rangerService.id+"/policies/"+ this.model.get('policyType'),{trigger: true}); }, onDelete :function(){ @@ -243,7 +262,7 @@ define(function(require){ XAUtil.blockUI('unblock'); XAUtil.allowNavigation(); XAUtil.notifySuccess('Success', localization.tt('msg.policyDeleteMsg')); - App.appRouter.navigate("#!/service/"+that.rangerService.id+"/policies",{trigger: true}); + App.appRouter.navigate("#!/service/"+that.rangerService.id+"/policies/"+ that.model.get('policyType'),{trigger: true}); }, error: function (model, response, options) { XAUtil.blockUI('unblock'); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js ---------------------------------------------------------------------- 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 8518765..253031d 100644 --- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js +++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js @@ -53,7 +53,10 @@ define(function(require){ * @constructs */ templateData : function(){ - return { 'id' : this.model.id }; + var obj = XAUtil.enumElementByValue(XAEnums.RangerPolicyType, this.model.get('policyType')) + return { 'id' : this.model.id, + 'policyType' : obj.label + }; }, initialize: function(options) { console.log("initialized a RangerPolicyForm Form View"); @@ -66,7 +69,13 @@ define(function(require){ this.defaultValidator={} }, initializeCollection: function(){ - this.formInputList = XAUtil.makeCollForGroupPermission(this.model, 'policyItems'); + if(XAUtil.isMaskingPolicy(this.model.get('policyType'))){ + this.formInputList = XAUtil.makeCollForGroupPermission(this.model, 'dataMaskPolicyItems'); + }else if(XAUtil.isRowFilterPolicy(this.model.get('policyType'))){ + this.formInputList = XAUtil.makeCollForGroupPermission(this.model, 'rowFilterPolicyItems'); + }else{ + this.formInputList = XAUtil.makeCollForGroupPermission(this.model, 'policyItems'); + } this.formInputAllowExceptionList= XAUtil.makeCollForGroupPermission(this.model, 'allowExceptions'); this.formInputDenyList = XAUtil.makeCollForGroupPermission(this.model, 'denyPolicyItems'); this.formInputDenyExceptionList = XAUtil.makeCollForGroupPermission(this.model, 'denyExceptions'); @@ -97,7 +106,7 @@ define(function(require){ var schemaNames = this.getPolicyBaseFieldNames(); var formDataType = new BackboneFormDataType(); - attrs = formDataType.getFormElements(this.rangerServiceDefModel.get('resources'),this.rangerServiceDefModel.get('enums'), attrs, this); + attrs = formDataType.getFormElements(this.rangerServiceDefModel.get('resources'),this.rangerServiceDefModel.get('enums'), attrs, this, true); var attr1 = _.pick(_.result(this.model,'schemaBase'),basicSchema); var attr2 = _.pick(_.result(this.model,'schemaBase'),schemaNames); @@ -176,9 +185,16 @@ define(function(require){ setupForm : function() { if(!this.model.isNew()){ this.selectedResourceTypes = {}; + var resourceDefList = this.rangerServiceDefModel.get('resources'); + if(XAUtil.isMaskingPolicy(this.model.get('policyType')) && XAUtil.isRenderMasking(this.rangerServiceDefModel.get('dataMaskDef'))){ + resourceDefList = this.rangerServiceDefModel.get('dataMaskDef').resources; + } _.each(this.model.get('resources'),function(obj,key){ - var resourceDef = _.findWhere(this.rangerServiceDefModel.get('resources'),{'name':key}) - var sameLevelResourceDef = _.where(this.rangerServiceDefModel.get('resources'), {'level': resourceDef.level}); + var resourceDef = _.findWhere(resourceDefList,{'name':key}), + sameLevelResourceDef = []; + if(this.model.get('policyType') == XAEnums.RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value){ + sameLevelResourceDef = _.where(resourceDefList, {'level': resourceDef.level}); + } if(sameLevelResourceDef.length > 1){ obj['resourceType'] = key; this.model.set('sameLevel'+resourceDef.level, obj) @@ -186,12 +202,13 @@ define(function(require){ this.selectedResourceTypes['sameLevel'+resourceDef.level]=key; }else{ //single value support - if(! XAUtil.isSinglevValueInput(resourceDef) ){ + /*if(! XAUtil.isSinglevValueInput(resourceDef) ){ this.model.set(resourceDef.name, obj) }else{ //single value resource this.model.set(resourceDef.name, obj.values) - } + }*/ + this.model.set(resourceDef.name, obj) } },this) } @@ -209,6 +226,7 @@ define(function(require){ enableDenyAndExceptionsInPolicies = false; //By default hide the PolicyItems for all component except tag component if((!_.isUndefined(serviceDefOptions) && !_.isUndefined(serviceDefOptions.enableDenyAndExceptionsInPolicies))){ + if( !XAUtil.isAccessPolicy(this.model.get('policyType')) ) return; enableDenyAndExceptionsInPolicies = $.parseJSON(serviceDefOptions.enableDenyAndExceptionsInPolicies); } else { if(this.rangerServiceDefModel.get('name') == XAEnums.ServiceType.SERVICE_TAG.label){ @@ -241,8 +259,9 @@ define(function(require){ model : that.model, accessTypes: accessType, headerTitle: "", - rangerServiceDefModel : that.rangerServiceDefModel - }).render().el); + rangerServiceDefModel : that.rangerServiceDefModel, + rangerPolicyType : that.model.get('policyType') + }).render().el); if( enableDenyAndExceptionsInPolicies ){ that.$('[data-customfields="groupPermsAllowExclude"]').html(new PermissionList({ @@ -253,7 +272,7 @@ define(function(require){ accessTypes: accessType, headerTitle: "", rangerServiceDefModel : that.rangerServiceDefModel - }).render().el); + }).render().el); that.$('[data-customfields="groupPermsDeny"]').html(new PermissionList({ collection : that.formInputDenyList, @@ -330,29 +349,38 @@ define(function(require){ that.model.unset(key); } },this); - _.each(this.rangerServiceDefModel.get('resources'),function(obj){ + //To set resource values + //Check for masking policies + var resourceDef = this.rangerServiceDefModel.get('resources'); + if(XAUtil.isMaskingPolicy(this.model.get('policyType')) && XAUtil.isRenderMasking(this.rangerServiceDefModel.get('dataMaskDef'))){ + resourceDef = this.rangerServiceDefModel.get('dataMaskDef').resources; + } + if(XAUtil.isRowFilterPolicy(this.model.get('policyType')) && XAUtil.isRenderRowFilter(this.rangerServiceDefModel.get('rowFilterDef'))){ + resourceDef = this.rangerServiceDefModel.get('rowFilterDef').resources; + } + _.each(resourceDef,function(obj){ if(!_.isNull(obj)){ var tmpObj = that.model.get(obj.name); var rPolicyResource = new RangerPolicyResource(); //single value support - if(! XAUtil.isSinglevValueInput(obj) ){ - if(!_.isUndefined(tmpObj) && _.isObject(tmpObj)){ - rPolicyResource.set('values',tmpObj.resource.split(',')); - if(!_.isUndefined(tmpObj.isRecursive)){ - rPolicyResource.set('isRecursive', tmpObj.isRecursive) - } - if(!_.isUndefined(tmpObj.isExcludes)){ - rPolicyResource.set('isExcludes', tmpObj.isExcludes) - } - resources[obj.name] = rPolicyResource; - that.model.unset(obj.name); +// if(! XAUtil.isSinglevValueInput(obj) ){ + if(!_.isUndefined(tmpObj) && _.isObject(tmpObj)){ + rPolicyResource.set('values',tmpObj.resource.split(',')); + if(!_.isUndefined(tmpObj.isRecursive)){ + rPolicyResource.set('isRecursive', tmpObj.isRecursive) + } + if(!_.isUndefined(tmpObj.isExcludes)){ + rPolicyResource.set('isExcludes', tmpObj.isExcludes) } - }else{ - //For single value resource - rPolicyResource.set('values',tmpObj.split(',')); resources[obj.name] = rPolicyResource; that.model.unset(obj.name); } +// }else{ +// //For single value resource +// rPolicyResource.set('values',tmpObj.split(',')); +// resources[obj.name] = rPolicyResource; +// that.model.unset(obj.name); +// } } }); @@ -360,18 +388,18 @@ define(function(require){ this.model.unset('path'); //Set UserGroups Permission - var RangerPolicyItem = Backbone.Collection.extend(); - - this.model.set('policyItems', this.setPermissionsToColl(this.formInputList, new RangerPolicyItem())); - this.model.set('denyPolicyItems', this.setPermissionsToColl(this.formInputDenyList, new RangerPolicyItem())); - this.model.set('allowExceptions', this.setPermissionsToColl(this.formInputAllowExceptionList, new RangerPolicyItem())); - this.model.set('denyExceptions', this.setPermissionsToColl(this.formInputDenyExceptionList, new RangerPolicyItem())); + if( XAUtil.isMaskingPolicy(this.model.get('policyType')) ){ + this.model.set('dataMaskPolicyItems', this.setPermissionsToColl(this.formInputList, new RangerPolicyItem())); + }else if( XAUtil.isRowFilterPolicy(this.model.get('policyType')) ){ + this.model.set('rowFilterPolicyItems', this.setPermissionsToColl(this.formInputList, new RangerPolicyItem())); + }else{ + this.model.set('policyItems', this.setPermissionsToColl(this.formInputList, new RangerPolicyItem())); + this.model.set('denyPolicyItems', this.setPermissionsToColl(this.formInputDenyList, new RangerPolicyItem())); + this.model.set('allowExceptions', this.setPermissionsToColl(this.formInputAllowExceptionList, new RangerPolicyItem())); + this.model.set('denyExceptions', this.setPermissionsToColl(this.formInputDenyExceptionList, new RangerPolicyItem())); + } this.model.set('service',this.rangerService.get('name')); - /*//Unset attrs which are not needed - _.each(this.model.attributes.resources,function(obj,key){ - this.model.unset(key, obj.values.toString()) - },this)*/ }, setPermissionsToColl : function(list, policyItemList) { list.each(function(m){ @@ -389,7 +417,7 @@ define(function(require){ var rPolicyItemCondList = new RangerPolicyItemConditionList(m.get('conditions')) policyItem.set('conditions', rPolicyItemCondList) } - if(!_.isUndefined(m.get('accesses')) && !_.isUndefined(m.get('delegateAdmin'))){ + if(!_.isUndefined(m.get('delegateAdmin'))){ policyItem.set("delegateAdmin",m.get("delegateAdmin")); } if(!_.isUndefined(m.get('accesses'))){ @@ -398,6 +426,13 @@ define(function(require){ policyItem.set('accesses', rangerPlcItemAccessList) policyItemList.add(policyItem) } + if(!_.isUndefined(m.get('dataMaskInfo'))){ + policyItem.set("dataMaskInfo",m.get("dataMaskInfo")); + } + if(!_.isUndefined(m.get('rowFilterInfo'))){ + policyItem.set("rowFilterInfo",m.get("rowFilterInfo")); + } + } }, this); @@ -503,14 +538,11 @@ define(function(require){ }, getPlugginAttr :function(autocomplete, options){ - var that =this; - var type = options.containerCssClass, validRegExpString = true; + var that =this, type = options.containerCssClass, validRegExpString = true, select2Opts=[]; if(!autocomplete) return{tags : true,width :'220px',multiple: true,minimumInputLength: 1, 'containerCssClass' : type}; else { - - - return { + select2Opts = { containerCssClass : options.type, closeOnSelect : true, tags:true, @@ -520,6 +552,12 @@ define(function(require){ tokenSeparators: [",", " "], initSelection : function (element, callback) { var data = []; + //to set single select value + if(!_.isUndefined(options.singleValueInput) && options.singleValueInput){ + callback({ id : element.val(), text : element.val() }); + return; + } + //this is form multi-select value $(element.val().split(",")).each(function () { data.push({id: this, text: this}); }); @@ -590,6 +628,11 @@ define(function(require){ return "No Matches found"; } }; + //To support single value input + if(!_.isUndefined(options.singleValueInput) && options.singleValueInput){ + select2Opts['maximumSelectionSize'] = 1; + } + return select2Opts; } }, getDataParams : function(term, options) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyTableLayout.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyTableLayout.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyTableLayout.js index baad130..cd4d99e 100644 --- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyTableLayout.js +++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyTableLayout.js @@ -21,6 +21,7 @@ define(function(require){ 'use strict'; + var App = require('App'); var Backbone = require('backbone'); var XAEnums = require('utils/XAEnums'); var XALinks = require('modules/XALinks'); @@ -48,14 +49,9 @@ define(function(require){ template: RangerPolicyTableLayoutTmpl, templateHelpers : function(){ - /*return { - isSysAdmin : this.isSysAdmin, - assetId : this.assetModel.id, - assetModel : this.assetModel, - version : XAGlobals.version - };*/ return { - rangerService:this.rangerService + rangerService:this.rangerService, + rangerPolicyType : this.collection.queryParams['policyType'] }; }, @@ -77,7 +73,9 @@ define(function(require){ 'btnDeletePolicy' : '[data-name="deletePolicy"]', 'btnShowMore' : '[data-id="showMore"]', 'btnShowLess' : '[data-id="showLess"]', - 'visualSearch' : '.visual_search' + 'visualSearch' : '.visual_search', + 'policyTypeTab' : 'div[data-id="policyTypeTab"]', + 'addNewPolicy' : '[data-js="addNewPolicy"]' }, /** ui events hash */ @@ -86,7 +84,7 @@ define(function(require){ events['click ' + this.ui.btnDeletePolicy] = 'onDelete'; events['click ' + this.ui.btnShowMore] = 'onShowMore'; events['click ' + this.ui.btnShowLess] = 'onShowLess'; - + events['click ' + this.ui.policyTypeTab + ' ul li a'] = 'onTabChange'; return events; }, @@ -99,23 +97,14 @@ define(function(require){ _.extend(this, _.pick(options,'rangerService')); - /* this.collection.extraSearchParams = { -// resourceType : XAEnums.AssetType.ASSET_HDFS.value, - assetId : this.assetModel.id - };*/ this.bindEvents(); this.initializeServiceDef(); -// this.isSysAdmin = SessionMgr.isSystemAdmin(); }, /** all events binding here */ bindEvents : function(){ - //this.listenTo(this.collection, "remove", this.render, this); - /*this.listenTo(this.model, "change:foo", this.modelChanged, this);*/ - /*this.listenTo(communicator.vent,'someView:someEvent', this.someEventHandler, this)'*/ //this.listenTo(this.collection, "sync", this.render, this); - // }, initializeServiceDef : function(){ this.rangerServiceDefModel = new RangerServiceDef(); @@ -126,14 +115,18 @@ define(function(require){ }) }, - initializePolicies : function(){ + initializePolicies : function(policyType){ this.collection.url = XAUtil.getServicePoliciesURL(this.rangerService.id); + if(!_.isUndefined(policyType)){ + this.collection.queryParams['policyType'] = policyType; + } this.collection.fetch({ cache : false, }); }, /** on render callback */ onRender: function() { + this.setTabForPolicyListing(); this.addVisualSearch(); this.renderTable(); this.initializePolicies(); @@ -142,6 +135,16 @@ define(function(require){ /** all post render plugin initialization */ initializePlugins: function(){ }, + setTabForPolicyListing : function(){ + var policyType = this.collection.queryParams['policyType'] + if( XAUtil.isMaskingPolicy(policyType) ){ + this.ui.policyTypeTab.find('ul li').removeClass('active'); + this.$el.find('li[data-tab="masking"]').addClass('active'); + }else if( XAUtil.isRowFilterPolicy(policyType) ){ + this.ui.policyTypeTab.find('ul li').removeClass('active'); + this.$el.find('li[data-tab="rowLevelFilter"]').addClass('active'); + } + }, renderTable : function(){ var that = this; this.rTableList.show(new XATableLayout({ @@ -206,10 +209,10 @@ define(function(require){ label : localization.tt("lbl.group"), formatter: _.extend({}, Backgrid.CellFormatter.prototype, { fromRaw: function (rawValue, model) { - if(!_.isUndefined(rawValue)) + if(!_.isUndefined(rawValue)){ return XAUtil.showGroupsOrUsersForPolicy(rawValue, model); - else - return '--'; + } + return '--'; } }), editable : false, @@ -229,22 +232,7 @@ define(function(require){ sortable : false }, }; - /*_.each(this.rangerServiceDefModel.get('resources'), function(obj){ - if(!_.isUndefined(obj) && !_.isNull(obj)) - cols[obj.name]={ - cell : "html", - label : XAUtil.capitaliseFirstLetter(obj.name), - editable: false, - sortable : false, - formatter: _.extend({}, Backgrid.CellFormatter.prototype, { - fromRaw: function (rawValue,model) { - rawValue = model.get('resources') - return _.isUndefined(rawValue[obj.name]) ? '--' : rawValue[obj.name].values.toString(); - } - }) - }; - });*/ cols['permissions'] = { cell : "html", label : localization.tt("lbl.action"), @@ -378,6 +366,25 @@ define(function(require){ getNameOfPolicyTypeNVList : function() { return _.map(XAEnums.PolicyType, function(type) { return { 'label': type.label, 'value': type.label};}); }, + onTabChange : function(e){ + var that = this, + tab = $(e.currentTarget).attr('href'); + var href = this.ui.addNewPolicy.attr('href') + switch (tab) { + case "#access": + var val = XAEnums.RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value; + App.appRouter.navigate("#!/service/"+this.rangerService.id+"/policies/"+ val,{trigger: true}); + break; + case "#masking": + var val = XAEnums.RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value; + App.appRouter.navigate("#!/service/"+this.rangerService.id+"/policies/"+ val,{trigger: true}); + break; + case "#rowLevelFilter": + var val = XAEnums.RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value; + App.appRouter.navigate("#!/service/"+this.rangerService.id+"/policies/"+ val,{trigger: true}); + break; + } + }, /** on close */ onClose: function(){ } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/scripts/views/service/ServiceForm.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/service/ServiceForm.js b/security-admin/src/main/webapp/scripts/views/service/ServiceForm.js index dcec203..c731cea 100644 --- a/security-admin/src/main/webapp/scripts/views/service/ServiceForm.js +++ b/security-admin/src/main/webapp/scripts/views/service/ServiceForm.js @@ -88,7 +88,7 @@ define(function(require){ var attrs = _.pick(_.result(this.rangerServiceDefModel,'schemaBase'), this.getSerivceBaseFieldNames()); var that = this; var formDataType = new BackboneFormDataType(); - return formDataType.getFormElements(this.rangerServiceDefModel.get('configs'),this.rangerServiceDefModel.get('enums'), attrs, this); + return formDataType.getFormElements(this.rangerServiceDefModel.get('configs'),this.rangerServiceDefModel.get('enums'), attrs, this, false); }, /** on render callback */ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/templates/helpers/XAHelpers.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/templates/helpers/XAHelpers.js b/security-admin/src/main/webapp/templates/helpers/XAHelpers.js index ff27f97..2b5effe 100644 --- a/security-admin/src/main/webapp/templates/helpers/XAHelpers.js +++ b/security-admin/src/main/webapp/templates/helpers/XAHelpers.js @@ -511,7 +511,8 @@ Handlebars.registerHelper('getServices', function(services, serviceDef) { var XAEnums = require('utils/XAEnums'); var tr = '', serviceOperationDiv = ''; - var serviceType = serviceDef.get('name'); + var serviceType = serviceDef.get('name'), + policyType = XAEnums.RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value; if(!_.isUndefined(services[serviceType])){ _.each(services[serviceType],function(serv){ serviceName = serv.get('name'); @@ -523,7 +524,7 @@ </div>' } tr += '<tr><td><div>\ - <a data-id="'+serv.id+'" href="#!/service/'+serv.id+'/policies">'+_.escape(serv.attributes.name)+'</a>'+serviceOperationDiv+'\ + <a data-id="'+serv.id+'" href="#!/service/'+serv.id+'/policies/'+policyType+'">'+_.escape(serv.attributes.name)+'</a>'+serviceOperationDiv+'\ </div></td></tr>'; }); } @@ -542,6 +543,15 @@ return (returnFlag) ? options.fn(this) : options.inverse(this); }); + Handlebars.registerHelper('isRenderMasking', function() { + var XAEnums = require('utils/XAEnums'); + return XAUtil.isRenderMasking(XAEnums.RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value); + }); + Handlebars.registerHelper('isRenderRowFilter', function() { + var XAEnums = require('utils/XAEnums'); + return XAUtil.isRenderRowFilter(XAEnums.RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value); + }); + return HHelpers; }); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/templates/policies/PermissionItem.html ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/templates/policies/PermissionItem.html b/security-admin/src/main/webapp/templates/policies/PermissionItem.html index 99c20fa..756f8e6 100644 --- a/security-admin/src/main/webapp/templates/policies/PermissionItem.html +++ b/security-admin/src/main/webapp/templates/policies/PermissionItem.html @@ -28,13 +28,29 @@ </td> {{/if}} <td> - <a href="#" data-js="permissions" data-type="checklist" data-title="Select permissions" title="add/edit permissions" /> + <a href="#" data-js="permissions" data-type="checklist" data-title="Select permissions" title="add/edit permissions" ></a> <button type="button" class="btn btn-mini add-permissions" title="Add" style="display: inline-block;"><i class="icon-plus"></i> </button> +</td> +{{#if isMaskingPolicy}} +<td> + <a href="#" data-js="maskingType" data-type="radiolist" data-title="Select masking type" title="Select masking type" ></a> + <button type="button" class="btn btn-mini add-masking-type" title="Add" style="display: inline-block;"><i class="icon-plus"></i> + </button> </td> +{{/if}} +{{#if isRowFilterPolicy}} +<td> + <a href="#" data-js="rowLeveFilter" data-type="text" data-title="Enter row filter expression" title="Enter filter expression" ></a> + <button type="button" class="btn btn-mini add-row-filter" title="Add" style="display: inline-block;"><i class="icon-plus"></i> + </button> +</td> +{{/if}} +{{#if isAccessPolicy}} <td style=" width: 12%; "> <input data-js="delegatedAdmin" type="checkbox"> </td> +{{/if}} <td> <button type="button" class="btn btn-small btn-danger " data-action="delete"> <i class="icon-remove"></i> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html ---------------------------------------------------------------------- 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 9e31b0d..3937696 100644 --- a/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html +++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html @@ -12,7 +12,15 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --}} <form class="form-horizontal"> <fieldset> - <p class="formHeader">Policy Details :</p> + <p class="formHeader"> + 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></div> + </div> + {{/if}} {{#if id}} <div class="control-group field-id"> <label class="control-label" for="c1836_id">Policy ID</label> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/19c3744b/security-admin/src/main/webapp/templates/policies/RangerPolicyTableLayout_tmpl.html ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/templates/policies/RangerPolicyTableLayout_tmpl.html b/security-admin/src/main/webapp/templates/policies/RangerPolicyTableLayout_tmpl.html index 6776d5d..bde6b37 100644 --- a/security-admin/src/main/webapp/templates/policies/RangerPolicyTableLayout_tmpl.html +++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyTableLayout_tmpl.html @@ -14,6 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. --}} + +{{#compare "hive" "eq" this.rangerService.attributes.type}} + <div data-id="policyTypeTab"> + <ul class="nav nav-tabs tabs clearfix"> + <li data-tab="rowLevelFilter" class=""><a data-toggle="tab" + href="#rowLevelFilter">Row Level Filter</a></li> + <li data-tab="masking" class=""><a data-toggle="tab" + href="#masking">Masking</a></li> + <li data-tab="access" class="active"><a data-toggle="tab" + href="#access">Access</a></li> + </ul> +</div> +{{/compare}} <h3 class="wrap-header bold"> {{tt 'lbl.listOfPolicies'}} : {{rangerService.attributes.name}} </h3> <div class="wrap non-collapsible m-height "> <div> @@ -21,7 +34,7 @@ <div class="visual_search"></div> </div> <div class="clearfix"> - <a href="#!/service/{{rangerService.id}}/policies/create" class="btn btn-primary btn-right" type="button"> {{tt 'lbl.addNewPolicy'}} </a> + <a data-js="addNewPolicy" href="#!/service/{{rangerService.id}}/policies/create/{{this.rangerPolicyType}}" class="btn btn-primary btn-right" type="button"> {{tt 'lbl.addNewPolicy'}} </a> </div> <div data-id="r_table" class="clickable"></div>
