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/21 13:36: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/ranger-0.6 f2990fe78 -> d6308e68a


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/d6308e68
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/d6308e68
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/d6308e68

Branch: refs/heads/ranger-0.6
Commit: d6308e68ad66211731f7d3949f5b219d7ba015cc
Parents: f2990fe
Author: pradeep agrawal <pr...@freestoneinfotech.com>
Authored: Tue Dec 20 19:31:01 2016 +0530
Committer: Gautam Borad <ga...@apache.org>
Committed: Wed Dec 21 19:05:46 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 +-
 .../scripts/modules/globalize/message/en.js     |   9 +-
 .../src/main/webapp/scripts/utils/XAUtils.js    |  34 +--
 .../views/permissions/ModulePermissionCreate.js |  22 +-
 .../views/permissions/ModulePermissionForm.js   | 259 +++++++++++--------
 .../views/permissions/ModulePermsTableLayout.js |  20 +-
 .../scripts/views/policies/PermissionList.js    |   5 +-
 security-admin/src/main/webapp/styles/xa.css    |  23 ++
 .../permissions/ModulePermissionForm_tmpl.html  |  41 ++-
 15 files changed, 394 insertions(+), 182 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d6308e68/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 6dc1e2f..e62fc87 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
@@ -842,18 +842,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/d6308e68/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/d6308e68/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 19c3d19..5c5d59a 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/d6308e68/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/d6308e68/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/d6308e68/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 8210650..813079f 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/d6308e68/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/d6308e68/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 de12935..fb7a326 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
@@ -233,7 +233,9 @@ define(function(require) {
 				componentPermissions			: 'Component Permissions',
 				selectDataMaskTypes				: 'Select Data Mask Types',
 				accessTypes						: 'Access Types',
-				rowLevelFilter					: 'Row Level Filter'
+                                rowLevelFilter					: 'Row Level Filter',
+                                selectAndAddUser                : 'Select and Add User',
+                                selectAndAddGroup               : 'Select and Add Group',
 			},
 			btn : {
 				add							: 'Add',
@@ -338,7 +340,10 @@ define(function(require) {
 				grpUpdatedSucc            : 'Group updated successfully',
 				grpCreatedSucc            : 'Group created successfully',
 				errorLoadingAuditLogs	  : 'Unable to connect to Audit store !!',
-				enterCustomMask			  : 'Please enter custom masked value or expression !!'
+                                enterCustomMask			  : 'Please enter custom masked value or expression !!',
+                                pleaseSelectUser          : 'Please select user.',
+                                pleaseSelectGroup         : 'Please select group.',
+                                addSelectedUserGroup      : 'Please add selected user/group to permissions else user/group will not be added.'
 				
 				
 				

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d6308e68/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 05733f8..b776e8d 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
@@ -521,24 +521,29 @@ define(function(require) {
 	};
 
 	XAUtils.showGroupsOrUsers = function(rawValue, model, userOrGroups) {
-		var showMoreLess = false, objArr = [];
+                var showMoreLess = false, objArr, lastShowMoreCnt = 1, j = 1, listShownCnt = 5000;
 		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
-						+ '-id="' + model.id + '" style="display:none;">'
-						+ name + '</span>';
+                                var eleStr = '', span = '<span class="label label-info float-left-margin-2" policy-' + userOrGroups
+                                        + '-id="' + model.id +'">'
+                                        +  _.escape(name) + '</span>';
+                                if( (i + listShownCnt ) === (listShownCnt*j) + 4){
+                                        eleStr = '<div data-id="moreSpans" style="display:none;">'+span;
+                                        if(i == objArr.length - 1){
+                                                eleStr += '</div>';
+                                        }
+                                        lastShowMoreCnt = ( listShownCnt*j ) + 4;
+                                        j++;
+                                }else if(i === lastShowMoreCnt - 1 || i == objArr.length - 1){
+                                        eleStr = span + '</div>';
+
+                                }else{
+                                        eleStr = span;
+                                }
+                                return eleStr;
 			} else if (i == 3 && objArr.length > 4) {
 				showMoreLess = true;
 				return '<span class="label label-info float-left-margin-2" policy-' + userOrGroups
@@ -563,7 +568,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/d6308e68/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/d6308e68/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..76154a9 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,34 @@ 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 +95,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 : {
@@ -98,29 +112,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 +144,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,13 +164,15 @@ 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) };	});
-								} else if(!_.isUndefined(data.vXUsers)){
-									results = data.vXUsers.map(function(m, i){	return {id : m.id+"", text: _.escape(m.name) };	});
-									if(!_.isEmpty(selectedVals)){
-										results = XAUtil.filterResultByText(results, selectedVals);
-									}
+                                                                        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 = XAUtil.filterResultByText(results, selectedVals);
+                                                                }
+
 							}
 							return { results : results};
 						},
