Repository: incubator-ranger Updated Branches: refs/heads/tag-policy 431167712 -> 85e13c4de
Added component level access type and also provided select/deselect all options in tag based policy form 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/85e13c4d Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/85e13c4d Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/85e13c4d Branch: refs/heads/tag-policy Commit: 85e13c4deb7dc97db81c7918b3c6efedda3f8e92 Parents: 4311677 Author: Gautam <[email protected]> Authored: Fri Jun 5 11:31:52 2015 +0530 Committer: Madhan Neethiraj <[email protected]> Committed: Fri Jun 5 00:08:03 2015 -0700 ---------------------------------------------------------------------- .../main/webapp/scripts/modules/XAOverrides.js | 226 +++++++++++++++++++ .../scripts/modules/globalize/message/en.js | 3 +- .../src/main/webapp/scripts/utils/XAUtils.js | 17 +- .../scripts/views/policies/PermissionList.js | 88 +++++++- .../views/policies/RangerPolicyCreate.js | 6 +- .../scripts/views/service/ServiceCreate.js | 2 +- security-admin/src/main/webapp/styles/xa.css | 35 ++- .../webapp/templates/common/TopNav_tmpl.html | 6 +- 8 files changed, 353 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/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 9bc1533..28b6128 100644 --- a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js +++ b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js @@ -568,6 +568,232 @@ }, }); + // bootstrap-editable ============================================ + /** + ********************** custom type created for tag based policies + List of taglistcheck. + Internally value stored as javascript array of values. + + @class tagchecklist + @extends list + @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); + }; + + $.fn.editableutils.inherit(TagChecklist, $.fn.editabletypes.list); + + $.extend(TagChecklist.prototype, { + renderList: function() { + var $label='', $div='', that = this; + this.$tpl.empty(); + + if(!$.isArray(this.sourceData)) { + return; + } + + this.servicePerms = _.groupBy(this.sourceData,function(obj){ + var val = obj.value; + return val.substr(0,val.indexOf(":")); + }); + var $table = $('<table>', {'class':'table table-policy-condition' }); + var $tbody = $('<tbody>'); + var $selectAllTr = $('<tr><th></th><td><i class="pull-right">Select / Deselect All</i></td><td><label><input type="checkbox" value="selectall" data-js="selectall"></label></td></tr>') + + $tbody.append($selectAllTr); + $table.append($tbody); + _.each(this.servicePerms, function(permissions,service) { + var $tr = $('<tr>'); + var $th = $('<th>').text(service); + var $td = $('<td>'); + var $selectAllPerComponent = $('<td><label><input type="checkbox" value="selectall" data-js="'+service+'selectall"></label></td>') + _.each(permissions, function(perm){ + $label = $('<label>').append($('<input>', { + type: 'checkbox', + value: perm.value, + 'data-js' : perm.value + })) + .append($('<span>').text(' '+perm.text)); + $td.append($label) + }) + $tr.append($th) + $tr.append($td) + $tr.append($selectAllPerComponent) + $tbody.append($tr) + + }, this); + $('<div>').append($table).appendTo(this.$tpl); + + this.$input = this.$tpl.find('input[type="checkbox"]'); + this.setClass(); + + this.$tpl.find('[data-js$="selectall"]').on('click',function(elem){ + console.log(elem) + var $elem = $(elem.currentTarget); + if($elem.attr('data-js') == "selectall"){ + that.$input.prop('checked',$elem.is(':checked')) + }else if($elem.attr('data-js').indexOf("selectall") >= 0){ + var idx = $elem.attr('data-js').indexOf("selectall") + var service = $elem.attr('data-js').substr(0,idx) + that.$tpl.find('[type="checkbox"][data-js^="'+service+'"]').prop('checked',$elem.is(':checked')) + var selectall = false; + selectall = true; + _.each(that.$tpl.find('[data-js$="selectall"]'), function(ele,i ){ + if($(ele).attr('data-js') != "selectall"){ + selectall = selectall && $(ele).is(':checked') + if(!selectall) return; + } + }) + that.$tpl.find('[data-js="selectall"]').prop('checked',selectall) + } + }) + + this.$tpl.find('input[type="checkbox"][data-js*=":"]').on('click',function(elem){ + //to handle selectall option for component level + var selectall = true; + _.each($(this).parent().parent().find('input'), function(ele){ + selectall = $(ele).is(':checked') && selectall + if(!selectall) return; + }) + var val = $(this).attr('data-js') + var service = val.substr(0,val.indexOf(":")) + that.$tpl.find('[data-js="'+service+'selectall"]').prop('checked',selectall) + //to handle selectall option + selectall = true; + _.each(that.$tpl.find('[data-js$="selectall"]'), function(ele,i ){ + if($(ele).attr('data-js') != "selectall"){ + selectall = selectall && $(ele).is(':checked') + if(!selectall) return; + } + }) + that.$tpl.find('[data-js="selectall"]').prop('checked',selectall) + + }) + }, + + value2str: function(value) { + return $.isArray(value) ? value.sort().join($.trim(this.options.separator)) : ''; + }, + + //parse separated string + str2value: function(str) { + var reg, value = null; + if(typeof str === 'string' && str.length) { + reg = new RegExp('\\s*'+$.trim(this.options.separator)+'\\s*'); + value = str.split(reg); + } else if($.isArray(str)) { + value = str; + } else { + value = [str]; + } + return value; + }, + + //set checked on required checkboxes + value2input: function(value) { + var that = this; + this.$input.prop('checked', false); + if($.isArray(value) && value.length) { + this.$input.each(function(i, el) { + var $el = $(el); + // cannot use $.inArray as it performs strict comparison + $.each(value, function(j, val){ + /*jslint eqeq: true*/ + if($el.val() == val) { + /*jslint eqeq: false*/ + $el.prop('checked', true); + } + }); + }); + //set checkall option for perticular service if all perms are checked + _.each(this.$tpl.find('[data-js$="selectall"]'), function(elem){ + var val = $(elem).attr('data-js') + if(val != "selectall"){ + var service = val.substr(0,val.indexOf("selectall")) + $(elem).find('[data-js^="'+service+'"]') + var serviceCheckbox = $(elem).parent().parent().siblings('td').find('input[type="checkbox"]') + var checkall = true; + _.each(serviceCheckbox, function(ele){ + checkall = $(ele).is(':checked') && checkall + if(!checkall) return; + }) + $(elem).prop('checked', checkall) + + checkall = true; + var selectAllChbx = that.$tpl.find('[data-js$="selectall"]') + _.each(selectAllChbx, function(ele){ + if($(ele).attr('data-js') == "selectall") return; + checkall = $(ele).is(':checked') && checkall + if(!checkall) return; + }) + that.$tpl.find('[data-js="selectall"]').prop('checked', checkall) + + } + }) + } + }, + + input2value: function() { + var checked = []; + this.$input.filter(':checked').each(function(i, el) { + checked.push($(el).val()); + }); + return checked; + }, + + //collect text of checked boxes + value2htmlFinal: function(value, element) { + var html = [], + checked = $.fn.editableutils.itemsByValue(value, this.sourceData), + escape = this.options.escape; + + if(checked.length) { + $.each(checked, function(i, v) { + var text = escape ? $.fn.editableutils.escape(v.text) : v.text; + html.push(text); + }); + $(element).html(html.join('<br>')); + } else { + $(element).empty(); + } + }, + }); + + TagChecklist.defaults = $.extend({}, $.fn.editabletypes.list.defaults, { + /** + @property tpl + @default <div></div> + **/ + tpl:'<div class="editable-checklist"></div>', + + /** + @property inputclass + @type string + @default null + **/ + inputclass: null, + + /** + Separator of values when reading from `data-value` attribute + + @property separator + @type string + @default ',' + **/ + separator: ',' + }); + + $.fn.editabletypes.tagchecklist = TagChecklist; + + }(window.jQuery)); + + //Scroll to top functionality on all views -- if the scroll height is > 500 px. http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/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 c427c41..36a513e 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 @@ -228,7 +228,8 @@ define(function(require) { editService : 'Edit Service', serviceDetails : 'Service Details', serviceName : 'Service Name', - isFinalPolicy : 'Is Final Policy' + isFinalPolicy : 'Is Final Policy', + componentPermissions : 'Component Permissions' }, btn : { add : 'Add', http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/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 a83b22a..00075dc 100644 --- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js +++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js @@ -1007,26 +1007,17 @@ define(function(require) { }; XAUtils.filterAllowedActions = function(controller) { var SessionMgr = require('mgrs/SessionMgr'); - if (!SessionMgr.isSystemAdmin()) { - var XAGlobals = require('utils/XAGlobals'); var that = this; var vXPortalUser = SessionMgr.getUserProfile(); var denyControllerActions = []; var denyModulesObj = []; var userModuleNames = _.pluck(vXPortalUser.get('userPermList'),'moduleName'); + //TODO Temporary fix for tag based policies : need to come from server + userModuleNames.push('Tag Based Policies') var groupModuleNames = _.pluck(vXPortalUser.get('groupPermissions'), 'moduleName'); var moduleNames = _.union(userModuleNames, groupModuleNames); - //TODO - /*if($.inArray('Policy Manager',moduleNames) >= 0){ - moduleNames.push('Resource Based Policies') - } - if($.inArray('Analytics',moduleNames) >= 0){ - moduleNames.push('Reports') - } - if($.inArray('KMS',moduleNames) >= 0){ - moduleNames.push('Key Manager') - }*/ + _.each(XAGlobals.ListOfModuleActions,function(val,key){ if(!_.isArray(val)){ _.each(val,function(val1,key1){ @@ -1056,8 +1047,6 @@ define(function(require) { } }); } - - } return controller; }; XAUtils.getRangerServiceByName = function(name) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/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 0901892..d6c9a97 100644 --- a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js +++ b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js @@ -66,7 +66,7 @@ define(function(require) { }, initialize : function(options) { - _.extend(this, _.pick(options, 'groupList','policyType','accessTypes','policyConditions','userList')); + _.extend(this, _.pick(options, 'groupList','policyType','accessTypes','policyConditions','userList','rangerServiceDefModel')); this.setupPermissionsAndConditions(); }, @@ -82,7 +82,11 @@ define(function(require) { this.dropDownChange(this.ui.selectGroups); this.dropDownChange(this.ui.selectUsers); //render permissions and policy conditions - this.renderPerms(); + if(this.rangerServiceDefModel.get('name') == XAEnums.ServiceType.SERVICE_TAG.label){ + this.renderPermsForTagBasedPolicies() + }else{ + this.renderPerms(); + } this.renderPolicyCondtion(); }, setupFormForEditMode : function() { @@ -300,6 +304,75 @@ define(function(require) { }); }, + renderPermsForTagBasedPolicies :function(){ + var that = this; + this.ui.addPerms.attr('data-type','tagchecklist') + this.ui.addPerms.attr('title','Components Permissions') + this.ui.delegatedAdmin.parent('td').hide(); + this.perms = _.map(this.accessTypes,function(m){return {text:m.label, value:m.name};}); +// this.perms.push({'value' : -1, 'text' : 'Select/Deselect All'}); + //create x-editable for permissions + this.ui.addPerms.editable({ + emptytext : 'Add Permissions', + source: this.perms, + value : this.permsIds, + display: function(values,srcData) { + if(_.isNull(values) || _.isEmpty(values)){ + $(this).empty(); + that.model.unset('accesses'); + that.ui.addPermissionsSpan.find('i').attr('class', 'icon-plus'); + that.ui.addPermissionsSpan.attr('title','add'); + return; + } + if(_.contains(values,"-1")){ + values = _.without(values,"-1") + } + //To remove selectall options + values = _.uniq(values); + if(values.indexOf("selectall") >= 0){ + values.splice(values.indexOf("selectall"), 1) + } +// that.checkDirtyFieldForGroup(values); + + + var permTypeArr = []; + var valArr = _.map(values, function(id){ + if(!_.isUndefined(id)){ + var obj = _.findWhere(srcData,{'value' : id}); + permTypeArr.push({permType : obj.value}); + return "<span class='label label-info'>" + id.substr(0,id.indexOf(":")).toUpperCase() + "</span>"; + } + }); + var perms = [] + if(that.model.has('accesses')){ + perms = that.model.get('accesses'); + } + + var items=[]; + _.each(that.accessItems, function(item){ + if($.inArray( item.type, values) >= 0){ + item.isAllowed = true; + items.push(item) ; + } + },this); + // Save form data to model + that.model.set('accesses', items); + $(this).html(_.uniq(valArr).join(" ")); + that.ui.addPermissionsSpan.find('i').attr('class', 'icon-pencil'); + that.ui.addPermissionsSpan.attr('title','edit'); + }, + }).on('click', function(e) { + e.stopPropagation(); + e.preventDefault(); + that.clickOnPermissions(that); + }); + that.ui.addPermissionsSpan.click(function(e) { + e.stopPropagation(); + that.$('a[data-js="permissions"]').editable('toggle'); + that.clickOnPermissions(that); + }); + + }, clickOnPermissions : function(that) { var selectAll = true; var checklist = that.$('.editable-checklist').find('input[type="checkbox"]') @@ -472,7 +545,8 @@ define(function(require) { 'userList' : this.userList, 'policyType' : this.policyType, 'accessTypes' : this.accessTypes, - 'policyConditions' : this.rangerServiceDefModel.get('policyConditions') + 'policyConditions' : this.rangerServiceDefModel.get('policyConditions'), + 'rangerServiceDefModel' : this.rangerServiceDefModel }; }, events : { @@ -513,8 +587,12 @@ define(function(require) { }, getPermHeaders : function(){ var permList = []; - permList.unshift(localization.tt('lbl.delegatedAdmin')); - permList.unshift(localization.tt('lbl.permissions')); + if(this.rangerServiceDefModel.get('name') != XAEnums.ServiceType.SERVICE_TAG.label){ + permList.unshift(localization.tt('lbl.delegatedAdmin')); + 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')); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/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 7370ee8..332a1d9 100644 --- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js +++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js @@ -48,11 +48,11 @@ define(function(require){ }; }, breadCrumbs :function(){ - + var name = this.rangerServiceDefModel.get('name') != XAEnums.ServiceType.SERVICE_TAG.label ? 'ServiceManager' : 'TagBasedServiceManager'; if(this.model.isNew()) - return [XALinks.get('ServiceManager'),XALinks.get('ManagePolicies',{model : this.rangerService}),XALinks.get('PolicyCreate')]; + return [XALinks.get(name),XALinks.get('ManagePolicies',{model : this.rangerService}),XALinks.get('PolicyCreate')]; else - return [XALinks.get('ServiceManager'),XALinks.get('ManagePolicies',{model : this.rangerService}),XALinks.get('PolicyEdit')]; + return [XALinks.get(name),XALinks.get('ManagePolicies',{model : this.rangerService}),XALinks.get('PolicyEdit')]; } , /** Layout sub regions */ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js b/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js index b14179e..9c6890f 100644 --- a/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js +++ b/security-admin/src/main/webapp/scripts/views/service/ServiceCreate.js @@ -268,7 +268,7 @@ define(function(require){ }, onCancel : function(){ XAUtil.allowNavigation(); - if(XAEnums.ServiceType.SERVICE_TAG.label == this.model.get('type')){ + if(XAEnums.ServiceType.SERVICE_TAG.label == this.rangerServiceDefModel.get('name')){ App.appRouter.navigate("#!/policymanager/tag",{trigger: true}); return; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/security-admin/src/main/webapp/styles/xa.css ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/styles/xa.css b/security-admin/src/main/webapp/styles/xa.css index ceb1f53..1a686d6 100644 --- a/security-admin/src/main/webapp/styles/xa.css +++ b/security-admin/src/main/webapp/styles/xa.css @@ -598,12 +598,12 @@ table td.backgrid-filter .clear { background-color: #eeeeee; } -table.table-permission tr th:last-child, table.table-permission tr td:last-child { +/*table.table-permission tr th:last-child, table.table-permission tr td:last-child { border: 0; padding-left: 6%; color: transparent; background-color: #fff; -} +}*/ .table-permission thead tr { color: #4F4F4F; @@ -1838,4 +1838,33 @@ td.select-row-cell { #r_topNav .dropdown-menu { margin:0; -} \ No newline at end of file +} + +.table-policy-condition th, +.table-policy-condition td { + border: none !important; + white-space: nowrap; + color: #444444 !important; +} + +.table-policy-condition tr:nth-child(even) td, .table-policy-condition tr:nth-child(even) th {background-color: #E4F4D8;} +.table-policy-condition tr:nth-child(odd) td, .table-policy-condition tr:nth-child(odd) th {background-color: #DEEEF9;} + +.table-policy-condition label { + float: left; + margin-right: 10px; +} +.label-lightblue, .label-lightgreen {text-shadow:none; display: block; margin-bottom: 2px;} +.label-lightblue {background-color: #DEEEF9; color: #000;} +.label-lightgreen {background-color: #E4F4D8; color: #000;} + +input[type="radio"], input[type="checkbox"] {margin-top: 0;} + +.table-policy-condition td:nth-child(3) { + border-left: 2px solid #fff !important; +} +.table-policy-condition td:nth-child(3) label { + float: none; + text-align: center; + margin-left: 10px; +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/85e13c4d/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html b/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html index a29423f..6b62ba3 100644 --- a/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html +++ b/security-admin/src/main/webapp/templates/common/TopNav_tmpl.html @@ -22,12 +22,12 @@ {{#hasAccessToTab 'Resource Based Policies'}} <li><a href="#!/policymanager/resource"><i class="icon-file"></i>Resource Based Policies</a></li> {{/hasAccessToTab}} - {{#hasAccessToTab 'Reports'}} - <li><a href="#!/reports/userAccess"><i class="icon-beaker"></i>Reports</a></li> - {{/hasAccessToTab}} {{#hasAccessToTab 'Tag Based Policies'}} <li><a href="#!/policymanager/tag"><i class="icon-tag"></i>Tag Based Policies</a></li> {{/hasAccessToTab}} + {{#hasAccessToTab 'Reports'}} + <li><a href="#!/reports/userAccess"><i class="icon-beaker"></i>Reports</a></li> + {{/hasAccessToTab}} </ul> </li> {{#hasAccessToTab 'Audit'}}
