Repository: incubator-ranger Updated Branches: refs/heads/master 405c51853 -> 0ab48758f
RANGER-326 : Add RO view of policy from Audit page Signed-off-by: Velmurugan Periasamy <[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/0ab48758 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/0ab48758 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/0ab48758 Branch: refs/heads/master Commit: 0ab48758fb0089da3b81978d00e2122f535c14ad Parents: 405c518 Author: Gautam Borad <[email protected]> Authored: Mon Mar 23 20:23:10 2015 +0530 Committer: Velmurugan Periasamy <[email protected]> Committed: Tue Mar 24 01:15:28 2015 -0400 ---------------------------------------------------------------------- .../org/apache/ranger/biz/ServiceDBStore.java | 7 + .../org/apache/ranger/rest/ServiceREST.java | 2 +- .../main/webapp/scripts/models/RangerPolicy.js | 14 ++ .../src/main/webapp/scripts/utils/XAEnums.js | 15 ++ .../scripts/views/policies/RangerPolicyRO.js | 138 +++++++++++++++++++ .../webapp/scripts/views/reports/AuditLayout.js | 42 +++++- security-admin/src/main/webapp/styles/xa.css | 7 + .../templates/policies/RangerPolicyRO_tmpl.html | 113 +++++++++++++++ 8 files changed, 335 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java index 844a52e..15530bf 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java @@ -1298,6 +1298,13 @@ public class ServiceDBStore implements ServiceStore { XXDataHist xDataHist = daoMgr.getXXDataHist().findObjByEventTimeClassTypeAndId(eventTime, AppConstants.CLASS_TYPE_RANGER_POLICY, policyId); + + if (xDataHist == null) { + String errMsg = "No policy history found for given time: " + eventTime; + LOG.error(errMsg); + throw restErrorUtil.createRESTException(errMsg, MessageEnums.DATA_NOT_FOUND); + } + String content = xDataHist.getContent(); RangerPolicy policy = (RangerPolicy) dataHistService.writeJsonToJavaObject(content, RangerPolicy.class); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java index 1cfaa91..5efa2c3 100644 --- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java +++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java @@ -1496,7 +1496,7 @@ public class ServiceREST { Long policyId = Long.parseLong(policyIdStr); Date eventTime = restErrorUtil.parseDate(eventTimeStr, "Invalid value for" + "Event Time", - MessageEnums.INVALID_INPUT_DATA, null, "eventTime", "MM/dd/yyyy"); + MessageEnums.INVALID_INPUT_DATA, null, "eventTime", "MM/dd/yyyy hh:mm:ss"); RangerPolicy policy = svcStore.getPolicyFromEventTime(eventTime, policyId); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/security-admin/src/main/webapp/scripts/models/RangerPolicy.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/models/RangerPolicy.js b/security-admin/src/main/webapp/scripts/models/RangerPolicy.js index 0d8574d..2228f23 100644 --- a/security-admin/src/main/webapp/scripts/models/RangerPolicy.js +++ b/security-admin/src/main/webapp/scripts/models/RangerPolicy.js @@ -83,6 +83,20 @@ define(function(require){ }); }, + /** need to pass eventTime in queryParams(opt.data) */ + fetchByEventTime : function(opt){ + var queryParams = opt.data; + queryParams.policyId = this.get('id'); + if(_.isUndefined(queryParams.eventTime)){ + throw('eventTime can not be undefined'); + }else{ + queryParams.eventTime = Globalize.format(new Date(queryParams.eventTime), "MM/dd/yyyy hh:mm:ss") + } + + opt.url = 'service/plugins/policies/eventTime'; + return this.fetch(opt); + }, + /** This models toString() */ toString : function(){ return this.get('name'); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/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 ce842f7..a8e9ead 100644 --- a/security-admin/src/main/webapp/scripts/utils/XAEnums.js +++ b/security-admin/src/main/webapp/scripts/utils/XAEnums.js @@ -78,6 +78,21 @@ define(function(require) { STATUS_VISIBLE:{value:1, label:'Visible', rbkey:'xa.enum.VisibilityStatus.IS_VISIBLE', tt: 'lbl.VisibilityStatus_IS_VISIBLE'} }); + XAEnums.AuditStatus = mergeParams(XAEnums.AuditStatus, { + AUDIT_ENABLED:{value:true, label:'Yes', rbkey:'xa.enum.AuditStatus.ENABLED', tt: 'lbl.AuditStatus_ENABLED'}, + AUDIT_DISABLED:{value:false, label:'No', rbkey:'xa.enum.AuditStatus.DISABLED', tt: 'lbl.AuditStatus_DISABLED'} + }); + + XAEnums.RecursiveStatus = mergeParams(XAEnums.RecursiveStatus, { + STATUS_RECURSIVE:{value:true, label:'recursive', rbkey:'xa.enum.RecursiveStatus.RECURSIVE', tt: 'lbl.RecursiveStatus_RECURSIVE'}, + STATUS_NONRECURSIVE:{value:false, label:'nonrecursive', rbkey:'xa.enum.RecursiveStatus.NONRECURSIVE', tt: 'lbl.RecursiveStatus_NONRECURSIVE'} + }); + + XAEnums.ExcludeStatus = mergeParams(XAEnums.ExcludeStatus, { + STATUS_EXCLUDE:{value:true, label:'exclude', rbkey:'xa.enum.ExcludeStatus.EXCLUDE', tt: 'lbl.ExcludeStatus_EXCLUDE'}, + STATUS_INCLUDE:{value:false, label:'include', rbkey:'xa.enum.ExcludeStatus.INCLUDE', tt: 'lbl.ExcludeStatus_INCLUDE'} + }); + XAEnums.ActiveStatus = mergeParams(XAEnums.ActiveStatus, { STATUS_DISABLED:{value:0, label:'Disabled', rbkey:'xa.enum.ActiveStatus.STATUS_DISABLED', tt: 'lbl.ActiveStatus_STATUS_DISABLED'}, STATUS_ENABLED:{value:1, label:'Enabled', rbkey:'xa.enum.ActiveStatus.STATUS_ENABLED', tt: 'lbl.ActiveStatus_STATUS_ENABLED'}, http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js new file mode 100644 index 0000000..16f489a --- /dev/null +++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js @@ -0,0 +1,138 @@ +/* + * 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 XAEnums = require('utils/XAEnums'); + var XAGlobals = require('utils/XAGlobals'); + var XAUtils = require('utils/XAUtils'); + var localization = require('utils/XALangSupport'); + + var RangerPolicyROTmpl = require('hbs!tmpl/policies/RangerPolicyRO_tmpl'); + var RangerService = require('models/RangerService'); + + var RangerPolicyRO = Backbone.Marionette.Layout.extend({ + _viewName: 'RangerPolicyRO', + + template: RangerPolicyROTmpl, + templateHelpers: function() { + return { + PolicyDetails: this.PolicyDetails, + }; + }, + breadCrumbs: [], + + /** Layout sub regions */ + regions: { + //'rAuditTable' : 'div[data-id="r_auditTable"]', + }, + + /** ui selector cache */ + ui: { + + }, + + /** ui events hash */ + events: function() { + var events = {}; + return events; + }, + + /** + * intialize a new AuditLayout Layout + * @constructs + */ + initialize: function(options) { + _.extend(this, options); + this.initializePolicy(); + this.initializePolicyDetailsObj(); + }, + + initializePolicy: function() { + var data = { + eventTime : this.eventTime, + }; + this.policy.fetchByEventTime({ + async: false, + cache: false, + data : data + }); + }, + + initializePolicyDetailsObj : function(){ + var self = this; + var details = this.PolicyDetails = {}; + details.id = this.policy.get('id'); + details.name = this.policy.get('name'); + details.isEnabled = this.policy.get('isEnabled') ? localization.tt('lbl.ActiveStatus_STATUS_ENABLED') : localization.tt('lbl.ActiveStatus_STATUS_DISABLED'); + details.description = this.policy.get('description'); + details.isAuditEnabled = this.policy.get('isAuditEnabled') ? XAEnums.AuditStatus.AUDIT_ENABLED.label : XAEnums.AuditStatus.AUDIT_DISABLED.label; + details.resources = []; + _.each(this.serviceDef.get('resources'), function(def, i){ + if(!_.isUndefined(this.policy.get('resources')[def.name])){ + var resource = {}, + policyResources = this.policy.get('resources')[def.name]; + resource.label = def.label; + resource.values = policyResources.values; + if(def.recursiveSupported){ + resource.Rec_Exc = policyResources.isRecursive ? XAEnums.RecursiveStatus.STATUS_RECURSIVE.label : XAEnums.RecursiveStatus.STATUS_NONRECURSIVE.label; + } else if(def.excludesSupported){ + resource.Rec_Exc = policyResources.isExcludes ? XAEnums.ExcludeStatus.STATUS_EXCLUDE.label : XAEnums.ExcludeStatus.STATUS_INCLUDE.label; + } + details.resources.push(resource); + } + }, this); + var perm = details.permissions = this.getPermHeaders(); + perm.policyItems = this.policy.get('policyItems'); + }, + + /** all events binding here */ + bindEvents: function() {}, + + /** on render callback */ + onRender: function() { + this.$el.find('#permissionsDetails table tr td:empty').html('-') + }, + + getPermHeaders : function(){ + var permList = [], + policyCondition = false; + permList.unshift(localization.tt('lbl.delegatedAdmin')); + permList.unshift(localization.tt('lbl.permissions')); + if(!_.isEmpty(this.serviceDef.get('policyConditions'))){ + permList.unshift(localization.tt('h.policyCondition')); + policyCondition = true; + } + permList.unshift(localization.tt('lbl.selectUser')); + permList.unshift(localization.tt('lbl.selectGroup')); + return { + header : permList, + policyCondition : policyCondition + }; + }, + + /** on close */ + onClose: function() {} + }); + + return RangerPolicyRO; +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/security-admin/src/main/webapp/scripts/views/reports/AuditLayout.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/reports/AuditLayout.js b/security-admin/src/main/webapp/scripts/views/reports/AuditLayout.js index 7f27f84..1e0d4c5 100644 --- a/security-admin/src/main/webapp/scripts/views/reports/AuditLayout.js +++ b/security-admin/src/main/webapp/scripts/views/reports/AuditLayout.js @@ -39,6 +39,8 @@ define(function(require) { var RangerService = require('models/RangerService'); var AuditlayoutTmpl = require('hbs!tmpl/reports/AuditLayout_tmpl'); var vOperationDiffDetail = require('views/reports/OperationDiffDetail'); + var RangerPolicy = require('models/RangerPolicy'); + var RangerPolicyRO = require('views/policies/RangerPolicyRO'); require('moment'); require('bootstrap-datepicker'); @@ -713,14 +715,49 @@ define(function(require) { }, renderBigDataTable : function(){ + var that = this , self = this; + var TableRow = Backgrid.Row.extend({ + events: { + 'click' : 'onClick' + }, + initialize : function(){ + var that = this; + var args = Array.prototype.slice.apply(arguments); + Backgrid.Row.prototype.initialize.apply(this, args); + }, + onClick: function (e) { + var self = this; + var policyId = this.model.get('policyId'); + var serviceDef = that.serviceDefList.findWhere({'id':this.model.get('repoType')}); + var eventTime = this.model.get('eventTime'); + + var policy = new RangerPolicy({ + id: policyId + }); + var view = new RangerPolicyRO({ + policy: policy, + serviceDef: serviceDef, + eventTime : eventTime + }); + var modal = new Backbone.BootstrapModal({ + animate : true, + content : view, + title: localization.tt("h.policy")+': '+policy.get('name'), + okText :localization.tt("lbl.ok"), + allowCancel : false, + escape : true + }).open(); + } + }); + this.ui.tableList.removeClass("clickable"); this.rTableList.show(new XATableLayout({ columns: this.getColumns(), collection: this.accessAuditList, includeFilter : false, gridOpts : { - row: Backgrid.Row.extend({}), + row: TableRow, header : XABackgrid, emptyText : 'No Access Audit found!' } @@ -744,7 +781,8 @@ define(function(require) { cache : false, async : false }); - var href = '#!/service/'+rangerService.get('id')+'/policies/'+model.get('policyId')+'/edit'; + // var href = '#!/service/'+rangerService.get('id')+'/policies/'+model.get('policyId')+'/edit'; + var href = 'javascript:void(0)'; return '<a href="'+href+'" title="'+rawValue+'">'+rawValue+'</a>'; } }), http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/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 d15ce94..b2ade90 100644 --- a/security-admin/src/main/webapp/styles/xa.css +++ b/security-admin/src/main/webapp/styles/xa.css @@ -1,3 +1,4 @@ + /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -639,6 +640,12 @@ table.backgrid thead tr:hover { background: transparent; } +.table-read-only tr th:last-child, table.table-read-only tr td:last-child { + border: 1px solid #dddddd !important; + color: #4F4F4F !important; + background-color: inherit !important; +} + .r-path { word-break: break-all; font-weight: normal; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/0ab48758/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html b/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html new file mode 100644 index 0000000..b2cec3a --- /dev/null +++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html @@ -0,0 +1,113 @@ +{{!-- + 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. +--}} +<div id="policyDetails"> + <p class="formHeader"> + Policy Details : + </p> + <table class="table table-bordered table-condensed"> + <tbody> + <tr> + <td> + {{tt 'lbl.policyId'}} + </td> + <td> + <div class="controls"><label class="label label-ranger">{{PolicyDetails.id}}</label></div> + </td> + </tr> + <tr> + <td> + {{tt 'lbl.policyName'}} + </td> + <td> + {{PolicyDetails.name}} + <span class="label label-inverse pull-right">{{PolicyDetails.isEnabled}}</span> + </td> + </tr> + {{#each PolicyDetails.resources}} + <tr> + <td> + {{this.label}} + </td> + <td> + {{#each this.values}} + <span class="label label-info">{{this}}</span> + {{/each}} + <span class="label label-inverse pull-right">{{this.Rec_Exc}}</span> + </td> + </tr> + {{/each}} + <tr> + <td> + {{tt 'lbl.description'}} + </td> + <td> + {{PolicyDetails.description}} + </td> + </tr> + </tr> + <td> + {{tt 'lbl.auditLogging'}} + </td> + <td> + <span class="label label-info">{{PolicyDetails.isAuditEnabled}}</span> + </td> + </tr> + </tbody> + </table> +</div> +<div id="permissionsDetails"> + <p class="formHeader"> + User and Group Permissions : + </p> + <table class="table-permission table-condensed table-read-only" style="width:100%"> + <thead> + <tr> + {{#each PolicyDetails.permissions.header}} + <th>{{this}}</th> + {{/each}} + </tr> + </thead> + <tbody> + {{#each PolicyDetails.permissions.policyItems}} + <tr> + <td>{{#each this.groups}} + <span class="label label-info">{{this}}</span> + {{/each}}</td> + <td>{{#each this.users}} + <span class="label label-info">{{this}}</span> + {{/each}}</td> + {{#if ../PolicyDetails.permissions.policyCondition}} + <td>{{#each this.conditions}} + <span class="label label-info"> + {{this.type}} : + {{#each this.values}} + {{this}} + {{/each}} + </span> + {{/each}}</td> + {{/if}} + <td>{{#each this.accesses}} + <span class="label label-info">{{#if this.isAllowed}}{{this.type}}{{/if}}</span> + {{/each}}</td> + <td> + <input type="checkbox" {{#if this.delegateAdmin}}checked{{/if}} disabled="disabled"> + </td> + </tr> + {{/each}} + </tbody> + </table> +</div> \ No newline at end of file
