You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/01/07 20:32:21 UTC

[22/27] incubator-ranger git commit: Ranger-203 : Add pluggable logic to UI code

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9d85cb76/security-admin/src/main/webapp/scripts/views/policies/GroupPermList.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/policies/GroupPermList.js b/security-admin/src/main/webapp/scripts/views/policies/GroupPermList.js
new file mode 100644
index 0000000..c7e876a
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policies/GroupPermList.js
@@ -0,0 +1,429 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ /*
+ *
+ */
+define(function(require) {
+    'use strict';
+    
+	var Backbone		= require('backbone');
+    var App		        = require('App');
+	var XAEnums			= require('utils/XAEnums');
+	var XAUtil			= require('utils/XAUtils');
+	var localization	= require('utils/XALangSupport');
+	var VXGroup			= require('models/VXGroup');
+	require('bootstrap-editable');
+    	
+	var FormInputItem = Backbone.Marionette.ItemView.extend({
+		_msvName : 'FormInputItem',
+		template : require('hbs!tmpl/policies/GroupPermItem'),
+		tagName : 'tr',
+		templateHelpers : function(){
+			
+			
+			return {
+				permissions 	: this.getPerms(),
+				policyKnox 		: this.policyType == XAEnums.ServiceType.Service_KNOX.value ? true :false,
+//				policyStorm 	: this.policyType == XAEnums.ServiceType.Service_STORM.value ? true :false,
+				isModelNew		: !this.model.has('editMode'),
+				stormPerms		: this.stormPermsIds.length == 14 ? _.union(this.stormPermsIds,[-1]) : this.stormPermsIds  
+						
+			};
+		},
+		ui : {
+			selectGroups	: '[data-js="selectGroups"]',
+			inputIPAddress	: '[data-js="ipAddress"]',
+			tags			: '[class=tags]'
+		},
+		events : {
+			'click [data-action="delete"]'	: 'evDelete',
+			'click td'						: 'evClickTD',
+			'change [data-js="selectGroups"]': 'evSelectGroup',
+			'change [data-js="ipAddress"]'	: 'evIPAddress'
+		},
+
+		initialize : function(options) {
+			_.extend(this, _.pick(options, 'groupList','policyType','accessTypes'));
+            //this.subjectList = this.mStudent.getSubjectList();
+			this.stormPermsIds = [];
+			if(this.policyType == XAEnums.AssetType.ASSET_STORM.value){
+				if(this.model.has('editMode') && this.model.get('editMode')){
+					this.stormPermsIds = _.map(this.model.get('_vPermList'), function(p){
+											if(XAEnums.XAPermType.XA_PERM_TYPE_ADMIN.value != p.permType)
+												return p.permType;
+										});
+				}
+			}
+		},
+ 
+		onRender : function() {
+			var that = this;
+			if(!_.isUndefined(this.model.get('groupName'))){
+				this.ui.selectGroups.val(this.model.get('groupName').split(','));
+			}
+			if(!_.isUndefined(this.model.get('ipAddress'))){
+				this.ui.inputIPAddress.val(this.model.get('ipAddress').toString());
+			}
+			if(this.model.has('editMode') && this.model.get('editMode')){
+				_.each(this.model.get('accesses'), function(p){
+					if(p.value)
+						this.$el.find('input[data-name="' + p.type + '"]').attr('checked', 'checked');
+				},this);
+			}
+			this.createGroupDropDown();
+			this.groupDropDownChange();
+			if(this.policyType == XAEnums.AssetType.ASSET_STORM.value){
+				this.renderStormPerms();
+			}
+			
+			
+			this.accessItems = _.map(this.getPerms(), function(perm){ return {'type':perm.label,value : false}});
+		},
+		groupDropDownChange : function(){
+			var that = this;
+			this.ui.selectGroups.on('change',function(e){
+		//		console.log(e.currentTarget.value);
+				that.checkDirtyFieldForDropDown(e);
+				var duplicateGroupName = false;
+				
+				that.toggleAddButton(e);
+				if(e.removed != undefined){
+					var gIdArr = [],gNameArr = [];
+					gIdArr = _.without(that.model.get('groupId').split(','), e.removed.id);
+					if(that.model.get('groupName') != undefined)
+						gNameArr = _.without(that.model.get('groupName').split(','), e.removed.text);
+					if(!_.isEmpty(gIdArr)){
+						that.model.set('groupId',gIdArr.join(','));
+						that.model.set('groupName',gNameArr.join(','));
+					}else{
+						that.model.unset('groupId');
+						that.model.unset('groupName');
+					}
+					return;
+				}
+				if(!_.isUndefined(e.added)){
+						that.model.set('groupId', e.currentTarget.value);
+						var groupNameList = _.map($(e.currentTarget).select2("data"), function(obj){return obj.text});
+						that.model.set('groupName',groupNameList.toString())
+				}
+			});
+		},
+		createGroupDropDown :function(){
+			var that = this;
+			if(this.model.has('editMode') && !_.isEmpty(this.ui.selectGroups.val())){
+				var temp = this.ui.selectGroups.val().split(",");
+				_.each(temp , function(name){
+					if(_.isUndefined(that.groupList.where({ name : name}))){
+						var group = new VXGroup({name: name});
+						group.fetch({async:false}).done(function(){
+							that.groupList.add(group);
+						});
+					}
+				});
+			}
+			this.groupArr = this.groupList.map(function(m){
+				return { id : m.id+"" , text : m.get('name')};
+			});
+			this.ui.selectGroups.select2({
+				closeOnSelect : true,
+				placeholder : 'Select Group',
+			//	maximumSelectionSize : 1,
+				width :'220px',
+				tokenSeparators: [",", " "],
+				tags : this.groupArr, 
+				initSelection : function (element, callback) {
+					var data = [];
+					console.log(that.groupList);
+					
+					$(element.val().split(",")).each(function () {
+						var obj = _.findWhere(that.groupArr,{text:this});
+						data.push({id: obj.id, text: this})
+					});
+					callback(data);
+				},
+				createSearchChoice: function(term, data) {
+				/*	if ($(data).filter(function() {
+						return this.text.localeCompare(term) === 0;
+					}).length === 0) {
+						return {
+							id : term,
+							text: term
+						};
+					}*/
+				},
+				ajax: { 
+					url: "service/xusers/groups",
+					dataType: 'json',
+					data: function (term, page) {
+						return {name : term};
+					},
+					results: function (data, page) { 
+						var results = [] , selectedVals = [];
+						/*if(!_.isEmpty(that.ui.selectGroups.select2('val')))
+							selectedVals = that.ui.selectGroups.select2('val');*/
+						selectedVals = that.getGroupSelectdValues();
+						if(data.resultSize != "0"){
+							//if(data.vXGroups.length > 1){
+
+								results = data.vXGroups.map(function(m, i){	return {id : m.id+"", text: m.name};	});
+								if(!_.isEmpty(selectedVals))
+									results = XAUtil.filterResultByIds(results, selectedVals);
+						//		console.log(results.length);
+								return {results : results};
+							//}
+						//	results = [{id : data.vXGroups.id+"", text: data.vXGroups.name}];
+						//	return {results : results};
+						}
+						return {results : results};
+					}
+				},	
+				formatResult : function(result){
+					return result.text;
+				},
+				formatSelection : function(result){
+					return result.text;
+				},
+				formatNoMatches: function(result){
+					return 'No group found.';
+				}
+			}).on('select2-focus', XAUtil.select2Focus);
+		},
+		getGroupSelectdValues : function(){
+			var vals = [],selectedVals = [];
+			this.collection.each(function(m){
+				if(!_.isUndefined(m.get('groupId'))){
+					vals.push.apply(vals, m.get('groupId').split(','));
+				}
+			});
+			if(!_.isEmpty(this.ui.selectGroups.select2('val')))
+				selectedVals = this.ui.selectGroups.select2('val');
+			vals.push.apply(vals , selectedVals);
+			vals = $.unique(vals);
+			return vals;
+		},
+		evDelete : function(){
+			var that = this;
+			this.collection.remove(this.model);
+			this.toggleAddButton();
+		},
+		evClickTD : function(e){
+			var that = this;
+			var $el = $(e.currentTarget),permList =[],perms =[];
+			if($(e.toElement).is('td')){
+				var $checkbox = $el.find('input');
+				$checkbox.is(':checked') ? $checkbox.prop('checked',false) : $checkbox.prop('checked',true);
+			}
+			var curPerm = $el.find('input').data('id');
+			var curPermName = $el.find('input').data('name');
+			if(!_.isUndefined(curPerm)){
+				var perms = [];
+				if(this.model.has('accesses')){
+					if(_.isArray(this.model.get('accesses')))
+						perms = this.model.get('accesses');
+					else
+						perms.push(this.model.get('accesses'));
+				}
+				if($el.find('input[type="checkbox"]').is(':checked')){
+					_.each(that.accessItems, function(obj){ if(obj.type == curPermName) obj.value = true });
+					
+					if(curPerm == XAEnums.XAPermType.XA_PERM_TYPE_ADMIN.value){
+						$el.parent().find('input[type="checkbox"]:not(:checked)[data-id!="'+curPerm+'"]').map(function(){
+							_.each(that.accessItems, function(obj){ if(obj.type == $(this).data('name')) obj.value = true }, this);
+						});
+						$el.parent().find('input[type="checkbox"]').prop('checked',true);
+					}
+				} else {
+					_.each(that.accessItems, function(obj){ if(obj.type == curPermName ) obj.value = false }, this);
+				}
+				
+//				this.checkDirtyFieldForCheckBox(perms);
+				if(!_.isEmpty(that.accessItems))
+					this.model.set('accesses', that.accessItems);
+				else 
+					this.model.unset('accesses');
+			}
+		},
+		checkDirtyFieldForCheckBox : function(perms){
+			var permList = [];
+			if(!_.isUndefined(this.model.get('_vPermList')))
+				permList = _.map(this.model.attributes._vPermList,function(obj){return obj.permType;});
+			perms = _.map(perms,function(obj){return obj.permType;});
+			XAUtil.checkDirtyField(permList, perms, this.$el);
+		},
+		toggleAddButton : function(e){
+			var temp = [];
+			this.collection.each(function(m){
+				if(!_.isUndefined(m.get('groupId'))){
+					temp.push.apply(temp, m.get('groupId').split(','));
+					
+				}
+			});
+			if(!_.isUndefined(e)){
+				if( !_.isUndefined(e.added) && ((temp.length + 1) == this.groupList.length)) 
+					$('[data-action="addGroup"]').hide();
+				if(!_.isUndefined(e.removed))
+					$('[data-action="addGroup"]').show();
+			}else{
+				$('[data-action="addGroup"]').show();
+			}
+		},
+		evIPAddress :function(e){
+			if(!_.isEmpty($(e.currentTarget).val()))
+				this.model.set('ipAddress',$(e.currentTarget).val().split(','));
+			else
+				this.model.unset('ipAddress');
+		},
+		renderStormPerms :function(){
+			var that = this;
+			var permArr = _.pick(XAEnums.XAPermType,  XAUtil.getStormActions(this.policyType));
+			this.stormPerms =  _.map(permArr,function(m){return {text:m.label, value:m.value};});
+			this.stormPerms.push({'value' : -1, 'text' : 'Select/Deselect All'});
+			this.ui.tags.editable({
+			    placement: 'right',
+//			    emptytext : 'Please select',
+			    source: this.stormPerms,
+			    display: function(idList,srcData) {
+			    	if(_.isEmpty(idList.toString())){
+			    		$(this).html('');
+			    		return;
+			    	}
+			    	if(!_.isArray(idList))
+			    		idList = [idList];
+//			    	that.checkDirtyFieldForGroup(values);
+			    	var permTypeArr = [];
+		    		var valArr = _.map(idList, function(id){
+		    			if(!(parseInt(id) <= 0) && (!_.isNaN(parseInt(id)))){
+		    				var obj = _.findWhere(srcData,{'value' : parseInt(id)});
+		    				permTypeArr.push({permType : obj.value});
+		    				return "<span class='label label-inverse'>" + obj.text + "</span>";
+		    			}
+		    		});
+		    		
+		    		if(that.model.has('_vPermList')){
+                        var adminPerm = _.where(that.model.get('_vPermList'),{'permType': XAEnums.XAPermType.XA_PERM_TYPE_ADMIN.value });
+                        permTypeArr = _.isEmpty(adminPerm) ? permTypeArr : _.union(permTypeArr,adminPerm);
+                    }
+                    that.model.set('_vPermList', permTypeArr);
+//		    		if(!_.isEmpty(perms))
+//		    			that.model.set('_vPermList', perms);
+//		    		that.model.set('_vPermList', permTypeArr);
+		    		$(this).html(valArr.join(" "));
+			    },
+			});
+			this.$('[id^="tags-edit-"]').click(function(e) {
+			    e.stopPropagation();
+			    e.preventDefault();
+			    that.$('#' + $(this).data('editable') ).editable('toggle');
+			    that.$('input[type="checkbox"][value="-1"]').click(function(e){
+					var checkboxlist =$(this).closest('.editable-checklist').find('input[type="checkbox"][value!=-1]')
+					$(this).is(':checked') ? checkboxlist.prop('checked',true) : checkboxlist.prop('checked',false); 
+					
+				});
+			});
+			
+		},
+		checkDirtyFieldForDropDown : function(e){
+			//that.model.has('groupId')
+			var groupIdList =[];
+			if(!_.isUndefined(this.model.get('groupId')))
+				groupIdList = this.model.get('groupId').split(',');
+			XAUtil.checkDirtyField(groupIdList, e.val, $(e.currentTarget));
+		},
+		getPerms : function(){
+			var permList = _.map(this.accessTypes,function(type){ return type.label});
+			return _.map(permList, function(perm){ return _.findWhere(XAEnums.XAPermType,{label:perm})})
+		}
+	});
+
+
+
+	return Backbone.Marionette.CompositeView.extend({
+		_msvName : 'FormInputItemList',
+		template : require('hbs!tmpl/policies/GroupPermList'),
+		//tagName : 'ul', 
+		//className : 'timeline-container',
+		templateHelpers :function(){
+			return {
+				permHeaders : this.getPermHeaders()
+			};
+		},
+		getItemView : function(item){
+			if(!item){
+				return;
+			}
+			return FormInputItem;
+		},
+		itemViewContainer : ".js-formInput",
+		itemViewOptions : function() {
+			return {
+				'collection' 	: this.collection,
+				'groupList' 	: this.groupList,
+				'policyType'	: this.policyType,
+				'accessTypes'	: this.accessTypes
+			};
+		},
+		events : {
+			'click [data-action="addGroup"]' : 'addNew'
+		},
+		initialize : function(options) {
+			_.extend(this, _.pick(options, 'groupList','policyType','accessTypes','rangerServiceDefModel'));
+			//this.hiveGroupPerm = _.has(options,'hiveGroupPerm') ? true : false;
+			this.listenTo(this.groupList, 'sync', this.render, this);
+			if(this.collection.length == 0)
+				this.collection.add(new Backbone.Model());
+		},
+		onRender : function(){
+			//console.log("onRender of ArtifactFormNoteList called");
+			this.toggleAddButton();
+		},
+		addNew : function(){
+			var that =this;
+			if(this.groupList.length > this.collection.length){
+				this.collection.add(new Backbone.Model());
+				this.toggleAddButton();
+			}
+		},
+		toggleAddButton : function(){
+			var groupIds=[];
+			this.collection.each(function(m){
+				if(!_.isUndefined(m.get('groupId'))){
+					var temp = m.get('groupId').split(',');
+					groupIds.push.apply(groupIds,temp);
+				}
+			});
+			if(groupIds.length == this.groupList.length)
+				this.$('button[data-action="addGroup"]').hide();
+			else
+				this.$('button[data-action="addGroup"]').show();
+		},
+		getPermHeaders : function(){
+			var permList = _.map(this.accessTypes,function(type){ return type.label});
+			if(!_.isEmpty(this.rangerServiceDefModel.get('policyConditions'))){
+				_.each(this.rangerServiceDefModel.get('policyConditions'), function(cond){
+					if(!_.isNull(cond) && !_.isNull(cond.label)) permList.unshift(cond.label);
+				});
+			}
+			permList.unshift(localization.tt('lbl.selectGroup'));
+			permList.push("");
+			return permList;
+		},
+	});
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9d85cb76/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
new file mode 100644
index 0000000..15ddd8e
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
@@ -0,0 +1,322 @@
+/*
+ * 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.
+ */
+
+ 
+/* 
+ * Policy create view
+ */
+
+define(function(require){
+    'use strict';
+
+	var Backbone		= require('backbone');
+	var App				= require('App');
+	var XAEnums			= require('utils/XAEnums');
+	var XAUtil			= require('utils/XAUtils');
+	var XALinks 		= require('modules/XALinks');
+	var localization	= require('utils/XALangSupport');
+	
+	var PolicycreateTmpl = require('hbs!tmpl/hdfs/PolicyCreate_tmpl');
+	var RangerPolicyForm = require('views/policies/RangerPolicyForm');
+	var RangerServiceDef	= require('models/RangerServiceDef');
+
+	var PolicyCreate = Backbone.Marionette.Layout.extend(
+	/** @lends PolicyCreate */
+	{
+		_viewName : 'PolicyCreate',
+		
+    	template: PolicycreateTmpl,
+    	templateHelpers : function(){
+    		return {
+    			editPolicy : this.editPolicy
+    		};
+    	},
+    	breadCrumbs :function(){
+	    	
+    		if(this.model.isNew())
+    			return [XALinks.get('RepositoryManager'),XALinks.get('ManagePolicies',{model : this.rangerService}),XALinks.get('PolicyCreate')];
+    		else
+    			return [XALinks.get('RepositoryManager'),XALinks.get('ManagePolicies',{model : this.rangerService}),XALinks.get('PolicyEdit')];
+//    		return [];
+    	} ,        
+
+		/** Layout sub regions */
+    	regions: {
+			'rForm' :'div[data-id="r_form"]'
+		},
+
+    	/** ui selector cache */
+    	ui: {
+			'btnSave'	: '[data-id="save"]',
+			'btnCancel' : '[data-id="cancel"]',
+			'btnDelete' : '[data-id="delete"]',
+			'policyDisabledAlert' : '[data-id="policyDisabledAlert"]' 
+		},
+
+		/** ui events hash */
+		events: function() {
+			var events = {};
+			events['click ' + this.ui.btnSave]		= 'onSave';
+			events['click ' + this.ui.btnCancel]	= 'onCancel';
+//			events['click ' + this.ui.btnDelete]	= 'onDelete';
+			
+			return events;
+		},
+
+    	/**
+		* intialize a new PolicyCreate Layout 
+		* @constructs
+		*/
+		initialize: function(options) {
+			var that = this;
+			console.log("initialized a PolicyCreate Layout");
+
+			_.extend(this, _.pick(options, 'rangerService'));
+			this.initializeServiceDef();
+			that.form = new RangerPolicyForm({
+				template : require('hbs!tmpl/policies/RangerPolicyForm_tmpl'),
+				model : this.model,
+				rangerServiceDefModel : this.rangerServiceDefModel,
+				rangerService : this.rangerService
+			});
+
+			this.editPolicy = this.model.has('id') ? true : false;
+			this.bindEvents();
+			this.params = {};
+		},
+		initializeServiceDef : function(){
+			var service = _.find(XAEnums.ServiceType,function(service){
+				return service.label.toUpperCase() == this.rangerService.get('type').toUpperCase();
+			},this);
+			this.rangerServiceDefModel	= new RangerServiceDef({ id : service.value });
+			this.rangerServiceDefModel.fetch({
+				cache : false,
+				async : false
+			})
+		},
+
+		/** all events binding here */
+		bindEvents : function(){
+			/*this.listenTo(this.model, "change:foo", this.modelChanged, this);*/
+			/*this.listenTo(communicator.vent,'someView:someEvent', this.someEventHandler, this)'*/
+		},
+
+		/** on render callback */
+		onRender: function() {
+//			XAUtil.showAlerForDisabledPolicy(this);
+			this.rForm.show(this.form);
+//			this.rForm.$el.dirtyFields();
+//			XAUtil.preventNavigation(localization.tt('dialogMsg.preventNavPolicyForm'),this.rForm.$el);
+//			this.initializePlugins();
+		},
+
+		/** all post render plugin initialization */
+		initializePlugins: function(){
+		},
+		popupCallBack : function(msg,validateObj){
+			var that = this;
+			XAUtil.alertPopup({
+				msg :msg,
+				callback : function(){
+				//	if(validateObj.auditLoggin)
+				//		that.savePolicy();
+				}
+			});
+		},
+		onSave: function(){
+			var that = this, valid = false;
+			var errors = this.form.commit({validate : false});
+			if(! _.isEmpty(errors)){
+				return;
+			}
+			this.savePolicy();
+			/*var validateObj = this.form.formValidation();
+			valid = (validateObj.groupSet && validateObj.permSet) || (validateObj.userSet && validateObj.userPerm);
+			if(!valid){
+				if(validateObj.groupSet && (!validateObj.permSet)){
+					this.popupCallBack(localization.tt('msg.addGroupPermission'),validateObj);
+				}else if((!validateObj.groupSet) && (validateObj.permSet)) {
+					this.popupCallBack(localization.tt('msg.addGroup'),validateObj);
+						
+				}else if(validateObj.userSet && (!validateObj.userPerm)){
+					this.popupCallBack(localization.tt('msg.addUserPermission'),validateObj);
+				}else if((!validateObj.userSet) && (validateObj.userPerm)) {
+					this.popupCallBack(localization.tt('msg.addUser'),validateObj);
+						
+				}else if((!validateObj.auditLoggin) && (!validateObj.groupPermSet)){
+					XAUtil.alertPopup({
+						msg :localization.tt('msg.yourAuditLogginIsOff'),
+						callback : function(){
+							if(!that.model.isNew()){
+								that.model.destroy({success: function(model, response) {
+									XAUtil.notifySuccess('Success', localization.tt('msg.policyDeleteMsg'));
+									App.appRouter.navigate("#!/hdfs/"+that.assetModel.id+"/policies",{trigger: true});
+								}});
+							}else{
+								XAUtil.notifyError('Error', localization.tt('msg.policyNotAddedMsg'));
+								App.appRouter.navigate("#!/hdfs/"+that.assetModel.id+"/policies",{trigger: true});
+							}
+						}
+					});
+				}else{
+					this.savePolicy();
+				}
+			}else{
+				if(validateObj.groupSet && (!validateObj.permSet)){
+					this.popupCallBack(localization.tt('msg.addGroupPermission'),validateObj);
+				}else if((!validateObj.groupSet) && (validateObj.permSet)) {
+					this.popupCallBack(localization.tt('msg.addGroup'),validateObj);
+						
+				}else if(validateObj.userSet && (!validateObj.userPerm)){
+					this.popupCallBack(localization.tt('msg.addUserPermission'),validateObj);
+				}else if((!validateObj.userSet) && (validateObj.userPerm)) {
+					this.popupCallBack(localization.tt('msg.addUser'),validateObj);
+						
+				}else
+					this.savePolicy();
+			}*/
+			
+		},
+		savePolicy : function(){
+			var that = this;
+			this.form.beforeSave();
+			this.saveMethod();
+		},
+		saveMethod : function(){
+			var that = this;
+			XAUtil.blockUI();
+			this.model.url = "service/plugins/policies";
+			this.model.save({},{
+				wait: true,
+				success: function () {
+					XAUtil.blockUI('unblock');
+					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});
+					
+					/*var view = require('views/hdfs/HDFSTableLayout');
+					var resourceListForAsset = new VXResourceList([],{
+						   queryParams : {
+							   'assetId' : that.assetModel.id 
+						   }
+					   });
+					resourceListForAsset.fetch({
+						cache : true,
+						'data' : {
+				//			'resourceType':XAEnums.AssetType.ASSET_HDFS.value,
+							'assetId' :that.assetModel.id
+						}
+					}).done(function(){
+						var newColl = resourceListForAsset;
+						resourceListForAsset.getLastPage({
+							cache : false,
+							data  : {
+			//					'resourceType' : XAEnums.AssetType.ASSET_HDFS.value,
+								'assetId' : that.assetModel.id
+							}
+						}).done(function(){
+							var model = newColl.get(that.model.id);
+							if(model){
+								model.trigger("model:highlightBackgridRow");
+							}
+						});
+						
+						App.rContent.show(new view({
+							collection : resourceListForAsset,
+							assetModel : that.assetModel
+						}));
+					});*/
+					
+					console.log("success");
+				},
+				error: function (model, response, options) {
+					    XAUtil.blockUI('unblock');
+					    if ( response && response.responseJSON && response.responseJSON.msgDesc){
+						if( response.responseJSON.messageList && response.responseJSON.messageList.length > 0 && !_.isUndefined(response.responseJSON.messageList[0].fieldName)){
+						    if(response.responseJSON.messageList[0].fieldName == "parentPermission"){
+							XAUtil.confirmPopup({
+							    msg :response.responseJSON.msgDesc,
+							    callback : function(){
+								that.model.set('checkParentPermission',XAEnums.BooleanValue.BOOL_FALSE.value);
+								that.saveMethod();
+							    }
+							});
+						    }else{
+							that.form.fields.name.setError(response.responseJSON.msgDesc);
+							XAUtil.scrollToField(that.form.fields.name.$el);
+							//XAUtil.notifyError('Error', response.responseJSON.msgDesc);
+						    }
+						}else{
+						    //that.form.fields.name.setError(response.responseJSON.msgDesc);
+						    //XAUtil.scrollToField(that.form.fields.name.$el);
+						    XAUtil.notifyError('Error', response.responseJSON.msgDesc);
+						}
+					    }else
+						XAUtil.notifyError('Error', 'Error creating Policy!');
+					    console.log("error");
+				}
+			});
+		},
+		onDelete :function(){
+			var that = this;
+			XAUtil.confirmPopup({
+				//msg :localize.tt('msg.confirmDelete'),
+				msg :'Are you sure want to delete ?',
+				callback : function(){
+					XAUtil.blockUI();
+					that.model.destroy({
+							success: function(model, response) {
+								XAUtil.blockUI('unblock');
+								XAUtil.allowNavigation();
+								XAUtil.notifySuccess('Success', localization.tt('msg.policyDeleteMsg'));
+								App.appRouter.navigate("#!/hdfs/"+that.assetModel.id+"/policies",{trigger: true});
+							},
+							error: function (model, response, options) {
+								XAUtil.blockUI('unblock');
+								if ( response && response.responseJSON && response.responseJSON.msgDesc){
+									    XAUtil.notifyError('Error', response.responseJSON.msgDesc);
+								    }else
+								    	XAUtil.notifyError('Error', 'Error deleting Policy!');
+								    console.log("error");
+							}
+					});
+					
+				}
+			});
+		},
+		onCancel : function(){
+			XAUtil.allowNavigation();
+			App.appRouter.navigate("#!/service/"+this.rangerService.id+"/policies",{trigger: true});
+
+		},
+		/** on close */
+		onClose: function(){
+			XAUtil.allowNavigation();
+		}
+
+	});
+
+	return PolicyCreate;
+});

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9d85cb76/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
new file mode 100644
index 0000000..8bb5061
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
@@ -0,0 +1,617 @@
+/*
+ * 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 localization	= require('utils/XALangSupport');
+	var XAUtil			= require('utils/XAUtils');
+    
+	var VXAuditMap		= require('models/VXAuditMap');
+	var VXPermMap		= require('models/VXPermMap');
+	var VXPermMapList	= require('collections/VXPermMapList');
+	var VXGroupList		= require('collections/VXGroupList');
+	var VXAuditMapList	= require('collections/VXAuditMapList');
+	var VXUserList		= require('collections/VXUserList');
+	var GroupPermList 	= require('views/policies/GroupPermList');
+	var UserPermList 	= require('views/policies/UserPermList');
+	var RangerPolicyResource		= require('models/RangerPolicyResource');
+	var RangerPolicyResourceList	= require('collections/RangerPolicyResourceList');
+
+	require('backbone-forms.list');
+	require('backbone-forms.templates');
+	require('backbone-forms');
+	require('backbone-forms.XAOverrides');
+	require('jquery-ui');
+	require('tag-it');
+
+	var PolicyForm = Backbone.Form.extend(
+	/** @lends PolicyForm */
+	{
+		_viewName : 'PolicyForm',
+
+    	/**
+		* intialize a new PolicyForm Form View 
+		* @constructs
+		*/
+		initialize: function(options) {
+			console.log("initialized a PolicyForm Form View");
+			_.extend(this, _.pick(options, 'rangerServiceDefModel', 'rangerService'));
+			this.setupForm()
+    		Backbone.Form.prototype.initialize.call(this, options);
+
+			this.initializeCollection();
+			this.bindEvents();
+		},
+		type : {
+			DATABASE : 1,
+			TABLE    : 2,
+			COLUMN   : 3,
+			VIEW   : 4,
+			UDF   : 5
+		},
+		initializeCollection: function(){
+			this.permMapList = this.model.isNew() ? new VXPermMapList() : this.model.get('permMapList');
+			this.auditList = this.model.isNew() ? new VXAuditMapList() : this.model.get('auditList');
+			
+			//this.userList.fetch();
+			
+
+			/*If the model passed to the fn is new return an empty collection
+			 * otherwise return a collection that has models like 
+			 * {
+			 * 	groupId : 5,
+			 * 	permissionList : [4,3]
+			 * }
+			 * The formInputList will be passed to the forminputitemlist view.
+			 */
+
+			this.formInputList 		= XAUtil.makeCollForGroupPermission(this.model);
+			this.userPermInputList  = XAUtil.makeCollForUserPermission(this.model);
+
+		},
+		/** all events binding here */
+		bindEvents : function(){
+			this.on('isAuditEnabled:change', function(form, fieldEditor){
+    			this.evAuditChange(form, fieldEditor);
+    		});
+			this.on('isRecursive:change', function(form, fieldEditor){
+    			this.evRecursiveChange(form, fieldEditor);
+    		});
+			this.on('resourceStatus:change', function(form, fieldEditor){
+    			this.evResourceStatusChange(form, fieldEditor);
+    		});
+		},
+
+		/** fields for the form
+		*/
+		fields: ['name', 'description', 'isEnabled', 'isAuditEnabled'],
+		schema :function(){
+			var attrs = {};
+			var that = this;
+			_.each(this.rangerServiceDefModel.get('resources'),function(v,k){ 
+				if (v != null) {
+
+					var formObj = {};
+					switch(v.type){
+							case 'string' : formObj.type = 'Text'; break;
+							case 'select2' : 
+								formObj.type = 'Select2Remote';
+								formObj.pluginAttr = that.getPlugginAttr(false),
+								formObj.editorAttrs = {'data-placeholder': v.label },
+								formObj.options = function(callback, editor){
+				                    callback();
+				                },
+				                formObj.onFocusOpen = true
+								break;
+							case 'path' : 
+								formObj.type = 'Text';
+								that.initilializePathPlugin = true;
+								that.pathFieldName = v.name;
+								break;
+							default : formObj.type = 'Text'; break;
+					}	
+
+					formObj.title = v.label || v.name;
+					formObj.validators = [];
+					if (_.has(v,'mandatory') && v.mandatory){
+						formObj.validators.push('required');
+						formObj.title = formObj.title +" *"
+					}
+					formObj['class'] = 'serviceConfig';
+					var name = v.name;
+					attrs[name] = formObj;
+				}
+			});
+			var attr1 = _.pick(_.result(this.model,'schemaBase'), 'name','isEnabled');
+			var attr2 = _.pick(_.result(this.model,'schemaBase'),'description', 'isRecursive', 'isAuditEnabled');
+			return _.extend(attr1,_.extend(attrs,attr2));
+		},
+		/** on render callback */
+		render: function(options) {
+			var that = this;
+			
+			Backbone.Form.prototype.render.call(this, options);
+
+			if(!_.isUndefined(this.initilializePathPlugin) && this.initilializePathPlugin){ 
+				this.initializePathPlugins();
+			}
+			this.renderCustomFields();
+		/*	if(!this.model.isNew()){
+				this.setUpSwitches();
+			}
+			if(this.model.isNew() && this.fields._vAuditListToggle.editor.getValue() == 1){
+				this.model.set('auditList', new VXAuditMapList(new VXAuditMap({
+					'auditType' : XAEnums.XAAuditType.XA_AUDIT_TYPE_ALL.value,//fieldEditor.getValue()//
+					'resourceId' :this.model.get('id')
+					
+				})));
+			}*/
+			this.$el.find('.field-isEnabled').find('.control-label').remove();
+		},
+		evAuditChange : function(form, fieldEditor){
+			XAUtil.checkDirtyFieldForToggle(fieldEditor);
+		},
+		evRecursiveChange : function(form, fieldEditor){
+			XAUtil.checkDirtyFieldForToggle(fieldEditor);
+		},
+		evResourceStatusChange : function(form, fieldEditor){
+			XAUtil.checkDirtyFieldForToggle(fieldEditor);
+		},
+		formValidation : function(){
+			var groupSet = false,permSet = false,auditStatus= false,encryptStatus= false,groupPermSet = false,
+							userSet=false,userPerm = false,isUsers =false;
+			console.log('validation called..');
+			var breakFlag =false;
+			this.formInputList.each(function(m){
+				if(m.has('groupId') ||  m.has('_vPermList')){
+					if(! breakFlag){
+						groupSet = m.has('groupId') ? true : false ; 
+						if(!m.has('_vPermList')){
+							permSet = false;
+						}else
+							permSet = true;
+						if(groupSet && permSet)
+							groupPermSet = true;
+						else
+							breakFlag=true;
+					}
+				}
+			});
+			breakFlag = false;
+			
+			this.userPermInputList.each(function(m){
+					if(! breakFlag){
+						userSet = m.has('userId') || m.has('userName') ? true : false ; 
+						if(!m.has('_vPermList')){
+							userPerm = false;
+						}else
+							userPerm = true;
+						if(userSet && userPerm)
+							isUsers = true;
+						else
+							breakFlag=true;
+					}
+			});
+			var auditLoggin = this.fields.isAuditEnabled.editor.getValue();
+
+			return {groupPermSet: groupPermSet , groupSet : groupSet,permSet : permSet,auditLoggin :auditLoggin,
+				userSet : userSet,userPerm:userPerm,isUsers:isUsers};
+		},
+		setupForm : function() {
+			var resourcePath = _.map(this.model.get('resources'), function(obj,i){
+				if( i == 0 ) this.model.set('isRecursive', obj.isRecursive) 
+				return obj.value; 
+			}, this);
+			if(this.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_HDFS.label.toUpperCase()){
+				this.model.set('path', resourcePath.toString());
+			}else if(this.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_HIVE.label.toUpperCase()){
+				_.each(resourcePath, function(path) {
+					var temp  = path.split("/");
+					if(!_.isUndefined(temp[1]))	this.model.set('database', temp[1])	
+					if(!_.isUndefined(temp[2]))	this.model.set('table', temp[2])
+					if(!_.isUndefined(temp[3]))	this.model.set('column', temp[3])
+					
+				},this);
+			}else if(this.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_HBASE.label.toUpperCase()){
+				_.each(resourcePath, function(path) {
+					var temp  = path.split("/");
+					if(!_.isUndefined(temp[1]))	this.model.set('table', temp[1])	
+					if(!_.isUndefined(temp[2]))	this.model.set('column-family', temp[2])
+					if(!_.isUndefined(temp[3]))	this.model.set('column', temp[3])
+					
+				},this);
+			}else if(this.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_KNOX.label.toUpperCase()){
+				_.each(resourcePath, function(path) {
+					var temp  = path.split("/");
+					if(!_.isUndefined(temp[1]))	this.model.set('topology', temp[1])	
+					if(!_.isUndefined(temp[2]))	this.model.set('service', temp[2])
+					
+				},this);
+			}else if(this.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_STORM.label.toUpperCase()){
+				var resourcePath = _.map(this.model.get('resources'), function(obj,i){
+					if( i == 0 ) this.model.set('isRecursive', obj.isRecursive) 
+					return obj.value; 
+				}, this);
+				_.each(resourcePath, function(path) {
+					var temp  = path.split("/");
+					if(!_.isUndefined(temp[1]))	this.model.set('topology', temp[1])	
+				},this);
+			}
+		},
+		setUpSwitches :function(){
+			var that = this;
+			var encryptStatus = false,auditStatus = false,recursiveStatus = false;
+			auditStatus = this.model.has('auditList') ? true : false; 
+			this.fields._vAuditListToggle.editor.setValue(auditStatus);
+			
+			_.each(_.toArray(XAEnums.BooleanValue),function(m){
+				if(parseInt(that.model.get('isEncrypt')) == m.value)
+					encryptStatus =  (m.label == XAEnums.BooleanValue.BOOL_TRUE.label) ? true : false;
+				if(parseInt(that.model.get('isRecursive')) == m.value)
+					recursiveStatus =  (m.label == XAEnums.BooleanValue.BOOL_TRUE.label) ? true : false;
+			});
+			this.fields.isEncrypt.editor.setValue(encryptStatus);
+			this.fields.isRecursive.editor.setValue(recursiveStatus);
+			if(parseInt(this.model.get('resourceStatus')) != XAEnums.BooleanValue.BOOL_TRUE.value)
+				this.fields.resourceStatus.editor.setValue(false);
+		},
+		/** all custom field rendering */
+		renderCustomFields: function(){
+			var that = this;
+			var accessType = this.rangerServiceDefModel.get('accessTypes').filter(function(val) { return val !== null; });
+			var policyType = this.rangerService.get('type')
+			_.each(XAEnums.ServiceType, function(obj){ 
+				if(that.rangerService.get('type').toUpperCase() == obj.label.toUpperCase())
+					policyType = obj.value;
+			});
+			this.groupList = new VXGroupList();
+			var params = {sortBy : 'name'};
+			this.groupList.setPageSize(100,{fetch:false});
+			this.groupList.fetch({
+					cache :true,
+					data : params
+				}).done(function(){
+					that.$('[data-customfields="groupPerms"]').html(new GroupPermList({
+						collection : that.formInputList,
+						groupList  : that.groupList,
+						model : that.model,
+						policyType 	: policyType,
+						accessTypes : accessType,
+						rangerServiceDefModel : that.rangerServiceDefModel
+					}).render().el);
+			});
+			
+			this.userList = new VXUserList();
+			var params = {sortBy : 'name'};
+			this.userList.setPageSize(100,{fetch:false});
+			this.userList.fetch({
+					cache :true,
+					data: params
+				}).done(function(){
+					that.$('[data-customfields="userPerms"]').html(new UserPermList({
+						collection : that.userPermInputList,
+						model : that.model,
+						userList : that.userList,
+						policyType 	: policyType,
+						accessTypes : accessType,
+						rangerServiceDefModel : that.rangerServiceDefModel
+					}).render().el);
+			});
+		},
+	
+		beforeSave : function(){
+			var that = this, resources = '';
+			this.model.set('service',this.rangerService.get('name'));
+			if(that.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_HDFS.label.toUpperCase())
+				resources = this.model.get('path').split(',');
+			else if(that.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_HIVE.label.toUpperCase()){
+				resources = "/"+this.model.get('database');
+				resources += !_.isEmpty(this.model.get('table')) ? "/"+this.model.get('table') : '';
+				resources += !_.isEmpty(this.model.get('column')) ? "/"+this.model.get('column') : '';
+				resources = resources.split(',');
+			}else if(that.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_HBASE.label.toUpperCase()){
+				resources = "/"+this.model.get('table');
+				resources += !_.isEmpty(this.model.get('column-family')) ? "/"+this.model.get('column-family') : '';
+				resources += !_.isEmpty(this.model.get('column')) ? "/"+this.model.get('column') : '';
+				resources = resources.split(',');
+			}else if(that.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_KNOX.label.toUpperCase()){
+				resources = "/"+this.model.get('topology')+"/"+this.model.get('service');
+				resources = resources.split(',');
+			}else if(that.rangerService.get('type').toUpperCase() == XAEnums.ServiceType.Service_STORM.label.toUpperCase()){
+				resources = "/"+this.model.get('topology')
+				resources = resources.split(',');
+			}
+			var rPolicyResourceList = new RangerPolicyResourceList();
+			_.each(resources, function(val){
+				var rPolicyResource = new RangerPolicyResource();
+				rPolicyResource.set('type',that.rangerService.get('type'));
+				rPolicyResource.set('value',val);
+				rPolicyResource.set('isRecursive',that.model.get('isRecursive'))
+				rPolicyResource.set('isExcludes',null)
+				rPolicyResourceList.add(rPolicyResource);
+			});
+			
+			
+			
+			
+//			this.model.set('isEnabled',this.model.get('isEnabled')+"");
+//			this.model.set('isAuditEnabled',this.model.get('isAuditEnabled')+"");
+			this.model.set('resources',rPolicyResourceList);
+			this.model.unset('isRecursive');
+			this.model.unset('path');
+			
+			//Set UserGroups Permission
+			
+			var RangerPolicyItem = Backbone.Collection.extend();
+			var policyItemList = new RangerPolicyItem();
+			this.formInputList.each(function(m){
+				if(!_.isUndefined(m.get('groupName'))){
+					var RangerPolicyItem=Backbone.Model.extend()
+					var policyItem = new RangerPolicyItem();
+					policyItem.set('groups',m.get('groupName').split(','))
+					
+					var RangerPolicyItemAccessList = Backbone.Collection.extend();
+					var rangerPlcItemAccessList = new RangerPolicyItemAccessList(m.get('accesses'));
+					policyItem.set('accesses', rangerPlcItemAccessList)
+					policyItemList.add(policyItem)
+					
+				}
+			}, this);
+			this.userPermInputList.each(function(m){
+				if(!_.isUndefined(m.get('userName'))){
+					var RangerPolicyItem=Backbone.Model.extend()
+					var policyItem = new RangerPolicyItem();
+					policyItem.set('users',m.get('userName').split(','))
+					
+					var RangerPolicyItemAccessList = Backbone.Collection.extend();
+					var rangerPlcItemAccessList = new RangerPolicyItemAccessList(m.get('accesses'));
+					policyItem.set('accesses', rangerPlcItemAccessList)
+					policyItemList.add(policyItem)
+					
+				}
+			}, this);
+			this.model.set('policyItems', policyItemList)
+			
+		},
+		/** all post render plugin initialization */
+		initializePathPlugins: function(){
+			var that= this;	
+			function split( val ) {
+				return val.split( /,\s*/ );
+			}
+			function extractLast( term ) {
+				return split( term ).pop();
+			}
+
+			this.fields[that.pathFieldName].editor.$el.bind( "keydown", function( event ) {
+				// don't navigate away from the field on tab when selecting an item
+				/*if ( event.keyCode === $.ui.keyCode.TAB && $( this ).data( "ui-autocomplete" ).menu.active ) {
+					event.preventDefault();
+				}
+				//TODO FIXME This is not working. We need a way so that when user enters  and presses ENTER
+				// the text box should contain /app/billing* . Currently the '*' is getting removed.
+				if ( event.keyCode === $.ui.keyCode.ENTER ) {
+					event.preventDefault();
+					event.stopPropagation();
+					$(this).tagit("createTag", "brand-new-tag");
+					//$(this).autocomplete('close');
+					//$(this).val($(this).val() + ', ');
+					
+				}*/
+			}).tagit({
+				autocomplete : {
+					cache: false,
+					source: function( request, response ) {
+						var p = $.getJSON( "service/assets/hdfs/resources", {
+							dataSourceName: that.rangerService.get('name'),
+							baseDirectory: extractLast( request.term )
+						}).done(function(data){
+							if(data.vXStrings){
+								response(data.vXStrings);
+							} else {
+								response();
+							}
+
+						}).error(function(){
+							response();
+
+						});
+						setTimeout(function(){ 
+							p.abort();
+							console.log('connection timeout for resource path request...!!');
+						}, 7000);
+					},
+					open : function(){
+						$(this).removeClass('working');
+					},
+					search: function() {
+						if(!_.isUndefined(this.value) && _.contains(this.value,',')){ 
+							_.each(this.value.split(',') , function(tag){
+								that.fields[that.pathFieldName].editor.$el.tagit("createTag", tag);
+							});
+				        	return false;
+				        }	
+						var term = extractLast( this.value );
+						$(this).addClass('working');
+						if ( term.length < 1 ) {
+							return false;
+						}
+					},
+					focus: function(event, ui) {
+						var terms = split( this.value );
+						terms.pop();
+						terms.push( ui.item.value );
+						this.value = terms.join( ", " );
+						return false;
+					},
+					select: function( event, ui ) {
+						var terms = split( this.value );
+						terms.pop();
+						terms.push( ui.item.value );
+						terms.push( "" );
+						this.value = terms.join( ", " );
+						return false;
+					}
+					
+				},
+				beforeTagAdded: function(event, ui) {
+			        // do something special
+					that.fields[that.pathFieldName].$el.removeClass('error');
+		        	that.fields[that.pathFieldName].$el.find('.help-inline').html('');
+					var tags =  [];
+			        console.log(ui.tag);
+				if(ui.tagLabel.lastIndexOf('/') < 0 || 
+			        		ui.tagLabel.lastIndexOf('/') == ui.tagLabel.length -1 && ui.tagLabel.lastIndexOf('/') != 0){
+			        	tags = ui.tagLabel.substr(0,ui.tagLabel.lastIndexOf('/'));
+			        	that.fields[that.pathFieldName].$el.addClass('error');
+			        	that.fields[that.pathFieldName].$el.find('.help-inline').html('Please enter valid resource path : ' + ui.tagLabel);
+			        	return false;
+			        }
+//			        this.value = tags;
+			        /*if(_.contains(ui.tagLabel,','))
+			        	tags = ui.tagLabel.split(',');
+			        	this.value = tags;*/
+					}
+			});
+			/*this.fields.name.editor.$el.tagit({
+				beforeTagAdded: function(event, ui) {
+		        // do something special
+				var tags =  [];
+		        console.log(ui.tag);
+		        if(_.contains(ui.tagLabel,','))
+		        	tags = ui.tagLabel.split(',');
+		        	this.value = tags;
+				}
+			});*/
+			
+		},
+		getPlugginAttr :function(autocomplete, searchType){
+			var that =this;
+			var type = searchType;
+			if(!autocomplete)
+				return{tags : true,width :'220px',multiple: true,minimumInputLength: 1};
+			else {
+				
+				
+				return {
+					closeOnSelect : true,
+					//placeholder : 'Select User',
+					tags:true,
+					multiple: true,
+					minimumInputLength: 1,
+					width :'220px',
+					tokenSeparators: [",", " "],
+					initSelection : function (element, callback) {
+						var data = [];
+						$(element.val().split(",")).each(function () {
+							data.push({id: this, text: this});
+						});
+						callback(data);
+					},
+					createSearchChoice: function(term, data) {
+						if ($(data).filter(function() {
+							return this.text.localeCompare(term) === 0;
+						}).length === 0) {
+							return {
+								id : term,
+								text: term
+							};
+						}
+					},
+					/*query: function (query) {
+						var url = "service/assets/hive/resources";
+						var data = _.extend(that.getDataParams(type, query.term));
+						//var results = [ {id: query.term, path: query.term}];
+
+						$.get(url, data, function (resp) {
+							var serverRes = [];
+							if(resp.resultSize){
+								serverRes = resp.vXStrings.map(function(m, i){	return {id : m.text, path: m.text};	});
+							}
+							query.callback({results: serverRes});
+						}, 'json');
+
+						//query.callback({results: results});
+					},*/
+
+					ajax: { 
+						url: "service/assets/hive/resources",
+						dataType: 'json',
+						params : {
+							timeout: 3000
+						},
+						cache: false,
+						data: function (term, page) {
+							return _.extend(that.getDataParams(type, term));
+							
+						},
+						results: function (data, page) { 
+							var results = [];
+							if(!_.isUndefined(data)){
+								if(data.resultSize != "0"){
+									results = data.vXStrings.map(function(m, i){	return {id : m.value, text: m.value};	});
+								}
+							}
+							return { 
+								results : results
+							};
+						},
+						transport: function (options) {
+							$.ajax(options).error(function() { 
+								console.log("ajax failed");
+								this.success({
+									resultSize : 0
+								});
+							});
+							/*$.ajax.error(function(data) { 
+								console.log("ajax failed");
+								return {
+									results : []
+								};
+							});*/
+
+						}
+
+					},	
+					formatResult : function(result){
+						return result.text;
+					},
+					formatSelection : function(result){
+						return result.text;
+					},
+					formatNoMatches : function(term){
+						switch (type){
+							case  that.type.DATABASE :return localization.tt("msg.enterAlteastOneCharactere");
+							case  that.type.TABLE :return localization.tt("msg.enterAlteastOneCharactere");
+							case  that.type.COLUMN :return localization.tt("msg.enterAlteastOneCharactere");
+							default : return "No Matches found";
+						}
+					}
+				};	
+			}
+		},
+	});
+
+	return PolicyForm;
+});

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9d85cb76/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
new file mode 100644
index 0000000..b0f3809
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyTableLayout.js
@@ -0,0 +1,388 @@
+/*
+ * 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 XALinks 		= require('modules/XALinks');
+	var XAGlobals 		= require('utils/XAGlobals');
+	var SessionMgr 		= require('mgrs/SessionMgr');
+	var XAUtil			= require('utils/XAUtils');
+	
+	var XABackgrid		= require('views/common/XABackgrid');
+	var XATableLayout	= require('views/common/XATableLayout');
+	var localization	= require('utils/XALangSupport');
+	var vFolderInfo = require('views/folders/FolderInfo');
+	var RangerPolicyTableLayoutTmpl = require('hbs!tmpl/policies/RangerPolicyTableLayout_tmpl');
+
+	require('backgrid-filter');
+	require('backgrid-paginator');
+	require('bootbox');
+
+	var PolicyTableLayout = Backbone.Marionette.Layout.extend(
+	/** @lends PolicyTableLayout */
+	{
+		_viewName : 'PolicyTableLayout',
+		
+    	template: RangerPolicyTableLayoutTmpl,
+
+		templateHelpers : function(){
+			/*return {
+				isSysAdmin 	: this.isSysAdmin,
+				assetId 	: this.assetModel.id,
+				assetModel 	: this.assetModel,
+				version 	: XAGlobals.version
+			};*/
+			return {
+				rangerService:this.rangerService
+			};
+		},
+        
+    	breadCrumbs : function(){
+    		return [XALinks.get('RepositoryManager'),XALinks.get('ManagePolicies',{model : this.rangerService})];
+//    		return [];
+   		},        
+
+		/** Layout sub regions */
+    	regions: {
+			'rTableList'	: 'div[data-id="r_table"]',
+		},
+
+    	// /** ui selector cache */
+    	ui: {
+			'btnDeletePolicy' : '[data-name="deletePolicy"]',
+			'btnShowMore' : '[data-id="showMore"]',
+			'btnShowLess' : '[data-id="showLess"]',
+			'visualSearch' : '.visual_search'
+		},
+
+		/** ui events hash */
+		events: function() {
+			var events = {};
+			events['click ' + this.ui.btnDeletePolicy]  = 'onDelete';
+			events['click ' + this.ui.btnShowMore]  = 'onShowMore';
+			events['click ' + this.ui.btnShowLess]  = 'onShowLess';
+			
+			return events;
+		},
+
+    	/**
+		* intialize a new PolicyTableLayout Layout 
+		* @constructs
+		*/
+		initialize: function(options) {
+			console.log("initialized a PolicyTableLayout Layout");
+
+			_.extend(this, _.pick(options,'rangerService'));
+			
+		/*	this.collection.extraSearchParams = {
+//					resourceType : XAEnums.AssetType.ASSET_HDFS.value,
+					assetId : this.assetModel.id
+			};*/
+			this.bindEvents();
+//			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);
+			//
+		},
+
+		/** on render callback */
+		onRender: function() {
+//			this.initializePlugins();
+//			this.addVisualSearch();
+			this.renderTable();
+//			XAUtil.highlightDisabledPolicy(this);
+		},
+
+		/** all post render plugin initialization */
+		initializePlugins: function(){
+		},
+		renderTable : function(){
+			var that = this;
+			this.rTableList.show(new XATableLayout({
+				columns: this.getColumns(),
+				collection: this.collection,
+				includeFilter : false,
+				gridOpts : {
+//					row: TableRow,
+					header : XABackgrid,
+					emptyText : 'No Policies found!'
+				},
+			}));
+		},
+
+		getColumns : function(){
+			var that = this;
+			var cols = {
+				name : {
+					cell : "uri",
+					href: function(model){
+						return '#!/service/'+that.rangerService.id+'/policies/'+model.id+'/edit';
+					},
+					label	: localization.tt("lbl.policyName"),
+					editable: false,
+					sortable : false
+				},	
+				resources : {
+					cell : "html",
+					label	: localization.tt("lbl.resourcePath"),
+					editable: false,
+					sortable : false,
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue) {
+							return _.map(rawValue, function(resource){ return resource.value;}).toString();
+						}
+					})
+				},
+				isEnabled:{
+					label:localization.tt('lbl.status'),
+					cell :"html",
+					editable:false,
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue) {
+							return rawValue ? '<label class="label label-success">Enabled</label>' : '<label class="label label-important">Disabled</label>';
+						}
+					}),
+					click : false,
+					drag : false,
+					sortable : false
+				},
+				isAuditEnabled:{
+					label:localization.tt('lbl.auditLogging'),
+					cell :"html",
+					editable:false,
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue) {
+							return rawValue ? '<label class="label label-success">Enabled</label>' : '<label class="label label-important">Disabled</label>';
+						}
+					}),
+					click : false,
+					drag : false,
+					sortable : false
+				},
+				/*isRecursive:{
+					label:localization.tt('lbl.includesAllPathsRecursively'),
+					cell :"html",
+					editable:false,
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue) {
+							var status;
+							_.each(_.toArray(XAEnums.BooleanValue),function(m){
+								if(parseInt(rawValue) == m.value){
+									status =  (m.label == XAEnums.BooleanValue.BOOL_TRUE.label) ? true : false;
+								}	
+							});
+							return status ? '<label class="label label-success">YES</label>' : '<label class="label label">NO</label>';
+						}
+					}),
+					click : false,
+					drag : false,
+					sortable : false
+				},
+				permMapList : {
+					reName : 'groupName',
+					cell	: Backgrid.HtmlCell.extend({className: 'cellWidth-1'}),
+					label : localization.tt("lbl.groups"),
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue) {
+							if(!_.isUndefined(rawValue))
+								return XAUtil.showGroups(rawValue);
+							else
+							return '--';
+						}
+					}),
+					editable : false,
+					sortable : false
+				},
+				auditList : {
+					label : localization.tt("lbl.auditLogging"),
+					cell: "html",
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue, model) {
+							return model.has('auditList') ? '<label class="label label-success">ON</label>' : '<label class="label label">OFF</label>';
+						}
+					}),
+					click : false,
+					drag : false,
+					sortable : false,
+					editable : false
+				},
+				isEncrypt:{
+					label:localization.tt("lbl.encrypted"),
+					cell :"Switch",
+					editable:false,
+				//	canHeaderFilter : true,
+				//	headerFilterList :[{label : 'ON',value : 1},{label :'OFF' ,value:2}],
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue) {
+							var status;
+							_.each(_.toArray(XAEnums.BooleanValue),function(m){
+								if(parseInt(rawValue) == m.value){
+									status =  (m.label == XAEnums.BooleanValue.BOOL_TRUE.label) ? true : false;
+									return ;
+								}	
+							});
+							//You can use rawValue to custom your html, you can change this value using the name parameter.
+							return status;
+						}
+					}),
+					click : false,
+					drag : false,
+					onText : 'ON',
+					offText : 'OFF',
+					sortable : false
+				},
+				resourceStatus:{
+					label:localization.tt('lbl.status'),
+					cell :"html",
+					editable:false,
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue) {
+							var status;
+							_.each(_.toArray(XAEnums.BooleanValue),function(m){
+								if(parseInt(rawValue) == m.value){
+									status =  (m.label == XAEnums.BooleanValue.BOOL_TRUE.label) ? true : false;
+								}	
+							});
+							return status ? '<label class="label label-success">Enabled</label>' : '<label class="label label-important">Disabled</label>';
+						}
+					}),
+					click : false,
+					drag : false,
+					sortable : false
+				},
+				permissions : {
+					cell :  "html",
+					label : localization.tt("lbl.action"),
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+						fromRaw: function (rawValue,model) {
+							return '<a href="#!/hdfs/'+model.get('assetId')+'/policy/'+model.id+'" class="btn btn-mini" title="Edit"><i class="icon-edit icon-large" /></a>\
+									<a href="javascript:void(0);" data-name ="deletePolicy" data-id="'+model.id+'"  class="btn btn-mini btn-danger" title="Delete"><i class="icon-trash icon-large" /></a>';
+							//You can use rawValue to custom your html, you can change this value using the name parameter.
+						}
+					}),
+					editable: false,
+					sortable : false
+
+				}
+*/				
+			};
+			return this.collection.constructor.getTableCols(cols, this.collection);
+		},
+		onDelete :function(e){
+			var that = this;
+			var VXResource = require('models/VXResource');
+			var obj = this.collection.get($(e.currentTarget).data('id'));
+			var model = new VXResource(obj.attributes);
+			model.collection = this.collection;
+			XAUtil.confirmPopup({
+				//msg :localize.tt('msg.confirmDelete'),
+				msg :'Are you sure want to delete ?',
+				callback : function(){
+					XAUtil.blockUI();
+					model.destroy({
+						success: function(model, response) {
+							XAUtil.blockUI('unblock');
+							that.collection.remove(model.get('id'));
+							$(that.rFolderInfo.el).hide();
+							XAUtil.notifySuccess('Success', localization.tt('msg.policyDeleteMsg'));
+							if(that.collection.length ==  0){
+								that.renderTable();
+								that.collection.fetch();
+							}
+						},
+						error: function (model, response, options) {
+							XAUtil.blockUI('unblock');
+							if ( response && response.responseJSON && response.responseJSON.msgDesc){
+								    XAUtil.notifyError('Error', response.responseJSON.msgDesc);
+							    }else
+							    	XAUtil.notifyError('Error', 'Error deleting Policy!');
+							    console.log("error");
+						}
+					});
+				}
+			});
+		},
+		onShowMore : function(e){
+			var id = $(e.currentTarget).attr('policy-group-id');
+			this.rTableList.$el.find('[policy-group-id="'+id+'"]').show();
+			$('[data-id="showLess"][policy-group-id="'+id+'"]').show();
+			$('[data-id="showMore"][policy-group-id="'+id+'"]').hide();
+		},
+		onShowLess : function(e){
+			var id = $(e.currentTarget).attr('policy-group-id');
+			this.rTableList.$el.find('[policy-group-id="'+id+'"]').slice(4).hide();
+			$('[data-id="showLess"][policy-group-id="'+id+'"]').hide();
+			$('[data-id="showMore"][policy-group-id="'+id+'"]').show();
+		},
+		addVisualSearch : function(){
+			var that = this;
+			var searchOpt = ['Resource Path','Group','Policy Name'];//,'Start Date','End Date','Today'];
+			var serverAttrName  = [{text : "Resource Path", label :"name"}, {text : "Group", label :"groupName"},
+								   {text : "Policy Name", label :"policyName"}];
+			                     // {text : 'Start Date',label :'startDate'},{text : 'End Date',label :'endDate'},
+				                 //  {text : 'Today',label :'today'}];
+									
+			var pluginAttr = {
+				      placeholder :localization.tt('h.searchForPolicy'),
+				      container : this.ui.visualSearch,
+				      query     : '',
+				      callbacks :  { 
+				    	  valueMatches :function(facet, searchTerm, callback) {
+								switch (facet) {
+									case 'Result':
+										callback(XAUtil.enumToSelectLabelValuePairs(XAEnums.AuthStatus));
+										break;
+									case 'Login Type':
+										callback(XAUtil.enumToSelectLabelValuePairs(XAEnums.AuthType));
+										break;	
+									/*case 'Start Date' :
+										setTimeout(function () { XAUtil.displayDatepicker(that.ui.visualSearch, callback); }, 0);
+										break;
+									case 'End Date' :
+										setTimeout(function () { XAUtil.displayDatepicker(that.ui.visualSearch, callback); }, 0);
+										break;
+									case 'Today'	:
+										var today = Globalize.format(new Date(),"yyyy/mm/dd");
+										callback([today]);
+										break;*/
+								}     
+			            	
+							}
+				      }
+				};
+			window.vs = XAUtil.addVisualSearch(searchOpt,serverAttrName, this.collection,pluginAttr);
+		},
+		/** on close */
+		onClose: function(){
+		}
+
+	});
+
+	return PolicyTableLayout; 
+});

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9d85cb76/security-admin/src/main/webapp/scripts/views/policies/UserPermList.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/policies/UserPermList.js b/security-admin/src/main/webapp/scripts/views/policies/UserPermList.js
new file mode 100644
index 0000000..59b7eed
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policies/UserPermList.js
@@ -0,0 +1,430 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ /*
+ * 
+ */
+define(function(require) {
+    'use strict';
+    
+	var Backbone	= require('backbone');
+    	var App         = require('App');
+	var XAEnums		= require('utils/XAEnums');
+	var XAUtil			= require('utils/XAUtils');
+	var localization	= require('utils/XALangSupport');
+	var VXUser		= require('models/VXUser');
+	require('bootstrap-editable');
+    	
+	var UserPermissionItem = Backbone.Marionette.ItemView.extend({
+		_msvName : 'UserPermissionItem',
+		template : require('hbs!tmpl/common/UserPermissionItem'),
+		tagName : 'tr',
+		templateHelpers : function(){
+						
+			return {
+				permissions 	: this.getPerms(),
+				policyKnox 		: this.policyType == XAEnums.ServiceType.Service_KNOX.value ? true :false,
+//				policyStorm 	: this.policyType == XAEnums.ServiceType.Service_STORM.value ? true :false,
+			   isModelNew		: !this.model.has('editMode'),
+			   stormPerms		: this.stormPermsIds.length == 14 ? _.union(this.stormPermsIds,[-1]) : this.stormPermsIds
+			};
+		},
+		ui : {
+			selectUsers		: '[data-js="selectUsers"]',
+			inputIPAddress	: '[data-js="ipAddress"]',
+			tags			: '[class=tags]'
+		},
+		events : {
+			'click [data-action="delete"]'	: 'evDelete',
+			'click td'						: 'evClickTD',
+			'change [data-js="selectUsers"]': 'evSelectUser',
+			'change [data-js="ipAddress"]'	: 'evIPAddress'
+		},
+
+		initialize : function(options) {
+			_.extend(this, _.pick(options, 'userList','policyType','accessTypes'));
+            //this.subjectList = this.mStudent.getSubjectList();
+			this.stormPermsIds = [];
+			if(this.policyType == XAEnums.AssetType.ASSET_STORM.value){
+				if(this.model.has('editMode') && this.model.get('editMode')){
+					this.stormPermsIds = _.map(this.model.get('_vPermList'), function(p){
+						if(XAEnums.XAPermType.XA_PERM_TYPE_ADMIN.value != p.permType)
+							return p.permType;
+					});
+				}
+			}
+		},
+ 
+		onRender : function() {
+			var that = this;
+			
+			if(this.model.get('userName') != undefined){
+				this.ui.selectUsers.val(this.model.get('userName').split(','));
+			}
+			if(!_.isUndefined(this.model.get('ipAddress'))){
+				this.ui.inputIPAddress.val(this.model.get('ipAddress').toString());
+			}
+			
+			if(this.model.has('editMode') && this.model.get('editMode')){
+				_.each(this.model.get('accesses'), function(p){
+					if(p.value)
+						this.$el.find('input[data-name="' + p.type + '"]').attr('checked', 'checked');
+				},this);
+			}
+			if(this.policyType == XAEnums.AssetType.ASSET_STORM.value)
+				this.renderStormPerms();
+			
+			this.createSelectUserDropDown();
+			this.userDropDownChange();
+			
+			this.accessItems = _.map(this.getPerms(), function(perm){ return {'type':perm.label,'value': false}});
+		},
+		checkDirtyFieldForDropDown : function(e){
+			//that.model.has('groupId')
+			var userIdList =[];
+			if(!_.isUndefined(this.model.get('userId')))
+				userIdList = this.model.get('userId').split(',');
+			XAUtil.checkDirtyField(userIdList, e.val, $(e.currentTarget));
+		},
+		toggleAddButton : function(e){
+			var temp = [];
+			this.collection.each(function(m){
+				if(!_.isUndefined(m.get('userId'))){
+					temp.push.apply(temp, m.get('userId').split(','));
+					
+				}
+			});
+			if(!_.isUndefined(e)){
+				if( !_.isUndefined(e.added) && ((temp.length + 1) == this.userList.length)) 
+					$('[data-action="addUser"]').hide();
+				if(!_.isUndefined(e.removed))
+					$('[data-action="addUser"]').show();
+			}else{
+				$('[data-action="addUser"]').show();
+			}
+		},
+		evDelete : function(){
+			var that = this;
+			this.collection.remove(this.model);
+			this.toggleAddButton();
+		},
+		evClickTD : function(e){
+			var that = this;
+			var $el = $(e.currentTarget),permList =[],perms =[];
+			if($(e.toElement).is('td')){
+				var $checkbox = $el.find('input');
+				$checkbox.is(':checked') ? $checkbox.prop('checked',false) : $checkbox.prop('checked',true);  
+			}
+			var curPerm = $el.find('input').data('id');
+			var curPermName = $el.find('input').data('name');
+			if(!_.isUndefined(curPerm)){
+				var perms = [];
+				if(this.model.has('accesses')){
+					if(_.isArray(this.model.get('accesses')))
+						perms = this.model.get('accesses');
+					else
+						perms.push(this.model.get('accesses'));
+				}
+				
+				
+				if($el.find('input[type="checkbox"]').is(':checked')){
+					_.each(that.accessItems, function(obj){ if(obj.type == curPermName) obj.value = true });
+					if(curPerm == XAEnums.XAPermType.XA_PERM_TYPE_ADMIN.value){
+						$el.parent().find('input[type="checkbox"]:not(:checked)[data-id!="'+curPerm+'"]').map(function(){
+							_.each(that.accessItems, function(obj){ if(obj.type == $(this).data('name')) obj.value = true }, this);
+						});
+						//	this.model.set('_vPermList', perms);
+						$el.parent().find('input[type="checkbox"]').prop('checked',true);
+					}
+				} else {
+					_.each(that.accessItems, function(obj){ if(obj.type == curPermName ) obj.value = false }, this);
+				}
+//				this.checkDirtyFieldForCheckBox(perms);
+				if(!_.isEmpty(that.accessItems)){
+					this.model.set('accesses', that.accessItems);
+				} else {
+					this.model.unset('accesses');
+				}
+			}
+		},
+		checkDirtyFieldForCheckBox : function(perms){
+			var permList = [];
+			if(!_.isUndefined(this.model.get('_vPermList')))
+				permList = _.map(this.model.attributes._vPermList,function(obj){return obj.permType;});
+			perms = _.map(perms,function(obj){return obj.permType;});
+			XAUtil.checkDirtyField(permList, perms, this.$el);
+		},
+		createSelectUserDropDown :function(){
+			var that = this;
+			if(this.model.has('editMode') && !_.isEmpty(this.ui.selectUsers.val())){
+				var temp = this.ui.selectUsers.val().split(",");
+				_.each(temp , function(id){
+					if(_.isUndefined(that.userList.where({ name : name}))){
+						var user = new VXUser({name: name});
+						user.fetch({async:false}).done(function(){
+							that.userList.add(user);
+						});
+					}
+				});
+			}
+			this.userArr = this.userList.map(function(m){
+				return { id : m.id+"" , text : m.get('name')};
+			});
+			this.ui.selectUsers.select2({
+				closeOnSelect : true,
+				placeholder : 'Select User',
+		//		maximumSelectionSize : 1,
+				width :'220px',
+				tokenSeparators: [",", " "],
+				tags : this.userArr, 
+				initSelection : function (element, callback) {
+					var data = [];
+					$(element.val().split(",")).each(function () {
+						var obj = _.findWhere(that.userArr,{ text : this });	
+						data.push({ id : obj.id, text: this });
+					});
+					callback(data);
+				},
+				createSearchChoice: function(term, data) {
+					/*if ($(data).filter(function() {
+						return this.text.localeCompare(term) === 0;
+						//return this.value == (term) ?  true : false;
+					}).length === 0) {
+						return {
+							id : term,
+							text: term
+						};
+					}*/
+				},
+				ajax: { 
+					url: "service/xusers/users",
+					dataType: 'json',
+					data: function (term, page) {
+						return {name : term};
+					},
+					results: function (data, page) { 
+						var results = [],selectedVals=[];
+						/*if(!_.isEmpty(that.ui.selectUsers.select2('val')))
+							selectedVals = that.ui.selectUsers.select2('val');
+						selectedVals.push.apply(selectedVals, that.getUsersSelectdValues());
+						selectedVals = $.unique(selectedVals);*/
+						selectedVals = that.getUsersSelectdValues();
+						if(data.resultSize != "0"){
+							//if(data.vXUsers.length > 1){
+
+								results = data.vXUsers.map(function(m, i){	return {id : m.id+"", text: m.name};	});
+								if(!_.isEmpty(selectedVals))
+									results = XAUtil.filterResultByIds(results, selectedVals);
+								//console.log(results.length);
+								return {results : results};
+						//	}
+						//	results = [{id : data.vXUsers.id+"", text: data.vXUsers.name}];
+						//	return {results : results};
+						}
+						return {results : results};
+					}
+				},	
+				formatResult : function(result){
+					return result.text;
+				},
+				formatSelection : function(result){
+					return result.text;
+				},
+				formatNoMatches: function(result){
+					return 'No user found.';
+				}
+				
+			}).on('select2-focus', XAUtil.select2Focus);
+		},
+		userDropDownChange : function(){
+			var that = this;
+			this.ui.selectUsers.on('change',function(e){
+				//	console.log(e.currentTarget.value);
+					that.checkDirtyFieldForDropDown(e);
+					that.toggleAddButton(e);
+					var duplicateUsername = false;
+					if(e.removed != undefined){
+						var gIdArr = [],gNameArr = [];
+						gIdArr = _.without(that.model.get('userId').split(','), e.removed.id);
+						if(that.model.get('userName') != undefined)
+							gNameArr = _.without(that.model.get('userName').split(','), e.removed.text);
+						if(!_.isEmpty(gIdArr)){
+							that.model.set('userId',gIdArr.join(','));
+							that.model.set('userName',gNameArr.join(','));
+						}else{
+							that.model.unset('userId');
+							that.model.unset('userName');
+						}
+						return;
+						
+					}
+					if(!_.isUndefined(e.added)){
+							that.model.set('userId', e.currentTarget.value);
+							var userNameList = _.map($(e.currentTarget).select2("data"), function(obj){return obj.text});
+							that.model.set('userName',userNameList.toString())
+					}
+				});
+		},
+		getUsersSelectdValues : function(){
+			var vals = [],selectedVals = [];
+			this.collection.each(function(m){
+				if(!_.isUndefined(m.get('userId'))){
+					vals.push.apply(vals, m.get('userId').split(','));
+				}
+			});
+			if(!_.isEmpty(this.ui.selectUsers.select2('val')))
+				selectedVals = this.ui.selectUsers.select2('val');
+			vals.push.apply(vals , selectedVals);
+			vals = $.unique(vals);
+			return vals;
+		},
+		evIPAddress :function(e){
+			if(!_.isEmpty($(e.currentTarget).val()))
+				this.model.set('ipAddress',$(e.currentTarget).val().split(','));
+			else
+				this.model.unset('ipAddress');
+		},
+		renderStormPerms :function(){
+			var that = this;
+			var permArr = _.pick(XAEnums.XAPermType,  XAUtil.getStormActions(this.policyType));
+			this.stormPerms =  _.map(permArr,function(m){return {text:m.label, value:m.value};});
+			this.stormPerms.push({'value' : -1, 'text' : 'Select/Deselect All'});
+			this.ui.tags.editable({
+			    placement: 'right',
+//			    emptytext : 'Please select',
+			    source: this.stormPerms,
+			    display: function(idList,srcData) {
+			    	if(_.isEmpty(idList.toString())){
+			    		$(this).html('');
+			    		return;
+			    	}
+			    	if(!_.isArray(idList))
+			    		idList = [idList];
+//			    	that.checkDirtyFieldForGroup(values);
+			    	var permTypeArr = [];
+		    		var valArr = _.map(idList, function(id){
+		    			if(!(parseInt(id) <= 0) && (!_.isNaN(parseInt(id)))){
+			    			var obj = _.findWhere(srcData,{'value' : parseInt(id)});
+			    			permTypeArr.push({permType : obj.value});
+			    			return "<span class='label label-inverse'>" + obj.text + "</span>";
+		    			}
+		    		});
+		    		if(that.model.has('_vPermList')){
+                        var adminPerm = _.where(that.model.get('_vPermList'),{'permType': XAEnums.XAPermType.XA_PERM_TYPE_ADMIN.value });
+                        permTypeArr = _.isEmpty(adminPerm) ? permTypeArr : _.union(permTypeArr,adminPerm);
+                    }
+                    that.model.set('_vPermList', permTypeArr);
+		    		
+		    		$(this).html(valArr.join(" "));
+			    },
+			});
+			this.$('[id^="tags-edit-"]').click(function(e) {
+			    e.stopPropagation();
+			    e.preventDefault();
+			    that.$('#' + $(this).data('editable') ).editable('toggle');
+			    that.$('input[type="checkbox"][value="-1"]').click(function(e){
+					var checkboxlist =$(this).closest('.editable-checklist').find('input[type="checkbox"][value!=-1]');
+					$(this).is(':checked') ? checkboxlist.prop('checked',true) : checkboxlist.prop('checked',false); 
+					
+				});
+			});
+		},
+		getPerms : function(){
+			var permList = _.map(this.accessTypes,function(type){ return type.label});
+			return _.map(permList, function(perm){ return _.findWhere(XAEnums.XAPermType,{label:perm})})
+		}
+
+	});
+
+
+
+	return Backbone.Marionette.CompositeView.extend({
+		_msvName : 'UserPermissionList',
+		template : require('hbs!tmpl/common/UserPermissionList'),
+		//tagName : 'ul', 
+		//className : 'timeline-container',
+		templateHelpers :function(){
+			return {
+				permHeaders : this.getPermHeaders()
+			};
+		},
+		getItemView : function(item){
+			if(!item){
+				return;
+			}
+			return UserPermissionItem;
+		},
+		itemViewContainer : ".js-formInput",
+		itemViewOptions : function() {
+			return {
+				'collection' : this.collection,
+				'userList' : this.userList,
+				'policyType'	: this.policyType,
+				'accessTypes' : this.accessTypes
+			};
+		},
+		events : {
+			'click [data-action="addUser"]' : 'addNew'
+		},
+		initialize : function(options) {
+			_.extend(this, _.pick(options, 'userList','policyType','accessTypes','rangerServiceDefModel'));
+			//this.listenTo(this.collection, 'removeAddBtn', this.render, this);
+			/*if(options.model.isNew())
+				this.collection.add(new Backbone.Model());*/
+			if(this.collection.length == 0)
+				this.collection.add(new Backbone.Model());
+				
+		},
+		onRender : function(){
+			//console.log("onRender of ArtifactFormNoteList called");
+			this.toggleAddButton();
+		},
+		addNew : function(){
+			var that =this;
+			this.collection.add(new Backbone.Model());
+			this.toggleAddButton();
+		},
+		toggleAddButton : function(){
+			var userIds=[];
+			this.collection.each(function(m){
+				if(!_.isUndefined(m.get('userId'))){
+					var temp = m.get('userId').split(',');
+					userIds.push.apply(userIds,temp);
+				}
+			});
+			if(userIds.length == this.userList.length)
+				this.$('button[data-action="addUser"]').hide();
+			else
+				this.$('button[data-action="addUser"]').show();
+		},
+		getPermHeaders : function(){
+			var permList = _.map(this.accessTypes,function(type){ return type.label});
+			if(!_.isEmpty(this.rangerServiceDefModel.get('policyConditions'))){
+				_.each(this.rangerServiceDefModel.get('policyConditions'), function(cond){
+					if(!_.isNull(cond) && !_.isNull(cond.label)) permList.unshift(cond.label);
+				});
+			}
+			permList.unshift(localization.tt('lbl.selectGroup'));
+			permList.push("");
+			return permList;
+		},
+	
+	});
+
+});

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9d85cb76/security-admin/src/main/webapp/scripts/views/policymanager/ServiceLayout.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/policymanager/ServiceLayout.js b/security-admin/src/main/webapp/scripts/views/policymanager/ServiceLayout.js
new file mode 100644
index 0000000..0c29c2c
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policymanager/ServiceLayout.js
@@ -0,0 +1,106 @@
+/*
+ * 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 XALinks 			= require('modules/XALinks');
+	var XAEnums 			= require('utils/XAEnums');
+	var XAUtil				= require('utils/XAUtils');
+	var SessionMgr 			= require('mgrs/SessionMgr');
+	var RangerServiceList 	= require('collections/RangerServiceList');
+	
+	var ServicemanagerlayoutTmpl = require('hbs!tmpl/common/ServiceManagerLayout_tmpl');
+	return Backbone.Marionette.Layout.extend(
+	/** @lends Servicemanagerlayout */
+	{
+		_viewName : name,
+		
+    	template: ServicemanagerlayoutTmpl,
+
+		templateHelpers: function(){
+			var groupedServices = this.services.groupBy("type");
+
+			return {
+				isSysAdmin : SessionMgr.isSystemAdmin(),
+				serviceDefs : this.collection.models,
+				services : groupedServices
+			};
+		},
+    	breadCrumbs :[XALinks.get('RepositoryManager')],
+
+		/** Layout sub regions */
+    	regions: {},
+
+    	/** ui selector cache */
+    	ui: {},
+
+		/** ui events hash */
+		events : function(){
+			var events = {};
+			return events;
+		},
+    	/**
+		* intialize a new Servicemanagerlayout Layout 
+		* @constructs
+		*/
+		initialize: function(options) {
+			console.log("initialized a Servicemanagerlayout Layout");
+			this.services = new RangerServiceList();	
+			_.extend(this, _.pick(options, 'collection'));
+			this.bindEvents();
+			this.initializeServices();
+		},
+
+		/** all events binding here */
+		bindEvents : function(){
+			/*this.listenTo(communicator.vent,'someView:someEvent', this.someEventHandler, this)'*/
+			this.listenTo(this.collection, "sync", this.render, this);
+			this.listenTo(this.collection, "request", function(){
+				this.$('[data-id="r_tableSpinner"]').removeClass('display-none').addClass('loading');
+			}, this);
+		},
+
+		/** on render callback */
+		onRender: function() {
+			this.$('[data-id="r_tableSpinner"]').removeClass('loading').addClass('display-none');
+			this.initializePlugins();
+		},
+
+		/** all post render plugin initialization */
+		initializePlugins: function(){
+
+		},
+
+		initializeServices : function(){
+			this.services.fetch({
+			   cache : false,
+			   async : false
+			});
+
+		},
+		/** on close */
+		onClose: function(){
+		}
+
+	});
+});