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

incubator-ranger git commit: RANGER-1237:Ranger permissions do not load when there are bulk users

Repository: incubator-ranger
Updated Branches:
  refs/heads/master b99525389 -> ebcf9dd5e


RANGER-1237:Ranger permissions do not load when there are bulk users

Signed-off-by: Gautam Borad <ga...@apache.org>


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

Branch: refs/heads/master
Commit: ebcf9dd5e8c35a12b84405067bb7db0c5c3596c6
Parents: b995253
Author: pradeep agrawal <pr...@freestoneinfotech.com>
Authored: Tue Dec 13 12:39:58 2016 +0530
Committer: Gautam Borad <ga...@apache.org>
Committed: Wed Dec 14 15:04:38 2016 +0530

----------------------------------------------------------------------
 .../java/org/apache/ranger/biz/XUserMgr.java    |  24 +-
 .../ranger/service/XGroupPermissionService.java |  26 ++
 .../apache/ranger/service/XGroupService.java    |  17 +-
 .../ranger/service/XModuleDefService.java       |  43 ++--
 .../ranger/service/XUserPermissionService.java  |  27 ++
 .../org/apache/ranger/service/XUserService.java |  24 ++
 .../webapp/scripts/controllers/Controller.js    |   2 +-
 .../main/webapp/scripts/models/XABaseModel.js   |   4 +-
 .../scripts/modules/globalize/message/en.js     |   9 +-
 .../src/main/webapp/scripts/utils/XAUtils.js    |  14 +-
 .../views/permissions/ModulePermissionCreate.js |  22 +-
 .../views/permissions/ModulePermissionForm.js   | 251 +++++++++++--------
 security-admin/src/main/webapp/styles/xa.css    |  21 ++
 .../permissions/ModulePermissionForm_tmpl.html  |  41 ++-
 14 files changed, 354 insertions(+), 171 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index e3f7223..189a254 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -851,18 +851,26 @@ public class XUserMgr extends XUserMgrBase {
 		VXModuleDef vModuleDefPopulateOld = xModuleDefService.populateViewBean(xModuleDef);
 
 		List<XXGroupPermission> xgroupPermissionList = daoManager.getXXGroupPermission().findByModuleId(vXModuleDef.getId(), true);
-
-		for (XXGroupPermission xGrpPerm : xgroupPermissionList) {
-			VXGroupPermission vXGrpPerm = xGroupPermissionService.populateViewBean(xGrpPerm);
-			groupPermListOld.add(vXGrpPerm);
+                Map<Long, XXGroup> xXGroupMap=xGroupService.getXXGroupIdXXGroupMap();
+                if(xXGroupMap==null || xXGroupMap.isEmpty()){
+                        for (XXGroupPermission xGrpPerm : xgroupPermissionList) {
+                                VXGroupPermission vXGrpPerm = xGroupPermissionService.populateViewBean(xGrpPerm);
+                                groupPermListOld.add(vXGrpPerm);
+                        }
+                }else{
+                        groupPermListOld=xGroupPermissionService.getPopulatedVXGroupPermissionList(xgroupPermissionList,xXGroupMap,vModuleDefPopulateOld);
 		}
 		vModuleDefPopulateOld.setGroupPermList(groupPermListOld);
 
 		List<XXUserPermission> xuserPermissionList = daoManager.getXXUserPermission().findByModuleId(vXModuleDef.getId(), true);
-
-		for (XXUserPermission xUserPerm : xuserPermissionList) {
-			VXUserPermission vUserPerm = xUserPermissionService.populateViewBean(xUserPerm);
-			userPermListOld.add(vUserPerm);
+                Map<Long, XXUser> xXPortalUserIdXXUserMap=xUserService.getXXPortalUserIdXXUserMap();
+                if(xXPortalUserIdXXUserMap==null || xXPortalUserIdXXUserMap.isEmpty()){
+                        for (XXUserPermission xUserPerm : xuserPermissionList) {
+                                VXUserPermission vUserPerm = xUserPermissionService.populateViewBean(xUserPerm);
+                                userPermListOld.add(vUserPerm);
+                        }
+                }else{
+                        userPermListOld=xUserPermissionService.getPopulatedVXUserPermissionList(xuserPermissionList,xXPortalUserIdXXUserMap,vModuleDefPopulateOld);
 		}
 		vModuleDefPopulateOld.setUserPermList(userPermListOld);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/java/org/apache/ranger/service/XGroupPermissionService.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XGroupPermissionService.java b/security-admin/src/main/java/org/apache/ranger/service/XGroupPermissionService.java
index 20c3b67..3df5233 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XGroupPermissionService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XGroupPermissionService.java
@@ -17,12 +17,17 @@
 
 package org.apache.ranger.service;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.common.SearchField;
 import org.apache.ranger.db.RangerDaoManager;
 import org.apache.ranger.entity.XXGroup;
 import org.apache.ranger.entity.XXGroupPermission;
 import org.apache.ranger.view.VXGroupPermission;
+import org.apache.ranger.view.VXModuleDef;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
@@ -77,4 +82,25 @@ public class XGroupPermissionService extends XGroupPermissionServiceBase<XXGroup
 		vObj.setGroupName(xGroup.getName());
 		return vObj;
 	}
+
+        public List<VXGroupPermission> getPopulatedVXGroupPermissionList(List<XXGroupPermission> xgroupPermissionList,Map<Long, XXGroup> xXGroupMap,VXModuleDef vModuleDef){
+                List<VXGroupPermission> vXGroupPermissionList = new ArrayList<VXGroupPermission>();
+                XXGroup xXGroup=null;
+                for(XXGroupPermission xgroupPermission:xgroupPermissionList){
+                        if(xXGroupMap.containsKey(xgroupPermission.getGroupId())){
+                                xXGroup =xXGroupMap.get(xgroupPermission.getGroupId());
+                                VXGroupPermission vXGrpPerm=new VXGroupPermission();
+                                vXGrpPerm.setId(xgroupPermission.getId());
+                                vXGrpPerm.setGroupId(xgroupPermission.getGroupId());
+                                vXGrpPerm.setModuleId(xgroupPermission.getModuleId());
+                                vXGrpPerm.setIsAllowed(xgroupPermission.getIsAllowed());
+                                vXGrpPerm.setCreateDate(xgroupPermission.getCreateTime());
+                                vXGrpPerm.setUpdateDate(xgroupPermission.getUpdateTime());
+                                vXGrpPerm.setGroupName(xXGroup.getName());
+                                vXGrpPerm.setModuleName(vModuleDef.getModule());
+                                vXGroupPermissionList.add(vXGrpPerm);
+                        }
+                }
+                return vXGroupPermissionList;
+        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java b/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java
index d74d2bf..e259eae 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XGroupService.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.ranger.common.AppConstants;
 import org.apache.ranger.common.MessageEnums;
@@ -41,6 +42,7 @@ import org.apache.ranger.view.VXGroup;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 @Service
 @Scope("singleton")
@@ -253,5 +255,18 @@ public class XGroupService extends XGroupServiceBase<XXGroup, VXGroup> {
 	protected VXGroup mapEntityToViewBean(VXGroup vObj, XXGroup mObj) {
 		super.mapEntityToViewBean(vObj, mObj);
 		return vObj;
-	}	
+        }
+
+        public Map<Long, XXGroup> getXXGroupIdXXGroupMap(){
+                Map<Long, XXGroup> xXGroupMap=new HashMap<Long, XXGroup>();
+                try{
+                        List<XXGroup> xXGroupList=rangerDaoManager.getXXGroup().getAll();
+                        if(!CollectionUtils.isEmpty(xXGroupList)){
+                                for(XXGroup xXGroup:xXGroupList){
+                                        xXGroupMap.put(xXGroup.getId(), xXGroup);
+                                }
+                        }
+                }catch(Exception ex){}
+                return xXGroupMap;
+        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/java/org/apache/ranger/service/XModuleDefService.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XModuleDefService.java b/security-admin/src/main/java/org/apache/ranger/service/XModuleDefService.java
index 2e00643..b8403e8 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XModuleDefService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XModuleDefService.java
@@ -19,12 +19,14 @@ package org.apache.ranger.service;
 
 import java.util.ArrayList;
 import java.util.List;
-
+import java.util.Map;
 import org.apache.ranger.common.RangerConstants;
 import org.apache.ranger.common.SearchField;
 import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.entity.XXGroup;
 import org.apache.ranger.entity.XXGroupPermission;
 import org.apache.ranger.entity.XXModuleDef;
+import org.apache.ranger.entity.XXUser;
 import org.apache.ranger.entity.XXUserPermission;
 import org.apache.ranger.view.VXGroupPermission;
 import org.apache.ranger.view.VXModuleDef;
@@ -32,6 +34,7 @@ import org.apache.ranger.view.VXUserPermission;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 @Service
 @Scope("singleton")
@@ -49,6 +52,11 @@ public class XModuleDefService extends
 	@Autowired
 	XGroupPermissionService xGrpPermService;
 
+        @Autowired
+        XUserService xUserService;
+
+        @Autowired
+        XGroupService xGroupService;
 	public XModuleDefService() {
 		searchFields.add(new SearchField("module", "obj.module",
 				SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.PARTIAL));
@@ -84,34 +92,33 @@ public class XModuleDefService extends
 
 	@Override
 	public VXModuleDef populateViewBean(XXModuleDef xObj) {
-
 		VXModuleDef vModuleDef = super.populateViewBean(xObj);
+                Map<Long, XXUser> xXPortalUserIdXXUserMap=xUserService.getXXPortalUserIdXXUserMap();
+                Map<Long, XXGroup> xXGroupMap=xGroupService.getXXGroupIdXXGroupMap();
 		List<VXUserPermission> vXUserPermissionList = new ArrayList<VXUserPermission>();
 		List<VXGroupPermission> vXGroupPermissionList = new ArrayList<VXGroupPermission>();
-
 		List<XXUserPermission> xuserPermissionList = rangerDaoManager
 				.getXXUserPermission().findByModuleId(xObj.getId(), false);
 		List<XXGroupPermission> xgroupPermissionList = rangerDaoManager
 				.getXXGroupPermission().findByModuleId(xObj.getId(), false);
-		for (XXUserPermission xUserPerm : xuserPermissionList) {
-
-			VXUserPermission vXUserPerm = xUserPermService
-					.populateViewBean(xUserPerm);
-			vXUserPermissionList.add(vXUserPerm);
-
+                if(CollectionUtils.isEmpty(xXPortalUserIdXXUserMap)){
+                        for (XXUserPermission xUserPerm : xuserPermissionList) {
+                                VXUserPermission vXUserPerm = xUserPermService.populateViewBean(xUserPerm);
+                                vXUserPermissionList.add(vXUserPerm);
+                        }
+                }else{
+                        vXUserPermissionList=xUserPermService.getPopulatedVXUserPermissionList(xuserPermissionList,xXPortalUserIdXXUserMap,vModuleDef);
 		}
-
-		for (XXGroupPermission xGrpPerm : xgroupPermissionList) {
-
-			VXGroupPermission vXGrpPerm = xGrpPermService
-					.populateViewBean(xGrpPerm);
-			vXGroupPermissionList.add(vXGrpPerm);
-
+                if(CollectionUtils.isEmpty(xXGroupMap)){
+                        for (XXGroupPermission xGrpPerm : xgroupPermissionList) {
+                                VXGroupPermission vXGrpPerm = xGrpPermService.populateViewBean(xGrpPerm);
+                                vXGroupPermissionList.add(vXGrpPerm);
+                        }
+                }else{
+                        vXGroupPermissionList=xGrpPermService.getPopulatedVXGroupPermissionList(xgroupPermissionList,xXGroupMap,vModuleDef);
 		}
-
 		vModuleDef.setUserPermList(vXUserPermissionList);
 		vModuleDef.setGroupPermList(vXGroupPermissionList);
 		return vModuleDef;
 	}
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/java/org/apache/ranger/service/XUserPermissionService.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XUserPermissionService.java b/security-admin/src/main/java/org/apache/ranger/service/XUserPermissionService.java
index bd3a50d..3a97ef8 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XUserPermissionService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XUserPermissionService.java
@@ -17,11 +17,17 @@
 
 package org.apache.ranger.service;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.ranger.common.SearchField;
 import org.apache.ranger.db.RangerDaoManager;
 import org.apache.ranger.entity.XXModuleDef;
 import org.apache.ranger.entity.XXPortalUser;
+import org.apache.ranger.entity.XXUser;
 import org.apache.ranger.entity.XXUserPermission;
+import org.apache.ranger.view.VXModuleDef;
 import org.apache.ranger.view.VXUserPermission;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
@@ -71,4 +77,25 @@ public class XUserPermissionService extends XUserPermissionServiceBase<XXUserPer
 		return vObj;
 	}
 
+        public List<VXUserPermission> getPopulatedVXUserPermissionList(List<XXUserPermission> xuserPermissionList,Map<Long, XXUser> xXPortalUserIdXXUserMap,VXModuleDef vModuleDef){
+                List<VXUserPermission> vXUserPermissionList = new ArrayList<VXUserPermission>();
+                XXUser xXUser=null;
+                for(XXUserPermission xuserPermission:xuserPermissionList){
+                        if(xXPortalUserIdXXUserMap.containsKey(xuserPermission.getUserId())){
+                                xXUser =xXPortalUserIdXXUserMap.get(xuserPermission.getUserId());
+                                VXUserPermission vXUserPerm=new VXUserPermission();
+                                vXUserPerm.setId(xuserPermission.getId());
+                                vXUserPerm.setUserId(xXUser.getId());
+                                vXUserPerm.setModuleId(xuserPermission.getModuleId());
+                                vXUserPerm.setIsAllowed(xuserPermission.getIsAllowed());
+                                vXUserPerm.setCreateDate(xuserPermission.getCreateTime());
+                                vXUserPerm.setUpdateDate(xuserPermission.getUpdateTime());
+                                vXUserPerm.setModuleName(vModuleDef.getModule());
+                                vXUserPerm.setLoginId(xXUser.getName());
+                                vXUserPerm.setUserName(xXUser.getName());
+                                vXUserPermissionList.add(vXUserPerm);
+                        }
+                }
+                return vXUserPermissionList;
+        }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/java/org/apache/ranger/service/XUserService.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XUserService.java b/security-admin/src/main/java/org/apache/ranger/service/XUserService.java
index 8ba9ef6..0d07982 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XUserService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XUserService.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.ranger.biz.RangerBizUtil;
@@ -47,6 +48,7 @@ import org.apache.ranger.view.VXUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 @Service
 @Scope("singleton")
@@ -383,5 +385,27 @@ public class XUserService extends XUserServiceBase<XXUser, VXUser> {
 
 		return trxLogList;
 	}
+        public Map<Long, XXUser> getXXPortalUserIdXXUserMap(){
+                Map<Long, XXUser> xXPortalUserIdXXUserMap=new HashMap<Long, XXUser>();
+                try{
+                        Map<String, XXUser> xXUserMap=new HashMap<String, XXUser>();
+                        List<XXUser> xXUserList=daoManager.getXXUser().getAll();
+                        if(!CollectionUtils.isEmpty(xXUserList)){
+                                for(XXUser xxUser:xXUserList){
+                                        xXUserMap.put(xxUser.getName(), xxUser);
+                                }
+                        }
+                        xXUserList=null;
+                        List<XXPortalUser> xXPortalUserList=daoManager.getXXPortalUser().getAll();
+                        if(!CollectionUtils.isEmpty(xXPortalUserList)){
+                                for(XXPortalUser xXPortalUser:xXPortalUserList){
+                                        if(xXUserMap.containsKey(xXPortalUser.getLoginId())){
+                                                xXPortalUserIdXXUserMap.put(xXPortalUser.getId(),xXUserMap.get(xXPortalUser.getLoginId()));
+                                        }
+                                }
+                        }
+                }catch(Exception ex){}
+                return xXPortalUserIdXXUserMap;
+        }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/webapp/scripts/controllers/Controller.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/controllers/Controller.js b/security-admin/src/main/webapp/scripts/controllers/Controller.js
index fc56496..041c6b7 100755
--- a/security-admin/src/main/webapp/scripts/controllers/Controller.js
+++ b/security-admin/src/main/webapp/scripts/controllers/Controller.js
@@ -346,7 +346,7 @@ define(function(require) {
 		   var modulePermission 	= new ModulePermission({id : moduleId});
 		   var that = this
 		   modulePermission.collection = new ModulePermissionList();
-		   modulePermission.fetch({cache : true}).done(function(){
+                   modulePermission.fetch({cache : false}).done(function(){
 			   App.rContent.show(new view({
 				   model : modulePermission,
 				   groupList : that.groupList,

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/webapp/scripts/models/XABaseModel.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/models/XABaseModel.js b/security-admin/src/main/webapp/scripts/models/XABaseModel.js
index 03b4e13..6083210 100644
--- a/security-admin/src/main/webapp/scripts/models/XABaseModel.js
+++ b/security-admin/src/main/webapp/scripts/models/XABaseModel.js
@@ -41,9 +41,9 @@ define(function(require){
 		},
 		bindErrorEvents :function(){
 			//Moved require inside fuctn expression due to ie issue
-			this.bind("error", function(){
+                        this.bind("error", function(e){
 				var XAUtils = require('utils/XAUtils');
-			        XAUtils.defaultErrorHandler();
+                                XAUtils.defaultErrorHandler(undefined, e);
 			});
 		},
 		/**

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/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 99a5424..63a5b0f 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
@@ -237,7 +237,9 @@ define(function(require) {
 				selectMaskingOption             : 'Select Masking Option',
 				versionTime                     : 'Version / Time',
 				serviceType                     : 'Service Type',
-				hostName						: 'Host Name'
+                                hostName						: 'Host Name',
+                                selectAndAddUser                                : 'Select and Add User',
+                                selectAndAddGroup                               : 'Select and Add Group',
 			},
 			btn : {
 				add							: 'Add',
@@ -373,7 +375,10 @@ define(function(require) {
                 resultMsg               :'Search by access result i.e Allowed/Denied logs.',
                 statusMsg               :'Status of Policy Enable/Disable.',
                 columnfamily            :'Hbase column-family',
-                searchForPluginStatus   : "Search for Plugin Status...."
+                searchForPluginStatus   : "Search for Plugin Status....",
+                pleaseSelectUser        : 'Please select user.',
+                pleaseSelectGroup       : 'Please select group.',
+                addSelectedUserGroup	: 'Please add selected user/group to permissions else user/group will not be added.'
 
 			},
 			plcHldr : {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/webapp/scripts/utils/XAUtils.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/utils/XAUtils.js b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
index 14ac70b..c026b52 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
@@ -537,19 +537,10 @@ define(function(require) {
 	};
 
 	XAUtils.showGroupsOrUsers = function(rawValue, model, userOrGroups) {
-		var showMoreLess = false, objArr = [];
+                var showMoreLess = false, objArr;
 		if (!_.isArray(rawValue) && rawValue.length == 0)
 			return '--';
-		if (userOrGroups == 'groups') {
-			_.each(rawValue, function(perm) {
-				objArr = _.union(objArr, _.escape(perm.groupName))
-			});
-		} else if (userOrGroups == 'users') {
-			_.each(rawValue, function(perm) {
-				objArr = _.union(objArr, _.escape(perm.userName))
-			});
-		}
-
+                objArr = (userOrGroups == 'groups') ? _.pluck(rawValue, 'groupName') : _.pluck(rawValue, 'userName');
 		var newObjArr = _.map(objArr, function(name, i) {
 			if (i >= 4) {
 				return '<span class="label label-info float-left-margin-2" policy-' + userOrGroups
@@ -579,7 +570,6 @@ define(function(require) {
 		newObjArr.unshift('<div data-id="groupsDiv">');
 		newObjArr.push('</div>');
 		return newObjArr.length ? newObjArr.join(' ') : '--';
-
 	};
 
 	XAUtils.defaultErrorHandler = function(model, error) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionCreate.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionCreate.js b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionCreate.js
index 02b879d..0d1c92f 100644
--- a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionCreate.js
+++ b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionCreate.js
@@ -92,29 +92,9 @@ define(function(require){
 		initializePlugins: function(){
 		},
 		renderForm : function(){
-			var VXGroupList		= require('collections/VXGroupList');
-			var VXUserList		= require('collections/VXUserList');
-		    var params = {sortBy : 'name'};
-		    this.userList = new VXUserList();
-		    this.userList.setPageSize(100,{fetch:true});
-		    this.userList.fetch({
-		    	cache :false,
-				data: params,
-				async : false
-		   });
-		   this.groupList = new VXGroupList();
-		   this.groupList.setPageSize(100,{fetch:true});
-		   this.groupList.fetch({
-			   cache :false,
-			   data : params,
-			   async : false
-		   });
-		   var that = this;
 		   this.form = new ModulePermissionForm({
 			   template  : require('hbs!tmpl/permissions/ModulePermissionForm_tmpl'),
-			   model 	  : that.model,
-			   groupList : that.groupList,
-			   userList  : that.userList
+                           model 	  : this.model,
 		   });
 		   this.rForm.show(this.form);
 		},

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionForm.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionForm.js b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionForm.js
index 1756955..aa4c332 100644
--- a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionForm.js
+++ b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermissionForm.js
@@ -48,20 +48,35 @@ define(function(require) {
 		templateHelpers :function(){
 		},
 		templateData : function(){
-			return { 'id' : this.model.id, 'permHeaders' : this.getPermHeaders() };
+                        return {
+                                'id' : this.model.id,
+                                'permHeaders' : this.getPermHeaders(),
+                                'userList' : this.model.get('userPermList'),
+                                'groupList' : this.model.get('groupPermList')
+                        };
 		},
 		initialize : function(options) {
-			_.extend(this, _.pick(options, 'groupList','userList'));
+                        _.extend(this, _.pick(options));
+
 			if (!this.model.isNew()){
 				this.setupFieldsforEditModule();
 			}
 			Backbone.Form.prototype.initialize.call(this, options);
 		},
 		ui : {
-			/*selectGroups	: 'div[data-fields="selectGroups"]',
-			selectUsers		: 'div[data-fields="selectUsers"]',*/
+                        selectGroups	: 'div[data-editors="selectGroups"]',
+                        selectUsers		: 'div[data-editors="selectUsers"]',
+                        addGroupBtn		: '[data-id="addGroupBtn"]',
+                        addUserBtn		: '[data-id="addUserBtn"]',
 		},
-		events : {
+                events : function(){
+                        var events = {};
+                        events['click ' + this.ui.addGroupBtn ] = 'onAddGroup';
+                        events['click ' + this.ui.addUserBtn ] = 'onAddUser';
+                        events['click ' + '[data-js="addUser"]']  = 'onAddUserClick';
+                        events['click ' + '[data-js="selectedGroupSpan"]']  = 'onRemovedGroupClick';
+
+                        return events;
 		},
 		/** fields for the form
 		*/
@@ -81,13 +96,13 @@ define(function(require) {
 				selectGroups : {
 					type : 'Select2Remote',
 					editorAttrs  : {'placeholder' :'Select Group','tokenSeparators': [",", " "],multiple:true},
-					pluginAttr: this.getPlugginAttr(true,{'lookupURL':"service/xusers/groups",'permList':that.model.get('groupPermList'),'idKey':'groupId','textKey':'groupName'}),
+                                        pluginAttr: this.getPlugginAttr(true,{'lookupURL':"service/xusers/groups",'idKey':'groupId','textKey':'groupName'}),
 					title : localization.tt('lbl.selectGroup')+' *'
 				},
 				selectUsers : {
 					type : 'Select2Remote',
 					editorAttrs  : {'placeholder' :'Select User','tokenSeparators': [",", " "],multiple:true},
-					pluginAttr: this.getPlugginAttr(true,{'lookupURL':"service/xusers/users",'permList':that.model.get('userPermList'),'idKey':'userId','textKey':'userName'}),
+                                        pluginAttr: this.getPlugginAttr(true,{'lookupURL':"service/xusers/users",'idKey':'userId','textKey':'userName'}),
 					title : localization.tt('lbl.selectUser')+' *',
 				},
 				isAllowed : {
@@ -100,27 +115,28 @@ define(function(require) {
 		render: function(options) {
 			var that = this;
 			Backbone.Form.prototype.render.call(this, options);
+                        this.$el.find('[data-js="selectedGroupList"] span i').on('click', this.removeGroup.bind(this));
+                        this.$el.find('[data-js="selectedUserList"] span i').on('click', this.removeUser.bind(this));
 			
+                        if(this.model.get('groupPermList').length <= 0){
+                                this.$el.find('.emptySelectedGroups').show();
+                        }else{
+                                this.$el.find('.emptySelectedGroups').hide();
+                        }
+                        if(this.model.get('userPermList').length <= 0){
+                                this.$el.find('.emptySelectedUsers').show();
+                        }else{
+                                this.$el.find('.emptySelectedUsers').hide();
+                        }
 		},
 		setupFieldsforEditModule : function(){
-			var groupsNVList=[],usersNVList =[];
-			groupsNVList = _.map(this.model.get('groupPermList'),function(gPerm){
-				return {'id': Number(gPerm.groupId), 'text':_.escape(gPerm.groupName)};
-			});
-			this.model.set('selectGroups', groupsNVList);
-
-			usersNVList = _.map(this.model.get('userPermList'),function(uPerm){
-				return {'id': Number(uPerm.userId), 'text':_.escape(uPerm.userName)};
-			});
-			this.model.set('selectUsers', usersNVList);
-
+                        this.addedGroups = _.map(this.model.get('groupPermList'), function(g){ return { 'id' : g.groupId, 'text' : g.groupName} });
+                        this.addedUsers = _.map(this.model.get('userPermList'), function(u){ return { 'id' : u.userId, 'text' : u.userName} });
 		},
 		getPermHeaders : function(){
 			var permList = [];
-			permList.unshift(localization.tt('lbl.allowAccess'));
-			permList.unshift(localization.tt('lbl.selectUser'));
-			permList.unshift(localization.tt('lbl.selectGroup'));
-//			permList.push("");
+                        permList.unshift(localization.tt('lbl.selectAndAddUser'));
+                        permList.unshift(localization.tt('lbl.selectAndAddGroup'));
 			return permList;
 		},
 		getPlugginAttr :function(autocomplete, options){
@@ -131,25 +147,7 @@ define(function(require) {
 				return {
 					closeOnSelect : true,
 					multiple: true,
-					minimumInputLength: 0,
 					tokenSeparators: [",", " "],
-					initSelection : function (element, callback) {
-						var data = [];
-						_.each(options.permList,function (elem) {
-							data.push({id: elem[options.idKey], text: _.escape(elem[options.textKey])});
-						});
-						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: options.lookupURL,
 						type : 'GET',
@@ -169,12 +167,12 @@ define(function(require) {
 							selectedVals = that.getSelectedValues(options);
 							if(data.resultSize != "0"){
 								if(!_.isUndefined(data.vXGroups)){
-									results = data.vXGroups.map(function(m, i){	return {id : m.id+"", text: _.escape(m.name) };	});
+                                                                        results = data.vXGroups.map(function(m, i){	return {id : m.id, text: _.escape(m.name) };	});
 								} else if(!_.isUndefined(data.vXUsers)){
-									results = data.vXUsers.map(function(m, i){	return {id : m.id+"", text: _.escape(m.name) };	});
-									if(!_.isEmpty(selectedVals)){
+                                                                        results = data.vXUsers.map(function(m, i){	return {id : m.id, text: _.escape(m.name) };	});
+                                                                }
+                                                                if(!_.isEmpty(selectedVals)){
 										results = XAUtil.filterResultByText(results, selectedVals);
-									}
 								}
 							}
 							return { results : results};
@@ -202,75 +200,130 @@ define(function(require) {
 		},
 		getSelectedValues : function(options){
 			var vals = [],selectedVals = [];
-			var type = options.textKey == 'groupName' ? 'selectGroups' : 'selectUsers';
-			var $select = this.$('[name="'+type+'"]');
-			if(!_.isEmpty($select.select2('data'))){
-				selectedVals = _.map($select.select2('data'),function(obj){ return obj.text; });
+                        var added = options.textKey == 'groupName' ? this.addedGroups : this.addedUsers;
+                        if(!_.isEmpty(added)){
+                                selectedVals = _.map(added, function(obj){ return obj.text; });
 			}
 			vals.push.apply(vals , selectedVals);
-			vals = $.unique(vals);
 			return vals;
 		},
 		beforeSaveModulePermissions : function(){
-			if(this.model.get('module') != ''){
-				var groupValStr = this.fields.selectGroups.getValue();
-				var userValStr = this.fields.selectUsers.getValue();
-				this.compareAndUpdateObj(groupValStr,{'mode':'groups','permList':this.model.get('groupPermList'),'idKey':'groupId','textKey':'groupName'});
-				this.compareAndUpdateObj(userValStr,{'mode':'users','permList':this.model.get('userPermList'),'idKey':'userId','textKey':'userName'});
+                        if(!_.isEmpty(this.fields.selectGroups.editor.$el.select2('data'))
+                                        || !_.isEmpty(this.fields.selectUsers.editor.$el.select2('data'))){
+                                XAUtil.alertPopup({
+                                        msg :localization.tt('msg.addSelectedUserGroup'),
+                                });
+                                return false;
 			}
+                        this.model.unset('selectUsers');
+                        this.model.unset('selectGroups');
+
 			return true;
 		},
-		compareAndUpdateObj: function(objValsStr,options){
+                onAddGroup : function(e){
+                        var that = this, newPerms = [];
+                        var selectedGroups = this.fields.selectGroups.editor.$el.select2('data');
+                        _.each(selectedGroups, function(obj){
+                                var self = that;
+                                this.$el.find('[data-js="selectedGroupList"]').append('<span class="selected-widget"  ><i class="icon remove icon-remove" data-js="selectedGroupIcon" data-id="'+obj.id+'"></i>&nbsp;'+obj.text+'</span>')
+                                this.addedGroups.push(obj)
+                                this.$el.find('[data-js="selectedGroupList"] :last').on('click',this.removeGroup.bind(this));
+                                this.fields.selectGroups.editor.$el.select2('data',[]);
+                                var addedGroupPerm =_.findWhere(this.model.get('groupPermList'), {'groupId': parseInt(obj.id) });
+                                if(!_.isUndefined(addedGroupPerm)){
+                                        addedGroupPerm.isAllowed = XAEnums.AccessResult.ACCESS_RESULT_ALLOWED.value;
+                                }else{
+                                        var perm = {};
+                                        perm['moduleId'] = that.model.get('id');
+                                        perm['groupId'] = obj['id'];
+                                        perm.isAllowed = XAEnums.AccessResult.ACCESS_RESULT_ALLOWED.value;
+                                        newPerms.push(perm);
+                                }
+                        }, this);
+                        if(!_.isEmpty(newPerms)){
+                                var permissions = this.model.get('groupPermList');
+                                this.model.set('groupPermList', permissions.concat(newPerms));
+                        }
+
+                        this.emptyCheck();
+                        if(_.isEmpty(selectedGroups))	alert(localization.tt("msg.pleaseSelectGroup"));
+                        return false;
 
-			var selectedVals = (!_.isNull(objValsStr)) ? objValsStr.toString().split(',') : [];
-			var selectedIdList=[];
-			selectedVals = _.each(selectedVals, function(eachVal){
-				//Ignoring any non existing Group Name
-				if(_.isNumber(parseInt(eachVal))  && !_.isNaN(parseInt(eachVal))){
-					selectedIdList.push(Number(eachVal));
+                },
+
+                removeGroup : function(e){
+                        var ele = $(e.currentTarget);
+                        var id = ele.attr('data-id');
+                        ele.parent().remove();
+                        this.addedGroups = _.reject(this.addedGroups, function(d){ return d.id == id; });
+                        var removedGroupPerm =_.findWhere(this.model.get('groupPermList'), {'groupId': parseInt(id) });
+                        if(!_.isUndefined(removedGroupPerm)){
+                                if(!_.has(removedGroupPerm, 'id')){
+                                        this.model.set('groupPermList', _.reject(this.model.get('groupPermList'), function(perm){ return perm.groupId == removedGroupPerm.groupId }));
+                                }else{
+                                        removedGroupPerm.isAllowed = XAEnums.AccessResult.ACCESS_RESULT_DENIED.value;
 				}
-			});
-			var modelPermList = options.permList;
-			var modelPerms = _.unique(_.pluck(options.permList, options.idKey));
-			if(!_.isEmpty(selectedIdList)){
-				//Look for equals
-				if(_.isEqual(selectedIdList,modelPerms)) {
-					//No changes in Selected Users
-				} else {
-					//look for new values -
-					//loop through each new element and check if it has any non matching ids
-					var diff = _.filter(selectedIdList, function(value){ return !_.contains(modelPerms, value); });
-					var that = this;
-					if(!_.isEmpty(diff)){
-						//push new elements to model groupPermList
-						_.each(diff, function(newEl){
-							var newObj = {};
-							newObj[options.idKey] = newEl;
-							newObj['moduleId'] = that.model.get('id');
-							newObj['isAllowed'] = 1;
-							options.permList.push(newObj);
-						});
-					}
-					//Look for removed users/groups
-					//loop through each model element and check new selected groups is missing from any original list  of group ids
-					var updDiff = _.filter(modelPerms, function(value){ return !_.contains(selectedIdList, value); });
-					if(!_.isEmpty(updDiff)){
-						_.each(options.permList, function(origElem){
-							if(_.contains(updDiff, origElem[options.idKey]))
-								origElem.isAllowed = 0;
-						});
-					}
+                        }
+                        this.emptyCheck();
+                },
+                onAddUser : function(e){
+                        var that = this, newPerms = [];
+                        var selectedUsers = this.fields.selectUsers.editor.$el.select2('data');
+                        _.each(selectedUsers, function(obj){
+                                var self = that;
+                                this.$el.find('[data-js="selectedUserList"]').append('<span class="selected-widget"  ><i class="icon remove icon-remove" data-js="selectedUserIcon" data-id="'+obj.id+'"></i>&nbsp;'+obj.text+'</span>')
+                                this.addedUsers.push(obj)
+                                this.$el.find('[data-js="selectedUserList"] :last').on('click',this.removeUser.bind(this));
+                                this.fields.selectUsers.editor.$el.select2('data', []);
+                                var addedUserPerm =_.findWhere(this.model.get('userPermList'), {'userId': parseInt(obj.id) });
+                                if(!_.isUndefined(addedUserPerm)){
+                                        addedUserPerm.isAllowed = XAEnums.AccessResult.ACCESS_RESULT_ALLOWED.value;
+                                }else{
+                                        var perm = {};
+                                        perm['moduleId'] = that.model.get('id');
+                                        perm['userId'] = obj['id'];
+                                        perm.isAllowed = XAEnums.AccessResult.ACCESS_RESULT_ALLOWED.value;
+                                        newPerms.push(perm);
 				}
-
-			} else {
-				//Remove permissions from all objects which earlier had permission
-				_.each(options.permList, function(perm){
-					perm.isAllowed = 0;
-				});
+                        }, this);
+                        if(!_.isEmpty(newPerms)){
+                                var permissions = this.model.get('userPermList');
+                                this.model.set('userPermList', permissions.concat(newPerms));
+                        }
+                        this.emptyCheck();
+                        if(_.isEmpty(selectedUsers))	alert(localization.tt("msg.pleaseSelectUser"));
+                        return false;
+                },
+                removeUser : function(e){
+                        var ele = $(e.currentTarget);
+                        var id = ele.attr('data-id');
+                        ele.parent().remove();
+                        this.addedUsers = _.reject(this.addedUsers, function(d){ return d.id == id; });
+                        var removedUserPerm =_.findWhere(this.model.get('userPermList'), {'userId': parseInt(id) });
+                        if(!_.isUndefined(removedUserPerm)){
+                                if(!_.has(removedUserPerm, 'id')){
+                                        this.model.set('userPermList', _.reject(this.model.get('userPermList'), function(perm){ return perm.userId == removedUserPerm.userId }));
+                                }else{
+                                        removedUserPerm.isAllowed = XAEnums.AccessResult.ACCESS_RESULT_DENIED.value;
+                                }
+                        }
+                        this.emptyCheck();
+                },
+                emptyCheck : function(type){
+                        if(this.$el.find('[data-js="selectedGroupList"] span').length > 0){
+                                this.$el.find('.emptySelectedGroups').hide();
+                        }else{
+                                this.$el.find('.emptySelectedGroups').show();
 			}
 
+                        if(this.$el.find('[data-js="selectedUserList"] span').length > 0){
+                                this.$el.find('.emptySelectedUsers').hide();
+                        }else{
+                                this.$el.find('.emptySelectedUsers').show();
+                        }
 		}
+
 	});
 	
 	return ModulePermissionForm;
-});
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/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 264e0ea..7d86dfa 100644
--- a/security-admin/src/main/webapp/styles/xa.css
+++ b/security-admin/src/main/webapp/styles/xa.css
@@ -2054,4 +2054,25 @@ td.subgrid-custom-cell{
 }
 .VS-search .search_facet_input_container{
 	margin-top: 1px;
+}
+.selected-widget {
+    padding: 3px 5px 3px 4px;
+    border-radius: 3px;
+    border: 1px solid #aaaaaa;
+    background-color: #e4e4e4;
+    margin: 3px 3px;
+    float: left;
+}
+.selected-list {
+    margin: 5px;
+    max-height: 270px;
+    overflow: auto;
+}
+
+.inline {
+    display: inline;
+}
+.vertAlignInitial{
+        vertical-align: initial !important;
+        text-align: left;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ebcf9dd5/security-admin/src/main/webapp/templates/permissions/ModulePermissionForm_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/permissions/ModulePermissionForm_tmpl.html b/security-admin/src/main/webapp/templates/permissions/ModulePermissionForm_tmpl.html
index 1bf096b..909d2fc 100644
--- a/security-admin/src/main/webapp/templates/permissions/ModulePermissionForm_tmpl.html
+++ b/security-admin/src/main/webapp/templates/permissions/ModulePermissionForm_tmpl.html
@@ -16,7 +16,7 @@
 --}}
 <form class="form-horizontal">
 	<fieldset>
-		<p class="formHeader"> Policy Details : </p>
+                <p class="formHeader"> Module Details : </p>
 	<div class="clearfix"></div>
 	<b class="policy-form">
 		<fieldset>
@@ -35,21 +35,48 @@
 					<thead>
 						<tr>
 							{{#each permHeaders}}
-							<th>{{./this}}</th>
+                                                        <th width="49%">{{./this}}</th>
 							{{/each}}
 						</tr>
 					</thead>
 					<tbody class="js-formInput">
 						<tr>
 							<td>
-								<div data-editors="selectGroups"></div>
+                                                                <div data-editors="selectGroups" class="inline"></div>
+                                                                <button data-id="addGroupBtn" class="icon icon-plus icon-2x btn btn-default" title="Add Group"></button>
 							</td>
 							<td>
-								<div data-editors="selectUsers"></div>
-							</td>
-							<td>
-								<div data-editors="isAllowed"></div>
+                                                                <div data-editors="selectUsers" class="inline"></div>
+                                                                <button data-id="addUserBtn" class="icon icon-plus icon-2x btn btn-default" title="Add User"></button>
+
 							</td>
+                                                        <!--<td>
+                                                                 <div data-editors="isAllowed"></div>
+                                                        </td>-->
+                                                </tr>
+                                                <tr>
+                                                        <td  class="vertAlignInitial">
+                                                                <div class="selected-list clearfix" data-js="selectedGroupList">
+                                                                <label class="editable-empty emptySelectedGroups">No Selected Groups</label>
+                                                                {{#each groupList}}
+                                                                        <span class="selected-widget">
+                                                                                <i class="icon remove icon-remove" data-id="{{./this.groupId}}"></i>&nbsp;
+                                                                                {{./this.groupName}}
+                                                                        </span>
+                                                                {{/each}}
+
+                                                                </div></td>
+                                                                <td class="vertAlignInitial" width="100%">
+                                                                <div class="selected-list clearfix" data-js="selectedUserList">
+                                                                        <label class="editable-empty emptySelectedUsers" style="text-align: center;">No Selected Users</label>
+
+                                                                        {{#each userList}}
+                                                                        <span class="selected-widget">
+                                                                                <i class="icon remove icon-remove" data-id="{{./this.userId}}"></i>&nbsp;
+                                                                                {{./this.userName}}
+                                                                        </span>
+                                                                {{/each}}
+                                                                </div></td>
 						</tr>
 					</tbody>
 				</table>