You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by pr...@apache.org on 2018/03/09 08:12:35 UTC

ranger git commit: RANGER-1985: [UI] Auditing for Ranger Usersync operations

Repository: ranger
Updated Branches:
  refs/heads/master 12cfce001 -> 8888b6285


RANGER-1985: [UI] Auditing for Ranger Usersync operations

Signed-off-by: pradeep <pr...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/8888b628
Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/8888b628
Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/8888b628

Branch: refs/heads/master
Commit: 8888b6285fba7373df8b00a0dd5b0ac0c4b17aea
Parents: 12cfce0
Author: ni3galave <ni...@gmail.com>
Authored: Thu Mar 8 20:03:48 2018 +0530
Committer: pradeep <pr...@apache.org>
Committed: Fri Mar 9 13:42:00 2018 +0530

----------------------------------------------------------------------
 .../scripts/modules/globalize/message/en.js     |  27 ++-
 .../src/main/webapp/scripts/utils/XAEnums.js    |   6 +
 .../main/webapp/scripts/utils/XAViewUtils.js    |  30 ++++
 .../webapp/scripts/views/reports/AuditLayout.js | 168 +++++++++++++++++--
 security-admin/src/main/webapp/styles/xa.css    |   6 +
 .../webapp/templates/kms/KmsKeyCreate_tmpl.html |   2 +-
 .../policies/RangerPolicyCreate_tmpl.html       |   2 +-
 .../templates/reports/AuditLayout_tmpl.html     |   3 +
 .../templates/reports/UserSyncInfo_tmpl.html    |  34 ++++
 .../templates/service/ServiceCreate_tmpl.html   |   2 +-
 .../templates/users/GroupCreate_tmpl.html       |   2 +-
 .../webapp/templates/users/UserCreate_tmpl.html |   2 +-
 12 files changed, 264 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/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 c3b41c1..d10c6a7 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