@@ -195,80 +192,136 @@ define(function(require) {
 						return result.text;
 					},
 					formatNoMatches : function(term){
-						return options.textKey == 'groupName' ?  'No group found.' : 'No user found.'; 
+                                                switch (term){
+                                                        default : return "No Matches found";
+                                                }
 					}
 				};
 			}
 		},
 		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);
 				}
+                        }, 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();
+                        }
 
-			} else {
-				//Remove permissions from all objects which earlier had permission
-				_.each(options.permList, function(perm){
-					perm.isAllowed = 0;
-				});
+                        if(this.$el.find('[data-js="selectedUserList"] span').length > 0){
+                                this.$el.find('.emptySelectedUsers').hide();
+                        }else{
+                                this.$el.find('.emptySelectedUsers').show();
 			}
-
 		}
 	});
 	

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d6308e68/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js
index 76dc027..92c07c7 100644
--- a/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js
+++ b/security-admin/src/main/webapp/scripts/views/permissions/ModulePermsTableLayout.js
@@ -184,9 +184,21 @@ define(function(require){
 				attrName = 'policy-users-id';
 			}
 			var $td = $(e.currentTarget).parents('td');
-			$td.find('['+attrName+'="'+id+'"]').show();
-			$td.find('[data-id="showLess"]['+attrName+'="'+id+'"]').show();
-			$td.find('[data-id="showMore"]['+attrName+'="'+id+'"]').hide();
+                        var show = false, shownCnt = 1;
+                        $.each($td.find('[data-id="moreSpans"]'), function(i, div){
+                                if($(div).is(':hidden') && !show){
+                                        $(div).show();
+                                        show = true;
+                                        return false;
+                                }
+                                if(!$(div).is(':hidden')){
+                                        shownCnt++;
+                                }
+                        })
+                        if($td.find('[data-id="moreSpans"]').length == shownCnt){
+                                $td.find('[data-id="showLess"]['+attrName+'="'+id+'"]').show();
+                                $td.find('[data-id="showMore"]['+attrName+'="'+id+'"]').hide();
+                        }
 			$td.find('[data-id="showMore"]['+attrName+'="'+id+'"]').parents('div[data-id="groupsDiv"]').addClass('set-height-groups');
 		},
 		onShowLess : function(e){
@@ -197,7 +209,7 @@ define(function(require){
 				attrName = 'policy-users-id';
 			}
 			var $td = $(e.currentTarget).parents('td');
-			$td.find('['+attrName+'="'+id+'"]').slice(4).hide();
+                        $td.find('[data-id="moreSpans"]').hide();
 			$td.find('[data-id="showLess"]['+attrName+'="'+id+'"]').hide();
 			$td.find('[data-id="showMore"]['+attrName+'="'+id+'"]').show();
 			$td.find('[data-id="showMore"]['+attrName+'="'+id+'"]').parents('div[data-id="groupsDiv"]').removeClass('set-height-groups');

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d6308e68/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
index d5631e0..6a61f55 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
@@ -472,10 +472,11 @@ define(function(require) {
 									val = 	pcond['evaluatorOptions']['engineName'] + ' Condition'
 								}
 								i++;
-								return '<span class="'+label+' white-space-normal" >'+name+' : '+ val + '</span>';
+                                                                return '<span class="'+label+' white-space-normal" >'+name+' : '+ _.escape(val) + '</span>';
 							});
 							var cond = _.map(value, function(val, name) {
-								return {'type' : name, 'values' : !_.isArray(val) ?  val.split(', ') : val};
+                                                                val = _.escape(val);
+                                                                return {'type' : name, 'values' : !_.isArray(val) ?  val.split(',') : val};
 							});
 							
 							that.model.set('conditions', cond);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d6308e68/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 9dbed64..13b1839 100644
--- a/security-admin/src/main/webapp/styles/xa.css
+++ b/security-admin/src/main/webapp/styles/xa.css
@@ -2026,4 +2026,27 @@ td.subgrid-custom-cell{
 }
 .customMask{
 	width: 95px;
+}
+.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;
+}
+.selected-widget .remove{
+        cursor:pointer;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d6308e68/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..34cb017 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>