@@ -244,7 +244,24 @@ define(function(require) {
                 clusterName                     : 'Cluster Name',
                 policyLabels					: 'Policy Labels',
                 activeStatus                    : 'Active Status',
-                selectTagService                : 'Tag Service'
+                selectTagService                : 'Tag Service',
+                syncSource                      : 'Sync Source',
+                noOfUsers                       : 'No. of users',
+                noOfGroups                      : 'No. of groups',
+                unixBackend                     : 'Unix',
+                fileName                        : 'File Name',
+                syncTime                        : 'Sync time',
+                lastModified                    : 'Last modified time',
+                ldapUrl                         : 'Ldap url',
+                isIncrementalSync               : 'Incremental sync',
+                groupHierarchyLevel             : 'Group hierarchy level',
+                minUserId                       : "Minimum user id",
+                minGroupId                      : "Minimum group id",
+                userSearchFilter                : 'User search filter',
+                groupSearchFilter               : 'Group search filter',
+                startDate                       : 'Start Date',
+                endDate                         : 'End Date'
+
 
 			},
 			btn : {
@@ -355,7 +372,10 @@ define(function(require) {
                 rowFilter                   : 'Row Filter',
                 policyLabelsinfo			: 'Label of policy',
                 serviceDetails              :'Service Details',
-                configProperties            : 'Config Properties'
+                configProperties            : 'Config Properties',
+                userSync                    :'User Sync',
+                syncSourceInfo              :'Sync Source',
+                syncDetails                  :'Sync Details'
                         },
 			msg : {
 				deletePolicyValidationMsg : 'Policy does not have any settings for the specific resource. Policy will be deleted. Press [Ok] to continue. Press [Cancel] to edit the policy.',
@@ -426,7 +446,8 @@ define(function(require) {
                 addUserOrGroupForDelegateAdmin      : 'Please select user/group for the selected permission(s)',
                 policyLabelsinfo		: 'Enter label of policy',
                 noUserFoundText			: 'No user associate with this group.',
-                showInitialHundredUser  : 'Initially search filter is applied for first hundred users. To get more users click on '
+                showInitialHundredUser  : 'Initially search filter is applied for first hundred users. To get more users click on ',
+                searchForUserSync       :"Search for your user sync audits..."
  
 			},
 			plcHldr : {

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/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 4aa21c1..6e101bf 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAEnums.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAEnums.js
@@ -375,5 +375,11 @@ define(function(require) {
                 XA_TAG_BASED_POLICIES:{value:6, label:'Tag Based Policies', rbkey:'xa.enum.MenuPermissions.XA_TAG_BASED_POLICIES', tt: 'lbl.XAPermForType_XA_TAG_BASED_POLICIES'}
 	});
 
+        XAEnums.UserSyncSource = mergeParams(XAEnums.UserSyncSource, {
+                USER_SYNC_UNIX:{value:0, label:'Unix', rbkey:'xa.enum.UserSyncSource.USER_SYNC_UNIX', tt: 'lbl.USER_SYNC_UNIX'},
+                USER_SYNC_LDAPAD:{value:1, label:'LDAP/AD', rbkey:'xa.enum.UserSyncSource.USER_SYNC_LDAPAD', tt: 'lbl.USER_SYNC_LDAPAD'},
+                USER_SYNC_FILE:{value:2, label:'File', rbkey:'xa.enum.UserSyncSource.USER_SYNC_FILE', tt: 'lbl.USER_SYNC_FILE'}
+        });
+
 	return XAEnums;
 });

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/scripts/utils/XAViewUtils.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/utils/XAViewUtils.js b/security-admin/src/main/webapp/scripts/utils/XAViewUtils.js
index 11a0624..fabf709 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAViewUtils.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAViewUtils.js
@@ -25,6 +25,7 @@ define(function(require) {
     var XAEnums = require('utils/XAEnums');
     var localization = require('utils/XALangSupport');
     var XAViewUtil = {};
+    require('Backbone.BootstrapModal');
 
     XAViewUtil.resourceTypeFormatter = function(rawValue, model){
         var resourcePath = _.isUndefined(model.get('resourcePath')) ? undefined : model.get('resourcePath');
@@ -91,6 +92,35 @@ define(function(require) {
             });
         }
     };
+
+    XAViewUtil.syncSourceDetail = function(e , that){
+        if($(e.target).is('.icon-edit,.icon-trash,a,code'))
+            return;
+        var SyncSourceView = Backbone.Marionette.ItemView.extend({
+            template : require('hbs!tmpl/reports/UserSyncInfo_tmpl'),
+            templateHelpers:function(){
+                var syncSourceInfo = _.filter(that.userSyncAuditList.models , function(m){
+                    return m.id == e.currentTarget.getAttribute('id');
+                });
+                syncSourceInfo = _.map(syncSourceInfo[0].get('syncSourceInfo'), function(value, key){
+                    return {'label': 'lbl.'+key, 'value': value };
+                });
+                return {'syncSourceInfo' : syncSourceInfo };
+            },
+            initialize: function(){
+            },
+            onRender: function(){}
+        });
+        var modal = new Backbone.BootstrapModal({
+            animate : true,
+            content     : new SyncSourceView({model : this.model}),
+            title: localization.tt("h.syncDetails"),
+            okText :localization.tt("lbl.ok"),
+            allowCancel : true,
+            escape : true
+        }).open();
+        modal.$el.find('.cancel').hide();
+    };
 	
 	return XAViewUtil;
 

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/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 d2703c0..c80dd4f 100644
--- a/security-admin/src/main/webapp/scripts/views/reports/AuditLayout.js
+++ b/security-admin/src/main/webapp/scripts/views/reports/AuditLayout.js
@@ -40,6 +40,7 @@ define(function(require) {
 	var RangerServiceDefList 		= require('collections/RangerServiceDefList');
 	var RangerService				= require('models/RangerService');
 	var RangerServiceList			= require('collections/RangerServiceList');
+        var VXUserList 				= require('collections/VXUserList');
 	var AuditlayoutTmpl 			= require('hbs!tmpl/reports/AuditLayout_tmpl');
 	var vOperationDiffDetail		= require('views/reports/OperationDiffDetail');
 	var RangerPolicy 				= require('models/RangerPolicy');
@@ -90,7 +91,8 @@ define(function(require) {
             btnShowMore : '[data-id="showMore"]',
                         btnShowLess : '[data-id="showLess"]',
             iconqueryInfo : '[data-name="queryInfo"]',
-            hidePopup : '[data-id="hide-popup"]'
+            hidePopup : '[data-id="hide-popup"]',
+            syncDetailes : '[data-id="syncDetailes"]'
 		},
 
 		/** ui events hash */
@@ -104,6 +106,7 @@ define(function(require) {
             if(this.currentTab == '#bigData'){
                 events['click ' + this.ui.hidePopup]  = 'onClickOutSide';
             }
+            events['click '+this.ui.syncDetailes] = 'onSyncDetailes';
             return events;
 		},
 
@@ -122,7 +125,7 @@ define(function(require) {
 			this.initializeServiceDefColl();
             if(_.isUndefined(App.vsHistory)){
 	            var startDateModel = new Backbone.Model({'category':'Start Date', value:Globalize.format(new Date(),"MM/dd/yyyy")});
-	            App.vsHistory = {'bigData':[startDateModel], 'admin':[], 'loginSession':[], 'plugin':[],'pluginStatus':[]};
+                    App.vsHistory = {'bigData':[startDateModel], 'admin':[], 'loginSession':[], 'plugin':[],'pluginStatus':[], 'userSync': []};
             }
 		},
 
@@ -257,27 +260,39 @@ define(function(require) {
 					break;
 				case "#pluginStatus":
 					 this.currentTab = '#pluginStatus';
-                                         App.vsHistory.pluginStatus = XAUtils.removeEmptySearchValue(App.vsHistory.pluginStatus);
+                     App.vsHistory.pluginStatus = XAUtils.removeEmptySearchValue(App.vsHistory.pluginStatus);
 					 this.ui.visualSearch.show();
 					 this.pluginInfoList = new VXPolicyExportAuditList();
-                                         this.renderPluginInfoTable();
+                     this.renderPluginInfoTable();
 					 this.modifyPluginStatusTableSubcolumns();
 					 //To use existing collection
 					 this.pluginInfoList.url = 'service/plugins/plugins/info';
 					 this.pluginInfoList.modelAttrName = 'pluginInfoList';
-                                         if(_.isEmpty(App.vsHistory.pluginStatus)){
-                                                 this.pluginInfoList.fetch({cache : false});
-                                         }
+                     if(_.isEmpty(App.vsHistory.pluginStatus)){
+                         this.pluginInfoList.fetch({cache : false});
+                     }
 					 this.addSearchForPluginStatusTab();
 					 this.ui.iconSearchInfo.hide();
                      $('.popover').remove();
 					 break;
+                case "#userSync":
+                     this.currentTab = '#userSync';
+                     this.ui.visualSearch.show();
+                     this.userSyncAuditList = new VXUserList();
+                     this.renderUserSyncTable();
+                     //To use existing collection
+                     this.userSyncAuditList.url = 'service/assets/ugsyncAudits';
+                     this.userSyncAuditList.modelAttrName = 'vxUgsyncAuditInfoList';
+                     this.userSyncAuditList.setSorting('id',1);
+                     this.addSearchForUserSyncTab();
+                     this.ui.iconSearchInfo.hide();
+                     break;
 			}
 			var lastUpdateTime = Globalize.format(new Date(),  "MM/dd/yyyy hh:mm:ss tt");
 			that.ui.lastUpdateTimeLabel.html(lastUpdateTime);
 		},
 		addSearchForBigDataTab :function(){
-                        var that = this , query = '';
+            var that = this , query = '';
 			var serverListForRepoType =  this.serviceDefList.map(function(serviceDef){ return {'label' : serviceDef.get('name').toUpperCase(), 'value' : serviceDef.get('id')}; })
 			var serverAttrName = [{text : 'Start Date',label :'startDate'},{text : 'End Date',label :'endDate'},
 			                      {text : 'User',label :'requestUser'},{text : 'Resource Name',label :'resourcePath'},
@@ -601,6 +616,51 @@ define(function(require) {
                                 })
                         });
 		},
+        addSearchForUserSyncTab : function(){
+            var that = this , query = '';
+            var searchOpt = [localization.tt("lbl.userName"), localization.tt("lbl.syncSource"), localization.tt("lbl.startDate"), localization.tt("lbl.endDate")];
+            var serverAttrName  = [{text : localization.tt("lbl.userName"), label :"userName"},{text : localization.tt("lbl.syncSource"), label :"syncSource"},
+                                   {text : 'Start Date',label :'startDate'},{text : 'End Date',label :'endDate'}];
+            if(_.isEmpty(App.vsHistory.userSync)){
+                query = '"Start Date": "'+Globalize.format(new Date(),"MM/dd/yyyy")+'"';
+                App.vsHistory.userSync.push(new Backbone.Model({'category':'Start Date', value:Globalize.format(new Date(),"MM/dd/yyyy")}));
+            }else{
+                _.map(App.vsHistory.userSync, function(a){ query += '"'+a.get('category')+'":"'+a.get('value')+'"'; });
+            }
+            var pluginAttr = {
+                placeholder    : localization.tt('msg.searchForUserSync'),
+                container         : this.ui.visualSearch,
+                query             : query,
+                type		   : 'userSync',
+                callbacks :  {
+                    valueMatches :function(facet, searchTerm, callback) {
+                        switch (facet) {
+                            case 'Sync Source':
+                                    callback( _.map(XAEnums.UserSyncSource, function(obj){ return obj.label; }) );
+                                    break;
+                            case 'Start Date' :
+                                    var endDate, models = that.visualSearch.searchQuery.where({category:"End Date"});
+                                    if(models.length > 0){
+                                        var tmpmodel = models[0];
+                                        endDate = tmpmodel.attributes.value;
+                                    }
+                                    XAUtils.displayDatepicker(that.ui.visualSearch, facet, endDate, callback);
+                                    break;
+                            case 'End Date' :
+                                    var startDate, models = that.visualSearch.searchQuery.where({category:"Start Date"});
+                                    if(models.length > 0){
+                                        var tmpmodel = models[0];
+                                        startDate = tmpmodel.attributes.value;
+                                    }
+                                    XAUtils.displayDatepicker(that.ui.visualSearch, facet, startDate, callback);
+                                    break;
+                        }
+                    }
+                }
+            }
+            this.visualSearch = XAUtils.addVisualSearch(searchOpt, serverAttrName, this.userSyncAuditList, pluginAttr);
+            this.setEventsToFacets(this.visualSearch, App.vsHistory.userSync);
+        },
 		renderAdminTable : function(){
 			var that = this , self = this;
 			
@@ -1299,7 +1359,7 @@ define(function(require) {
 			};
 			return this.policyExportAuditList.constructor.getTableCols(cols, this.policyExportAuditList);
 		},
-                renderPluginInfoTable : function(){
+        renderPluginInfoTable : function(){
 			this.ui.tableList.removeClass("clickable");
 			this.rTableList.show(new XATableLayout({
 				columns: this.getPluginInfoColums(),
@@ -1472,9 +1532,87 @@ define(function(require) {
 			return this.pluginInfoList.constructor.getTableCols(cols, this.pluginInfoList);
 	
 		},
-                isDateDifferenceMoreThanHr : function(date1, date2){
-                        var diff = Math.abs(date1 - date2) / 36e5;
-                        return parseInt(diff) >= 1 ? true : false;
+        renderUserSyncTable : function(){
+            this.$el.addClass("user-sync-table");
+            this.ui.tableList.removeClass("clickable");
+            this.rTableList.show(new XATableLayout({
+                columns: this.getUserSyncColums(),
+                collection: this.userSyncAuditList,
+                includeFilter : false,
+                gridOpts : {
+                    row : Backgrid.Row.extend({}),
+                    header : XABackgrid,
+                    emptyText : 'No plugin found!'
+                }
+            }));
+        },
+        getUserSyncColums : function(){
+            var cols ={
+                userName : {
+                    cell 	: 'string',
+                    label	: localization.tt("lbl.userName"),
+                    editable:false,
+                    sortable:false,
+                },
+                syncSource : {
+                    cell 	: 'html',
+                    label	: localization.tt("lbl.syncSource"),
+                    editable:false,
+                    sortable:false,
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function (rawValue, model) {
+                            var label = rawValue == "Unix" ? 'success' : (rawValue == "File" ? 'info' : 'yellow');
+                            return '<center><label class="label label-'+label+'">'+_.escape(rawValue)+'</label></center>';
+                        }
+                    }),
+                },
+                noOfUsers : {
+                    cell 	: 'string',
+                    label	: localization.tt("lbl.noOfUsers"),
+                    editable:false,
+                    sortable:false,
+                },
+                noOfGroups : {
+                    cell 	: 'string',
+                    label	: localization.tt("lbl.noOfGroups"),
+                    editable:false,
+                    sortable:false,
+                },
+                eventTime : {
+                    label : 'Event Time',
+                    cell: "String",
+                    click : false,
+                    drag : false,
+                    editable:false,
+                    sortType: 'toggle',
+                    direction: 'descending',
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function (rawValue, model) {
+                            return Globalize.format(new Date(rawValue),  "MM/dd/yyyy hh:mm:ss tt");
+                        }
+                    })
+                },
+                syncSourceDetail : {
+                    cell    : 'html',
+                    label : localization.tt("h.syncDetails"),
+                    editable:false,
+                    sortable:false,
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function (rawValue, model) {
+                            return('<button data-id="syncDetailes" title="Sync Details" id="'+ model.get('id') +'" ><i class="icon-eye-open"> </i></button>');
+                        }
+                    }),
+                }
+            }
+            return this.userSyncAuditList.constructor.getTableCols(cols, this.userSyncAuditList);
+
+        },
+        onSyncDetailes : function(e){
+            XAViewUtils.syncSourceDetail(e , this);
+        },
+        isDateDifferenceMoreThanHr : function(date1, date2){
+                var diff = Math.abs(date1 - date2) / 36e5;
+                return parseInt(diff) >= 1 ? true : false;
 		},
 		onRefresh : function(){
 			var that =this, coll,params = {};
@@ -1498,6 +1636,9 @@ define(function(require) {
 			case "#pluginStatus":
 				coll = this.pluginInfoList;
 				break;
+                        case "#userSync":
+                                coll = this.userSyncAuditList;
+                                break;
 			}
 			coll.fetch({
 				reset : true,
@@ -1544,6 +1685,9 @@ define(function(require) {
 				case "#pluginStatus":
 					this.collection = this.pluginInfoList;
 					break;
+                                case "#userSync":
+                                        this.collection = this.userSyncAuditList;
+                                        break;
 			}
 		},
 		clearVisualSearch : function(collection, serverAttrNameList) {

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/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 1f04aa2..4ba75fb 100644
--- a/security-admin/src/main/webapp/styles/xa.css
+++ b/security-admin/src/main/webapp/styles/xa.css
@@ -2291,3 +2291,9 @@ textarea:read-only{
   cursor: pointer;
   margin-left: 4px;
 }
+.user-sync-table td{
+  text-align: center !important;
+}
+.white-space-normal{
+  white-space: normal !important;
+}

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/templates/kms/KmsKeyCreate_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/kms/KmsKeyCreate_tmpl.html b/security-admin/src/main/webapp/templates/kms/KmsKeyCreate_tmpl.html
index b4b7f03..1dd8ae8 100644
--- a/security-admin/src/main/webapp/templates/kms/KmsKeyCreate_tmpl.html
+++ b/security-admin/src/main/webapp/templates/kms/KmsKeyCreate_tmpl.html
@@ -17,7 +17,7 @@
 <h4 class="wrap-header bold"> Key Detail </h4>
 <div class="wrap non-collapsible ">
 	<div data-id="r_form"></div>
-        <div class="form-actions form-policy row-fluid">
+        <div class="form-actions form-policy">
 		<button type="button" data-id="save" class="btn btn-primary">
 			Save
 		</button>

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/templates/policies/RangerPolicyCreate_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/policies/RangerPolicyCreate_tmpl.html b/security-admin/src/main/webapp/templates/policies/RangerPolicyCreate_tmpl.html
index eb844ff..78a56c6 100644
--- a/security-admin/src/main/webapp/templates/policies/RangerPolicyCreate_tmpl.html
+++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyCreate_tmpl.html
@@ -29,7 +29,7 @@
           <i class="icon-info-sign searchInfoUserAccess padding-right-10"></i>{{{infoMsg}}}
         </div>
 	<div data-id="r_form"></div>
-        <div class="form-actions form-policy row-fluid">
+        <div class="form-actions form-policy">
 	{{#if editPolicy}}
 		<button type="submit" data-id="save" class="btn  btn-spinner btn-primary">
 			<span>Save</span>

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/templates/reports/AuditLayout_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/reports/AuditLayout_tmpl.html b/security-admin/src/main/webapp/templates/reports/AuditLayout_tmpl.html
index b977d3d..7d9a34a 100644
--- a/security-admin/src/main/webapp/templates/reports/AuditLayout_tmpl.html
+++ b/security-admin/src/main/webapp/templates/reports/AuditLayout_tmpl.html
@@ -15,6 +15,9 @@
   limitations under the License.
 --}}
 <ul class="nav nav-tabs tabs clearfix">
+   <li data-js="userSync">
+     <a data-toggle="tab" href="#userSync">{{tt 'h.userSync'}}</a>
+   </li>
    <li data-js="pluginStatus">
      <a data-toggle="tab" href="#pluginStatus">{{tt 'h.pluginStatus'}}</a> 
    </li> 

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/templates/reports/UserSyncInfo_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/reports/UserSyncInfo_tmpl.html b/security-admin/src/main/webapp/templates/reports/UserSyncInfo_tmpl.html
new file mode 100644
index 0000000..8439fc2
--- /dev/null
+++ b/security-admin/src/main/webapp/templates/reports/UserSyncInfo_tmpl.html
@@ -0,0 +1,34 @@
+{{!--
+  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>
+        <table class="table table-bordered table-condensed backgrid">
+                <thead>
+                        <tr>
+                                <th class="renderable loginId">Name</th>
+                                <th class="renderable loginId">Value</th>
+                        </tr>
+                </thead>
+                <tbody>
+                        {{#each syncSourceInfo}}
+                                <tr>
+                                        <td class="string-cell renderable" >{{tt label}}</td>
+                                        <td class="string-cell renderable white-space-normal" title={{value}} >{{value}}</td>
+                                </tr>
+                        {{/each}}
+                </tbody>
+        </table>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/templates/service/ServiceCreate_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/service/ServiceCreate_tmpl.html b/security-admin/src/main/webapp/templates/service/ServiceCreate_tmpl.html
index 7464f83..dff0b66 100644
--- a/security-admin/src/main/webapp/templates/service/ServiceCreate_tmpl.html
+++ b/security-admin/src/main/webapp/templates/service/ServiceCreate_tmpl.html
@@ -21,7 +21,7 @@
 {{/if}}
 <div class="wrap non-collapsible ">
 	<div data-id="r_form"></div>
-        <div class="form-actions form-asset row-fluid">
+        <div class="form-actions form-asset">
 		<button type="submit" data-id="save" class="btn btn-primary">
 			Save
 		</button>

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/templates/users/GroupCreate_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/users/GroupCreate_tmpl.html b/security-admin/src/main/webapp/templates/users/GroupCreate_tmpl.html
index ffc29bf..26833b4 100644
--- a/security-admin/src/main/webapp/templates/users/GroupCreate_tmpl.html
+++ b/security-admin/src/main/webapp/templates/users/GroupCreate_tmpl.html
@@ -17,7 +17,7 @@
 <h4 class="wrap-header bold"> Group Detail </h4>
 <div class="wrap non-collapsible ">
 	<div data-id="r_form"></div>
-        <div class="form-actions form-policy row-fluid">
+        <div class="form-actions form-policy">
 		<button type="button" data-id="save" class="btn btn-primary">
 			Save
 		</button>

http://git-wip-us.apache.org/repos/asf/ranger/blob/8888b628/security-admin/src/main/webapp/templates/users/UserCreate_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/users/UserCreate_tmpl.html b/security-admin/src/main/webapp/templates/users/UserCreate_tmpl.html
index 13ce8cc..b11cc36 100644
--- a/security-admin/src/main/webapp/templates/users/UserCreate_tmpl.html
+++ b/security-admin/src/main/webapp/templates/users/UserCreate_tmpl.html
@@ -26,7 +26,7 @@
 		</li>
 	</ul>
 	<div data-id="r_form"></div>
-        <div class="form-actions form-policy row-fluid">
+        <div class="form-actions form-policy">
 		<button type="button" data-id="save" class="btn btn-primary">
 			Save
 		</button>