Repository: incubator-ranger
Updated Branches:
  refs/heads/master 4434e4d3c -> 2a309b5c1


RANGER-244-Provide-support-to-Show-Hide-Users-Revised

Signed-off-by: Velmurugan Periasamy <[email protected]>


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

Branch: refs/heads/master
Commit: 2a309b5c1a44de97cae1657278407037d0f33054
Parents: 4434e4d
Author: Gautam Borad <[email protected]>
Authored: Wed Mar 4 19:23:50 2015 +0530
Committer: Velmurugan Periasamy <[email protected]>
Committed: Mon Mar 9 10:59:49 2015 -0400

----------------------------------------------------------------------
 .../patches/010-users-and-groups-visibility.sql |  50 ++++
 .../patches/010-users-and-groups-visibility.sql |  44 ++++
 .../java/org/apache/ranger/biz/XUserMgr.java    |  31 +++
 .../apache/ranger/common/RangerCommonEnums.java |  22 +-
 .../java/org/apache/ranger/entity/XXGroup.java  |  26 ++
 .../java/org/apache/ranger/entity/XXUser.java   |  29 ++
 .../java/org/apache/ranger/rest/XUserREST.java  |  18 ++
 .../apache/ranger/service/XGroupService.java    |  17 +-
 .../ranger/service/XGroupServiceBase.java       |   2 +
 .../org/apache/ranger/service/XUserService.java |   4 +
 .../apache/ranger/service/XUserServiceBase.java |   2 +
 .../java/org/apache/ranger/view/VXGroup.java    |  21 ++
 .../java/org/apache/ranger/view/VXUser.java     |  12 +-
 .../scripts/collection_bases/VXGroupListBase.js |  26 +-
 .../scripts/collection_bases/VXUserListBase.js  |  23 +-
 .../src/main/webapp/scripts/models/VXGroup.js   |  15 +-
 .../src/main/webapp/scripts/models/VXUser.js    |  14 +
 .../main/webapp/scripts/modules/XAOverrides.js  | 263 +++++++++++++++++++
 .../scripts/modules/globalize/message/en.js     |  10 +-
 .../src/main/webapp/scripts/utils/XAEnums.js    |   5 +
 .../src/main/webapp/scripts/utils/XAUtils.js    |   1 +
 .../scripts/views/common/FormInputItemList.js   |   2 +-
 .../scripts/views/common/UserPermissionList.js  |   2 +-
 .../scripts/views/common/XATableLayout.js       |   7 +
 .../scripts/views/policies/PermissionList.js    |   4 +-
 .../scripts/views/policies/RangerPolicyForm.js  |   2 +-
 .../scripts/views/users/UserTableLayout.js      | 157 ++++++++++-
 security-admin/src/main/webapp/styles/xa.css    |  15 ++
 .../templates/users/UserTableLayout_tmpl.html   |   2 +
 .../org/apache/ranger/biz/TestXUserMgr.java     | 175 +++++++++++-
 30 files changed, 959 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/db/mysql/patches/010-users-and-groups-visibility.sql
----------------------------------------------------------------------
diff --git 
a/security-admin/db/mysql/patches/010-users-and-groups-visibility.sql 
b/security-admin/db/mysql/patches/010-users-and-groups-visibility.sql
new file mode 100644
index 0000000..6d954ee
--- /dev/null
+++ b/security-admin/db/mysql/patches/010-users-and-groups-visibility.sql
@@ -0,0 +1,50 @@
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements.  See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License.  You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+drop procedure if exists add_is_visible_column_to_x_user_table;
+delimiter ;;
+ create procedure add_is_visible_column_to_x_user_table() begin
+ 
+/* add is visible column in x_user table if not exist */
+ if exists (select * from information_schema.columns where 
table_schema=database() and table_name = 'x_user') then
+       if not exists (select * from information_schema.columns where 
table_schema=database() and table_name = 'x_user' and column_name = 
'is_visible') then
+               ALTER TABLE `x_user` ADD `is_visible` INT(11) NOT NULL DEFAULT 
'1';
+       end if;
+ end if; 
+end;;
+
+delimiter ;
+
+call add_is_visible_column_to_x_user_table();
+
+drop procedure if exists add_is_visible_column_to_x_user_table;
+
+drop procedure if exists add_is_visible_column_to_x_group_table;
+delimiter ;;
+ create procedure add_is_visible_column_to_x_group_table() begin
+ 
+/* add is visible column in x_group table if not exist */
+ if exists (select * from information_schema.columns where 
table_schema=database() and table_name = 'x_group') then
+       if not exists (select * from information_schema.columns where 
table_schema=database() and table_name = 'x_group' and column_name = 
'is_visible') then
+               ALTER TABLE `x_group` ADD `is_visible` INT(11) NOT NULL DEFAULT 
'1';
+       end if;
+ end if; 
+end;;
+
+delimiter ;
+
+call add_is_visible_column_to_x_group_table();
+
+drop procedure if exists add_is_visible_column_to_x_group_table;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/db/oracle/patches/010-users-and-groups-visibility.sql
----------------------------------------------------------------------
diff --git 
a/security-admin/db/oracle/patches/010-users-and-groups-visibility.sql 
b/security-admin/db/oracle/patches/010-users-and-groups-visibility.sql
new file mode 100644
index 0000000..38dc8e4
--- /dev/null
+++ b/security-admin/db/oracle/patches/010-users-and-groups-visibility.sql
@@ -0,0 +1,44 @@
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements.  See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License.  You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DECLARE
+       v_column_exists number := 0;
+BEGIN
+  Select count(*) into v_column_exists
+    from user_tab_cols
+    where column_name = upper('is_visible')
+      and table_name = upper('x_user');
+
+  if (v_column_exists = 0) then
+      execute immediate 'ALTER TABLE x_user ADD is_visible NUMBER(11) DEFAULT 
1 NOT NULL';
+      commit;
+  end if;
+end;
+/
+
+DECLARE
+       v_column_exists number := 0;
+BEGIN
+  Select count(*) into v_column_exists
+    from user_tab_cols
+    where column_name = upper('is_visible')
+      and table_name = upper('x_group');
+
+  if (v_column_exists = 0) then
+      execute immediate 'ALTER TABLE x_group ADD is_visible NUMBER(11) DEFAULT 
1 NOT NULL';
+      commit;
+  end if;
+end;
+/

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/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 fa03f2f..3c6ef3e 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
@@ -20,11 +20,18 @@
  package org.apache.ranger.biz;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
 import org.apache.log4j.Logger;
 import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.common.PropertiesUtil;
@@ -35,6 +42,8 @@ import org.apache.ranger.db.XXGroupUserDao;
 import org.apache.ranger.entity.XXGroup;
 import org.apache.ranger.entity.XXPortalUser;
 import org.apache.ranger.entity.XXTrxLog;
+import org.apache.ranger.entity.XXUser;
+import org.apache.ranger.service.XGroupService;
 import org.apache.ranger.service.XUserService;
 import org.apache.ranger.view.VXGroup;
 import org.apache.ranger.view.VXGroupList;
@@ -63,6 +72,9 @@ public class XUserMgr extends XUserMgrBase {
 
        @Autowired
        RangerBizUtil xaBizUtil;
+       
+       @Autowired
+       XGroupService xGroupService;
 
        static final Logger logger = Logger.getLogger(XUserMgr.class);
 
@@ -472,4 +484,23 @@ public class XUserMgr extends XUserMgrBase {
                return vXGroup;
        }
 
+       public void modifyUserVisibility(HashMap<Long, Integer> visibilityMap) 
{                        
+               Set<Long> keys = visibilityMap.keySet();
+               for (Long key : keys) {
+                       XXUser xUser = daoManager.getXXUser().getById(key);
+                       VXUser vObj = xUserService.populateViewBean(xUser);
+                       vObj.setIsVisible(visibilityMap.get(key));
+                       vObj = xUserService.updateResource(vObj);
+               }
+       }
+       
+       public void modifyGroupsVisibility(HashMap<Long, Integer> 
groupVisibilityMap) {                 
+               Set<Long> keys = groupVisibilityMap.keySet();
+               for (Long key : keys) {         
+                       XXGroup xGroup = daoManager.getXXGroup().getById(key);
+                       VXGroup vObj = xGroupService.populateViewBean(xGroup);
+                       vObj.setIsVisible(groupVisibilityMap.get(key));
+                       vObj = xGroupService.updateResource(vObj);
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/common/RangerCommonEnums.java
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/java/org/apache/ranger/common/RangerCommonEnums.java 
b/security-admin/src/main/java/org/apache/ranger/common/RangerCommonEnums.java
index 33edc28..c02998d 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/common/RangerCommonEnums.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/common/RangerCommonEnums.java
@@ -27,6 +27,18 @@
 public class RangerCommonEnums {
 
        /***************************************************************
+        * Enum values for VisibilityStatus
+        **************************************************************/
+       /**
+        * IS_VISIBLE is an element of enum VisibilityStatus. Its value is 
"IS_VISIBLE".
+        */
+       public static final int IS_VISIBLE = 1;
+       /**
+        * IS_HIDDEN is an element of enum VisibilityStatus. Its value is 
"IS_HIDDEN".
+        */
+       public static final int IS_HIDDEN = 0;
+
+       /***************************************************************
         * Enum values for ActiveStatus
         **************************************************************/
        /**
@@ -884,7 +896,15 @@ public class RangerCommonEnums {
         */
        public static final int ClassTypes_MAX = 1012;
 
-
+       static public String getLabelFor_VisibilityStatus( int elementValue ) {
+               if( elementValue == 0 ) {
+                       return "Hidden"; //IS_HIDDEN
+               }
+               if( elementValue == 1 ) {
+                       return "Visible"; //IS_VISIBLE
+               }
+               return null;
+       }
 
        static public String getLabelFor_ActiveStatus( int elementValue ) {
                if( elementValue == 0 ) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/entity/XXGroup.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXGroup.java 
b/security-admin/src/main/java/org/apache/ranger/entity/XXGroup.java
index 4224cc4..a31ea7b 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXGroup.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXGroup.java
@@ -86,6 +86,16 @@ public class XXGroup extends XXDBBase implements 
java.io.Serializable {
         */
        @Column(name="STATUS"  , nullable=false )
        protected int status = RangerConstants.STATUS_DISABLED;
+       
+       /**
+        * IsVisible
+        * <ul>
+        * <li>This attribute is of type enum CommonEnums::ActiveVisiblility
+        * </ul>
+        *
+        */
+       @Column(name="IS_VISIBLE"  , nullable=false )
+       protected Integer isVisible ;
 
        /**
         * Type of group
@@ -117,6 +127,7 @@ public class XXGroup extends XXDBBase implements 
java.io.Serializable {
                status = RangerConstants.STATUS_DISABLED;
                groupType = AppConstants.XA_GROUP_UNKNOWN;
                groupSource = RangerCommonEnums.GROUP_INTERNAL;
+               isVisible = RangerCommonEnums.IS_VISIBLE;
        }
 
        @Override
@@ -181,6 +192,20 @@ public class XXGroup extends XXDBBase implements 
java.io.Serializable {
        }
 
        /**
+        * @return the isVisible
+        */
+       public Integer getIsVisible() {
+               return isVisible;
+       }
+       
+       /**
+        * @param isVisible the isVisible to set
+        */
+       public void setIsVisible(Integer isVisible) {
+               this.isVisible = isVisible;
+       }
+       
+       /**
         * This method sets the value to the member attribute <b>groupType</b>.
         * You cannot set null to the attribute.
         * @param groupType Value to set member attribute <b>groupType</b>
@@ -227,6 +252,7 @@ public class XXGroup extends XXDBBase implements 
java.io.Serializable {
                str += "name={" + name + "} ";
                str += "description={" + description + "} ";
                str += "status={" + status + "} ";
+               str += "isvisible={" + isVisible + "} ";
                str += "groupType={" + groupType + "} ";
                str += "credStoreId={" + credStoreId + "} ";
                str += "groupSrc={" + groupSource + "} ";

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/entity/XXUser.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXUser.java 
b/security-admin/src/main/java/org/apache/ranger/entity/XXUser.java
index af339d2..d6416ba 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXUser.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXUser.java
@@ -34,6 +34,7 @@ import javax.persistence.Table;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.ranger.common.AppConstants;
+import org.apache.ranger.common.RangerCommonEnums;
 import org.apache.ranger.common.RangerConstants;
 
 
@@ -88,6 +89,15 @@ public class XXUser extends XXDBBase implements 
java.io.Serializable {
        protected int status = RangerConstants.STATUS_DISABLED;
 
        /**
+        * Status
+        * <ul>
+        * <li>This attribute is of type enum CommonEnums::ActiveStatus
+        * </ul>
+        *
+        */
+       @Column(name="IS_VISIBLE"  , nullable=false )
+       protected Integer isVisible ;
+       /**
         * Id of the credential store
         * <ul>
         * </ul>
@@ -102,6 +112,7 @@ public class XXUser extends XXDBBase implements 
java.io.Serializable {
         */
        public XXUser ( ) {
                status = RangerConstants.STATUS_DISABLED;
+               isVisible = RangerCommonEnums.IS_VISIBLE;
        }
 
        @Override
@@ -166,6 +177,23 @@ public class XXUser extends XXDBBase implements 
java.io.Serializable {
        }
 
        /**
+        * This method sets the value to the member attribute <b>isVisible</b>.
+        * You cannot set null to the attribute.
+        * @param status Value to set member attribute <b>isVisible</b>
+        */
+       public void setIsVisible(Integer isVisible) {
+               this.isVisible = isVisible;
+       }
+       
+       /**
+        * Returns the value for the member attribute <b>isVisible</b>
+        * @return int - value of member attribute <b>isVisible</b>.
+        */
+       public Integer getIsVisible() {
+               return isVisible;
+       }
+       
+       /**
         * This method sets the value to the member attribute 
<b>credStoreId</b>.
         * You cannot set null to the attribute.
         * @param credStoreId Value to set member attribute <b>credStoreId</b>
@@ -194,6 +222,7 @@ public class XXUser extends XXDBBase implements 
java.io.Serializable {
                str += "name={" + name + "} ";
                str += "description={" + description + "} ";
                str += "status={" + status + "} ";
+               str += "isvisible={" + isVisible + "} ";
                str += "credStoreId={" + credStoreId + "} ";
                str += "}";
                return str;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java 
b/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
index 9ebdd63..beb4829 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
@@ -19,6 +19,9 @@
 
  package org.apache.ranger.rest;
 
+import java.util.HashMap;
+import java.util.List;
+
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -156,6 +159,12 @@ public class XUserREST {
                return xUserMgr.updateXGroup(vXGroup);
        }
 
+       @PUT
+       @Path("/secure/groups/visibility")
+       @Produces({ "application/xml", "application/json" })
+       public void modifyGroupsVisibility(HashMap<Long, Integer> 
groupVisibilityMap){
+                xUserMgr.modifyGroupsVisibility(groupVisibilityMap);
+       }
        
        @DELETE
        @Path("/groups/{id}")
@@ -181,6 +190,7 @@ public class XUserREST {
                                request, xGroupService.sortFields);
                searchUtil.extractString(request, searchCriteria, "name", 
"group name", 
                                StringUtil.VALIDATION_NAME);
+               searchUtil.extractInt(request, searchCriteria, "isVisible", 
"Group Visibility");
                searchUtil.extractString(request, searchCriteria, 
"groupSource", "group source", 
                                StringUtil.VALIDATION_NAME);
                return xUserMgr.searchXGroups(searchCriteria);
@@ -246,6 +256,13 @@ public class XUserREST {
                return xUserMgr.updateXUser(vXUser);
        }
 
+       @PUT
+       @Path("/secure/users/visibility")
+       @Produces({ "application/xml", "application/json" })
+       public void modifyUserVisibility(HashMap<Long, Integer> visibilityMap){
+                xUserMgr.modifyUserVisibility(visibilityMap);
+       }
+
        @DELETE
        @Path("/users/{id}")
        @PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
@@ -274,6 +291,7 @@ public class XUserREST {
                searchUtil.extractString(request, searchCriteria, 
"emailAddress", "Email Address",
                                null);          
                searchUtil.extractInt(request, searchCriteria, "userSource", 
"User Source");
+               searchUtil.extractInt(request, searchCriteria, "isVisible", 
"User Visibility");
                searchUtil.extractString(request, searchCriteria, 
"userRoleList", "User Role",
                                null);
                return xUserMgr.searchXUsers(searchCriteria);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/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 6a45555..580c31c 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
@@ -36,8 +36,10 @@ import org.apache.ranger.entity.XXAsset;
 import org.apache.ranger.entity.XXGroup;
 import org.apache.ranger.entity.XXPortalUser;
 import org.apache.ranger.entity.XXTrxLog;
+import org.apache.ranger.entity.XXUser;
 import org.apache.ranger.util.RangerEnumUtil;
 import org.apache.ranger.view.VXGroup;
+import org.apache.ranger.view.VXUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
@@ -68,9 +70,13 @@ public class XGroupService extends 
XGroupServiceBase<XXGroup, VXGroup> {
                                SearchField.DATA_TYPE.STRING, 
SearchField.SEARCH_TYPE.PARTIAL));
                searchFields.add(new SearchField("groupSource", 
"obj.groupSource",
                                SearchField.DATA_TYPE.STRING, 
SearchField.SEARCH_TYPE.FULL));
+
+               searchFields.add(new SearchField("isVisible", "obj.isVisible",
+                               SearchField.DATA_TYPE.INTEGER, 
SearchField.SEARCH_TYPE.FULL ));
+
                 createdByUserId = new Long(PropertiesUtil.getIntProperty(
-                               "xa.xuser.createdByUserId", 1));                
 
-               
+                               "xa.xuser.createdByUserId", 1));
+
                 sortFields.add(new SortField("name", 
"obj.name",true,SortField.SORT_ORDER.ASC));
        }
 
@@ -234,6 +240,13 @@ public class XGroupService extends 
XGroupServiceBase<XXGroup, VXGroup> {
        }
        
        @Override
+       public VXGroup populateViewBean(XXGroup xGroup) {
+               VXGroup vObj = super.populateViewBean(xGroup);
+               vObj.setIsVisible(xGroup.getIsVisible());
+               return vObj;
+       }
+       
+       @Override
        protected XXGroup mapViewToEntityBean(VXGroup vObj, XXGroup mObj, int 
OPERATION_CONTEXT) {
                super.mapViewToEntityBean(vObj, mObj, OPERATION_CONTEXT);
                return mObj;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java 
b/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java
index c3eebc0..68df919 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java
@@ -43,6 +43,7 @@ public abstract class XGroupServiceBase<T extends XXGroup, V 
extends VXGroup>
        @Override
        protected XXGroup mapViewToEntityBean(VXGroup vObj, XXGroup mObj, int 
OPERATION_CONTEXT) {
                mObj.setName( vObj.getName());
+               mObj.setIsVisible(vObj.getIsVisible());
                mObj.setDescription( vObj.getDescription());
                mObj.setGroupType( vObj.getGroupType());
                mObj.setCredStoreId( vObj.getCredStoreId());
@@ -53,6 +54,7 @@ public abstract class XGroupServiceBase<T extends XXGroup, V 
extends VXGroup>
        @Override
        protected VXGroup mapEntityToViewBean(VXGroup vObj, XXGroup mObj) {
                vObj.setName( mObj.getName());
+               vObj.setIsVisible( mObj.getIsVisible());
                vObj.setDescription( mObj.getDescription());
                vObj.setGroupType( mObj.getGroupType());
                vObj.setCredStoreId( mObj.getCredStoreId());

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/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 5e4875f..abac343 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
@@ -107,6 +107,9 @@ public class XUserService extends XUserServiceBase<XXUser, 
VXUser> {
                                "XXPortalUser xXPortalUser, XXPortalUserRole 
xXPortalUserRole", 
                                "xXPortalUser.id=xXPortalUserRole.userId and 
xXPortalUser.loginId = obj.name "));
                
+               searchFields.add(new SearchField("isVisible", "obj.isVisible",
+                               SearchField.DATA_TYPE.INTEGER, 
SearchField.SEARCH_TYPE.FULL ));
+
                
                createdByUserId = new Long(PropertiesUtil.getIntProperty(
                                "xa.xuser.createdByUserId", 1));
@@ -198,6 +201,7 @@ public class XUserService extends XUserServiceBase<XXUser, 
VXUser> {
        @Override
        public VXUser populateViewBean(XXUser xUser) {
                VXUser vObj = super.populateViewBean(xUser);
+               vObj.setIsVisible(xUser.getIsVisible());
                String userName = vObj.getName();
                populateUserAttributes(userName, vObj);
                populateGroupList(xUser.getId(), vObj);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java 
b/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java
index b8a4487..943e280 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java
@@ -43,6 +43,7 @@ public abstract class XUserServiceBase<T extends XXUser, V 
extends VXUser>
        @Override
        protected XXUser mapViewToEntityBean(VXUser vObj, XXUser mObj, int 
OPERATION_CONTEXT) {
                mObj.setName( vObj.getName());
+               mObj.setIsVisible(vObj.getIsVisible());
                mObj.setDescription( vObj.getDescription());
                mObj.setCredStoreId( vObj.getCredStoreId());
                return mObj;
@@ -52,6 +53,7 @@ public abstract class XUserServiceBase<T extends XXUser, V 
extends VXUser>
        @Override
        protected VXUser mapEntityToViewBean(VXUser vObj, XXUser mObj) {
                vObj.setName( mObj.getName());
+               vObj.setIsVisible(mObj.getIsVisible());
                vObj.setDescription( mObj.getDescription());
                vObj.setCredStoreId( mObj.getCredStoreId());
                return vObj;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/view/VXGroup.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/view/VXGroup.java 
b/security-admin/src/main/java/org/apache/ranger/view/VXGroup.java
index 5536b3c..5c7e6fb 100644
--- a/security-admin/src/main/java/org/apache/ranger/view/VXGroup.java
+++ b/security-admin/src/main/java/org/apache/ranger/view/VXGroup.java
@@ -62,10 +62,16 @@ public class VXGroup extends VXDataObject implements 
java.io.Serializable {
        protected Long credStoreId;
 
        /**
+        * Group visibility
+        */
+       protected Integer isVisible;
+       
+       /**
         * Default constructor. This will set all the attributes to default 
value.
         */
        public VXGroup ( ) {
                groupType = AppConstants.XA_GROUP_UNKNOWN;
+               isVisible = RangerCommonEnums.IS_VISIBLE;
        }
 
        /**
@@ -136,6 +142,20 @@ public class VXGroup extends VXDataObject implements 
java.io.Serializable {
                return this.credStoreId;
        }
 
+       /**
+        * @return the isVisible
+        */
+       public Integer getIsVisible() {
+               return isVisible;
+       }
+
+       /**
+        * @param isVisible the isVisible to set
+        */
+       public void setIsVisible(Integer isVisible) {
+               this.isVisible = isVisible;
+       }
+
        @Override
        public int getMyClassType( ) {
            return AppConstants.CLASS_TYPE_XA_GROUP;
@@ -163,6 +183,7 @@ public class VXGroup extends VXDataObject implements 
java.io.Serializable {
                str += "description={" + description + "} ";
                str += "groupType={" + groupType + "} ";
                str += "credStoreId={" + credStoreId + "} ";
+               str += "isVisible={" + isVisible + "} ";
                str += "groupSrc={" + groupSource + "} ";
                str += "}";
                return str;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/java/org/apache/ranger/view/VXUser.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/view/VXUser.java 
b/security-admin/src/main/java/org/apache/ranger/view/VXUser.java
index a237377..5e188a9 100644
--- a/security-admin/src/main/java/org/apache/ranger/view/VXUser.java
+++ b/security-admin/src/main/java/org/apache/ranger/view/VXUser.java
@@ -29,6 +29,7 @@ import java.util.Collection;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.ranger.common.AppConstants;
+import org.apache.ranger.common.RangerCommonEnums;
 import org.codehaus.jackson.annotate.JsonAutoDetect;
 import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@@ -77,6 +78,7 @@ public class VXUser extends VXDataObject implements 
java.io.Serializable {
        protected Collection<String> groupNameList;
        
        protected int status;
+       protected Integer isVisible;
        protected int userSource;
        /**
         * List of roles for this user
@@ -87,6 +89,7 @@ public class VXUser extends VXDataObject implements 
java.io.Serializable {
         * Default constructor. This will set all the attributes to default 
value.
         */
        public VXUser ( ) {
+               isVisible = RangerCommonEnums.IS_VISIBLE;
        }
 
        /**
@@ -235,11 +238,17 @@ public class VXUser extends VXDataObject implements 
java.io.Serializable {
                return status;
        }
 
-       public void setStatus(int status) {
+       public void setStatus(Integer status) {
                this.status = status;
        }
        
+       public Integer getIsVisible() {
+               return isVisible;
+       }
        
+       public void setIsVisible(Integer isVisible) {
+               this.isVisible = isVisible;
+       }
 
        public int getUserSource() {
                return userSource;
@@ -289,6 +298,7 @@ public class VXUser extends VXDataObject implements 
java.io.Serializable {
                str += "password={" + password + "} ";
                str += "description={" + description + "} ";
                str += "credStoreId={" + credStoreId + "} ";
+               str += "isVisible={" + isVisible + "} ";
                str += "groupIdList={" + groupIdList + "} ";
                str += "groupNameList={" + groupNameList + "} ";
                str += "}";

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js 
b/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
index 7329c79..4b86d08 100644
--- a/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
+++ b/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
@@ -41,7 +41,18 @@ define(function(require){
                        this.modelName = 'VXGroup';
                        this.modelAttrName = 'vXGroups';
                        this.bindErrorEvents();
+            this._changes = { };
+                       this.on('change', this._onChange);
                },
+
+               _onChange : function(m){
+            this._changes[m.id] = m;
+               },
+
+               changed_models: function() {
+            return _.chain(this._changes).values();
+        },
+
                /*************************
                 * Non - CRUD operations
                 *************************/
@@ -56,7 +67,20 @@ define(function(require){
                        }, options);
 
                        return this.constructor.nonCrudOperation.call(this, 
url, 'GET', options);
-               }
+               },
+
+               setGroupsVisibility : function(postData , options){
+                       var url = XAGlobals.baseURL  + 
'xusers/secure/groups/visibility';
+
+                       options = _.extend({
+                               data : JSON.stringify(postData),
+                               contentType : 'application/json',
+                               dataType : 'json'
+                       }, options);
+
+                       return this.constructor.nonCrudOperation.call(this, 
url, 'PUT', options);
+               },
+
        },{
                // static class members
                /**

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js 
b/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
index 5ebcb3c..2c7f5fc 100644
--- a/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
+++ b/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
@@ -41,8 +41,17 @@ define(function(require){
                        this.modelName = 'VXUser';
                        this.modelAttrName = 'vXUsers';
                        this.bindErrorEvents();
+            this._changes = { };
+                       this.on('change', this._onChange);
                },
                
+               _onChange : function(m){
+            this._changes[m.id] = m;
+               },
+
+               changed_models: function() {
+            return _.chain(this._changes).values();
+        },
 
                /*************************
                 * Non - CRUD operations
@@ -58,7 +67,19 @@ define(function(require){
                        }, options);
 
                        return this.constructor.nonCrudOperation.call(this, 
url, 'GET', options);
-               }
+               },
+
+               setUsersVisibility : function(postData , options){
+                       var url = XAGlobals.baseURL  + 
'xusers/secure/users/visibility';
+
+                       options = _.extend({
+                               data : JSON.stringify(postData),
+                               contentType : 'application/json',
+                               dataType : 'json'
+                       }, options);
+
+                       return this.constructor.nonCrudOperation.call(this, 
url, 'PUT', options);
+               },
        },{
        /**
        * Table Cols to be passed to Backgrid

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/models/VXGroup.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/models/VXGroup.js 
b/security-admin/src/main/webapp/scripts/models/VXGroup.js
index 1a97741..fdad8aa 100644
--- a/security-admin/src/main/webapp/scripts/models/VXGroup.js
+++ b/security-admin/src/main/webapp/scripts/models/VXGroup.js
@@ -23,6 +23,7 @@ define(function(require){
 
        var VXGroupBase         = require('model_bases/VXGroupBase');
        var localization        = require('utils/XALangSupport');
+       var XAEnums         = require('utils/XAEnums');
        
        var VXGroup = VXGroupBase.extend(
        /** @lends VXGroup.prototype */
@@ -35,7 +36,19 @@ define(function(require){
                initialize: function() {
                        this.modelName = 'VXGroup';
                        this.bindErrorEvents();
-                       
+                       this.toView();
+               },
+
+               toView : function(){
+                       if(!_.isUndefined(this.get('isVisible'))){
+                               var visible = (this.get('isVisible') == 
XAEnums.VisibilityStatus.STATUS_VISIBLE.value);
+                               this.set('isVisible', visible);
+                       }
+               },
+
+               toServer : function(){
+                       var visible = this.get('isVisible') ? 
XAEnums.VisibilityStatus.STATUS_VISIBLE.value : 
XAEnums.VisibilityStatus.STATUS_HIDDEN.value;
+                       this.set('isVisible', visible);
                },
                /**
                 * @function schema

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/models/VXUser.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/models/VXUser.js 
b/security-admin/src/main/webapp/scripts/models/VXUser.js
index 9961032..b74ed5a 100644
--- a/security-admin/src/main/webapp/scripts/models/VXUser.js
+++ b/security-admin/src/main/webapp/scripts/models/VXUser.js
@@ -22,6 +22,7 @@ define(function(require){
        'use strict';   
 
        var VXUserBase  = require('model_bases/VXUserBase');
+       var XAEnums     = require('utils/XAEnums');
 
        var VXUser = VXUserBase.extend(
        /** @lends VXUser.prototype */
@@ -34,6 +35,19 @@ define(function(require){
                initialize: function() {
                        this.modelName = 'VXUser';
                        this.bindErrorEvents();
+                       this.toView();
+               },
+
+               toView : function(){
+                       if(!_.isUndefined(this.get('isVisible'))){
+                               var visible = (this.get('isVisible') == 
XAEnums.VisibilityStatus.STATUS_VISIBLE.value);
+                               this.set('isVisible', visible);
+                       }
+               },
+
+               toServer : function(){
+                       var visible = this.get('isVisible') ? 
XAEnums.VisibilityStatus.STATUS_VISIBLE.value : 
XAEnums.VisibilityStatus.STATUS_HIDDEN.value;
+                       this.set('isVisible', visible);
                },
                
                /** This models toString() */

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js 
b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
index df728a3..a351063 100644
--- a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
+++ b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
@@ -651,4 +651,267 @@
                 */
                
                (function(e){function t(t,n,r){var 
i=n.data("dF").dirtyFieldsDataProperty;var 
s=e.inArray(t,i);if(r=="dirty"&&s==-1){i.push(t);n.data("dF").dirtyFieldsDataProperty=i}else
 
if(r=="clean"&&s>-1){i.splice(s,1);n.data("dF").dirtyFieldsDataProperty=i}}function
 
n(t){if(t.data("dF").dirtyFieldsDataProperty.length>0){t.addClass(t.data("dF").dirtyFormClass);if(e.isFunction(t.data("dF").formChangeCallback)){t.data("dF").formChangeCallback.call(t,true,t.data("dF").dirtyFieldsDataProperty)}}else{t.removeClass(t.data("dF").dirtyFormClass);if(e.isFunction(t.data("dF").formChangeCallback)){t.data("dF").formChangeCallback.call(t,false,t.data("dF").dirtyFieldsDataProperty)}}}function
 r(t,n,r,i){if(i.data("dF").denoteDirtyFields){var 
s=i.data("dF").fieldOverrides;var o=n.attr("id");var u=false;for(var a in 
s){if(o==a){if(r=="changed"){e("#"+s[a]).addClass(i.data("dF").dirtyFieldClass)}else{e("#"+s[a]).removeClass(i.data("dF").dirtyFieldClass)}u=true}}if(u==false){var
 f=i.data("dF")[t];var l=f.split(
 
"-");switch(l[0]){case"next":if(r=="changed"){n.next(l[1]).addClass(i.data("dF").dirtyFieldClass)}else{n.next(l[1]).removeClass(i.data("dF").dirtyFieldClass)}break;case"previous":if(r=="changed"){n.prev(l[1]).addClass(i.data("dF").dirtyFieldClass)}else{n.prev(l[1]).removeClass(i.data("dF").dirtyFieldClass)}break;case"closest":if(r=="changed"){n.closest(l[1]).addClass(i.data("dF").dirtyFieldClass)}else{n.closest(l[1]).removeClass(i.data("dF").dirtyFieldClass)}break;case"self":if(r=="changed"){n.addClass(i.data("dF").dirtyFieldClass)}else{n.removeClass(i.data("dF").dirtyFieldClass)}break;default:if(l[0]=="id"||l[0]=="name"){switch(l[1]){case"class":if(r=="changed"){e("."+n.attr(l[0]),i).addClass(i.data("dF").dirtyFieldClass)}else{e("."+n.attr(l[0]),i).removeClass(i.data("dF").dirtyFieldClass)}break;case"title":if(r=="changed"){e("*[title='"+n.attr(l[0])+"']",i).addClass(i.data("dF").dirtyFieldClass)}else{e("*[title='"+n.attr(l[0])+"']",i).removeClass(i.data("dF").dirtyFieldClass)}brea
 
k;case"for":if(r=="changed"){e("label[for='"+n.attr(l[0])+"']",i).addClass(i.data("dF").dirtyFieldClass)}else{e("label[for='"+n.attr(l[0])+"']",i).removeClass(i.data("dF").dirtyFieldClass)}break}}break}}}}function
 i(i,s){var o=i.attr("name");var u=false;if(s.data("dF").trimText){var 
a=jQuery.trim(i.val())}else{var 
a=i.val()}if(i.hasClass(s.data("dF").ignoreCaseClass)){var 
a=a.toUpperCase();var 
f=i.data(s.data("dF").startingValueDataProperty).toUpperCase()}else{var 
f=i.data(s.data("dF").startingValueDataProperty)}if(a!=f){r("textboxContext",i,"changed",s);t(o,s,"dirty");u=true}else{r("textboxContext",i,"unchanged",s);t(o,s,"clean")}if(e.isFunction(s.data("dF").fieldChangeCallback)){s.data("dF").fieldChangeCallback.call(i,i.data(s.data("dF").startingValueDataProperty),u)}if(s.data("dF").denoteDirtyForm){n(s)}}function
 s(i,s){var o=i.attr("name");var 
u=false;if(s.data("dF").denoteDirtyOptions==false&&i.attr("multiple")!=true){if(i.hasClass(s.data("dF").ignoreCaseClass)){var
 a=i.val().t
 oUpperCase();var 
f=i.data(s.data("dF").startingValueDataProperty).toUpperCase()}else{var 
a=i.val();var 
f=i.data(s.data("dF").startingValueDataProperty)}if(a!=f){r("selectContext",i,"changed",s);t(o,s,"dirty");u=true}else{r("selectContext",i,"unchanged",s);t(o,s,"clean")}}else{var
 l=false;i.children("option").each(function(t){var n=e(this);var 
r=n.is(":selected");if(r!=n.data(s.data("dF").startingValueDataProperty)){if(s.data("dF").denoteDirtyOptions){n.addClass(s.data("dF").dirtyOptionClass)}l=true}else{if(s.data("dF").denoteDirtyOptions){n.removeClass(s.data("dF").dirtyOptionClass)}}});if(l){r("selectContext",i,"changed",s);t(o,s,"dirty");u=true}else{r("selectContext",i,"unchanged",s);t(o,s,"clean")}}if(e.isFunction(s.data("dF").fieldChangeCallback)){s.data("dF").fieldChangeCallback.call(i,i.data(s.data("dF").startingValueDataProperty),u)}if(s.data("dF").denoteDirtyForm){n(s)}}function
 o(i,s){var o=i.attr("name");var u=false;var 
a=i.attr("type");e(":"+a+"[name='"+o+"']",s).each(fun
 ction(t){var n=e(this);var 
i=n.is(":checked");if(i!=n.data(s.data("dF").startingValueDataProperty)){r("checkboxRadioContext",n,"changed",s);u=true}else{r("checkboxRadioContext",n,"unchanged",s)}});if(u){t(o,s,"dirty")}else{t(o,s,"clean")}if(e.isFunction(s.data("dF").fieldChangeCallback)){s.data("dF").fieldChangeCallback.call(i,i.data(s.data("dF").startingValueDataProperty),u)}if(s.data("dF").denoteDirtyForm){n(s)}}e.fn.dirtyFields=function(t){var
 n=e.extend({},e.fn.dirtyFields.defaults,t);return this.each(function(){var 
t=e(this);t.data("dF",n);t.data("dF").dirtyFieldsDataProperty=new 
Array;e("input[type='text'],input[type='file'],input[type='password'],textarea",t).not("."+t.data("dF").exclusionClass).each(function(n){e.fn.dirtyFields.configureField(e(this),t,"text")});e("select",t).not("."+t.data("dF").exclusionClass).each(function(n){e.fn.dirtyFields.configureField(e(this),t,"select")});e(":checkbox,:radio",t).not("."+t.data("dF").exclusionClass).each(function(n){e.fn.dirtyFields
 
.configureField(e(this),t,"checkRadio")});e.fn.dirtyFields.setStartingValues(t)})};e.fn.dirtyFields.defaults={checkboxRadioContext:"next-span",denoteDirtyOptions:false,denoteDirtyFields:true,denoteDirtyForm:false,dirtyFieldClass:"dirtyField",dirtyFieldsDataProperty:"dirtyFields",dirtyFormClass:"dirtyForm",dirtyOptionClass:"dirtyOption",exclusionClass:"dirtyExclude",fieldChangeCallback:"",fieldOverrides:{none:"none"},formChangeCallback:"",ignoreCaseClass:"dirtyIgnoreCase",preFieldChangeCallback:"",selectContext:"id-for",startingValueDataProperty:"startingValue",textboxContext:"id-for",trimText:false};e.fn.dirtyFields.configureField=function(t,n,r,u){if(!t.hasClass(n.data("dF").exclusionClass)){if(typeof
 
u!="undefined"){n.data("dF").fieldOverrides[t.attr("id")]=u}switch(r){case"text":t.change(function(){if(e.isFunction(n.data("dF").preFieldChangeCallback)){if(n.data("dF").preFieldChangeCallback.call(t,t.data(n.data("dF").startingValueDataProperty))==false){return
 false}}i(t,n)});break
 
;case"select":t.change(function(){if(e.isFunction(n.data("dF").preFieldChangeCallback)){if(n.data("dF").preFieldChangeCallback.call(t,t.data(n.data("dF").startingValueDataProperty))==false){return
 
false}}s(t,n)});break;case"checkRadio":t.change(function(){if(e.isFunction(n.data("dF").preFieldChangeCallback)){if(n.data("dF").preFieldChangeCallback.call(t,t.data(n.data("dF").startingValueDataProperty))==false){return
 
false}}o(t,n)});break}}};e.fn.dirtyFields.formSaved=function(t){e.fn.dirtyFields.setStartingValues(t);e.fn.dirtyFields.markContainerFieldsClean(t)};e.fn.dirtyFields.markContainerFieldsClean=function(t){var
 n=new 
Array;t.data("dF").dirtyFieldsDataProperty=n;e("."+t.data("dF").dirtyFieldClass,t).removeClass(t.data("dF").dirtyFieldClass);if(t.data("dF").denoteDirtyOptions){e("."+t.data("dF").dirtyOptionClass,t).removeClass(t.data("dF").dirtyOptionClass)}if(t.data("dF").denoteDirtyForm){t.removeClass(t.data("dF").dirtyFormClass)}};e.fn.dirtyFields.setStartingValues=function(t
 
,n){e("input[type='text'],input[type='file'],input[type='password'],:checkbox,:radio,textarea",t).not("."+t.data("dF").exclusionClass).each(function(n){var
 
r=e(this);if(r.attr("type")=="radio"||r.attr("type")=="checkbox"){e.fn.dirtyFields.setStartingCheckboxRadioValue(r,t)}else{e.fn.dirtyFields.setStartingTextValue(r,t)}});e("select",t).not("."+t.data("dF").exclusionClass).each(function(n){e.fn.dirtyFields.setStartingSelectValue(e(this),t)})};e.fn.dirtyFields.setStartingTextValue=function(t,n){return
 t.not("."+n.data("dF").exclusionClass).each(function(){var 
t=e(this);t.data(n.data("dF").startingValueDataProperty,t.val())})};e.fn.dirtyFields.setStartingCheckboxRadioValue=function(t,n){return
 t.not("."+n.data("dF").exclusionClass).each(function(){var t=e(this);var 
r;if(t.is(":checked")){t.data(n.data("dF").startingValueDataProperty,true)}else{t.data(n.data("dF").startingValueDataProperty,false)}})};e.fn.dirtyFields.setStartingSelectValue=function(t,n){return
 t.not("."+n.data("dF").ex
 clusionClass).each(function(){var 
t=e(this);if(n.data("dF").denoteDirtyOptions==false&&t.attr("multiple")!=true){t.data(n.data("dF").startingValueDataProperty,t.val())}else{var
 r=new Array;t.children("option").each(function(t){var 
i=e(this);if(i.is(":selected")){i.data(n.data("dF").startingValueDataProperty,true);r.push(i.val())}else{i.data(n.data("dF").startingValueDataProperty,false)}});t.data(n.data("dF").startingValueDataProperty,r)}})};e.fn.dirtyFields.rollbackTextValue=function(t,n,r){if(typeof
 r=="undefined"){r=true}return 
t.not("."+n.data("dF").exclusionClass).each(function(){var 
t=e(this);t.val(t.data(n.data("dF").startingValueDataProperty));if(r){i(t,n)}})};e.fn.dirtyFields.updateTextState=function(t,n){return
 
t.not("."+n.data("dF").exclusionClass).each(function(){i(e(this),n)})};e.fn.dirtyFields.rollbackCheckboxRadioState=function(t,n,r){if(typeof
 r=="undefined"){r=true}return 
t.not("."+n.data("dF").exclusionClass).each(function(){var 
t=e(this);if(t.data(n.data("dF").star
 
tingValueDataProperty)){t.attr("checked",true)}else{t.attr("checked",false)}if(r){o(t,n)}})};e.fn.dirtyFields.updateCheckboxRadioState=function(t,n){return
 
t.not("."+n.data("dF").exclusionClass).each(function(){o(e(this),n)})};e.fn.dirtyFields.rollbackSelectState=function(t,n,r){if(typeof
 r=="undefined"){r=true}return 
t.not("."+n.data("dF").exclusionClass).each(function(){var 
t=e(this);if(n.data("dF").denoteDirtyOptions==false&&t.attr("multiple")!=true){t.val(t.data(n.data("dF").startingValueDataProperty))}else{t.children("option").each(function(t){var
 
r=e(this);if(r.data(n.data("dF").startingValueDataProperty)){r.attr("selected",true)}else{r.attr("selected",false)}})}if(r){s(t,n)}})};e.fn.dirtyFields.updateSelectState=function(t,n){return
 
t.not("."+n.data("dF").exclusionClass).each(function(){s(e(this),n)})};e.fn.dirtyFields.rollbackForm=function(t){e("input[type='text'],input[type='file'],input[type='password'],:checkbox,:radio,textarea",t).not("."+t.data("dF").exclusionClass).eac
 
h(function(n){$object=e(this);if($object.attr("type")=="radio"||$object.attr("type")=="checkbox"){e.fn.dirtyFields.rollbackCheckboxRadioState($object,t,false)}else{e.fn.dirtyFields.rollbackTextValue($object,t,false)}});e("select",t).not("."+t.data("dF").exclusionClass).each(function(n){e.fn.dirtyFields.rollbackSelectState(e(this),t,false)});e.fn.dirtyFields.markContainerFieldsClean(t)};e.fn.dirtyFields.updateFormState=function(t){e("input[type='text'],input[type='file'],input[type='password'],:checkbox,:radio,textarea",t).not("."+t.data("dF").exclusionClass).each(function(n){$object=e(this);if($object.attr("type")=="radio"||$object.attr("type")=="checkbox"){e.fn.dirtyFields.updateCheckboxRadioState($object,t)}else{e.fn.dirtyFields.updateTextState($object,t)}});e("select",t).not("."+t.data("dF").exclusionClass).each(function(n){$object=e(this);e.fn.dirtyFields.updateSelectState($object,t)})};e.fn.dirtyFields.getDirtyFieldNames=function(e){return
 e.data("dF").dirtyFieldsDataProperty};
 })(jQuery)
+
+               var SelectRowCell = Backgrid.Extension.SelectRowCell = 
Backbone.View.extend({
+
+                   /** @property */
+                   className: "select-row-cell",
+
+                   /** @property */
+                   tagName: "td",
+
+                   /** @property */
+                   events: {
+                     "keydown input[type=checkbox]": "onKeydown",
+                     "change input[type=checkbox]": "onChange",
+                     "click input[type=checkbox]": "enterEditMode"
+                   },
+
+                   /**
+                      Initializer. If the underlying model triggers a `select` 
event, this cell
+                      will change its checked value according to the event's 
`selected` value.
+                      @param {Object} options
+                      @param {Backgrid.Column} options.column
+                      @param {Backbone.Model} options.model
+                   */
+                   initialize: function (options) {
+
+                     this.column = options.column;
+                     if (!(this.column instanceof Backgrid.Column)) {
+                       this.column = new Backgrid.Column(this.column);
+                     }
+
+                     var column = this.column, model = this.model, $el = 
this.$el;
+                     this.listenTo(column, "change:renderable", function 
(column, renderable) {
+                       $el.toggleClass("renderable", renderable);
+                     });
+
+                     if (Backgrid.callByNeed(column.renderable(), column, 
model)) $el.addClass("renderable");
+
+                     this.listenTo(model, "backgrid:select", function (model, 
selected) {
+                       this.checkbox().prop("checked", selected).change();
+                     });
+                   },
+
+                   /**
+                      Returns the checkbox.
+                    */
+                   checkbox: function () {
+                     return this.$el.find("input[type=checkbox]");
+                   },
+
+                   /**
+                      Focuses the checkbox.
+                   */
+                   enterEditMode: function () {
+                     this.checkbox().focus();
+                   },
+
+                   /**
+                      Unfocuses the checkbox.
+                   */
+                   exitEditMode: function () {
+                     this.checkbox().blur();
+                   },
+
+                   /**
+                      Process keyboard navigation.
+                   */
+                   onKeydown: function (e) {
+                     var command = new Backgrid.Command(e);
+                     if (command.passThru()) return true; // skip ahead to 
`change`
+                     if (command.cancel()) {
+                       e.stopPropagation();
+                       this.checkbox().blur();
+                     }
+                     else if (command.save() || command.moveLeft() || 
command.moveRight() ||
+                              command.moveUp() || command.moveDown()) {
+                       e.preventDefault();
+                       e.stopPropagation();
+                       this.model.trigger("backgrid:edited", this.model, 
this.column, command);
+                     }
+                   },
+
+                   /**
+                      When the checkbox's value changes, this method will 
trigger a Backbone
+                      `backgrid:selected` event with a reference of the model 
and the
+                      checkbox's `checked` value.
+                   */
+                   onChange: function () {
+                     var checked = this.checkbox().prop("checked");
+                     this.$el.parent().toggleClass("selected", checked);
+                     this.model.set('isVisible', checked)
+                     this.model.trigger("backgrid:selected", this.model, 
checked);
+                   },
+
+                   /**
+                      Renders a checkbox in a table cell.
+                   */
+                   render: function () {
+                       var val;
+                       if(_.has(this, 'model'))
+                               val = (this.model.get(this.column.get('name'))) 
? 'checked' : '';
+                     this.$el.empty().append('<input tabindex="-1" 
type="checkbox" '+ val +'/>');
+                     this.delegateEvents();
+                     return this;
+                   }
+
+                 });
+
+                 /**
+                    Renders a checkbox to select all rows on the current page.
+                    @class Backgrid.Extension.SelectAllHeaderCell
+                    @extends Backgrid.Extension.SelectRowCell
+                 */
+                 var SelectAllHeaderCell = 
Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({
+
+                   /** @property */
+                   className: "select-all-header-cell",
+
+                   /** @property */
+                   tagName: "th",
+
+                   /**
+                      Initializer. When this cell's checkbox is checked, a 
Backbone
+                      `backgrid:select` event will be triggered for each model 
for the current
+                      page in the underlying collection. If a `SelectRowCell` 
instance exists
+                      for the rows representing the models, they will check 
themselves. If any
+                      of the SelectRowCell instances trigger a Backbone 
`backgrid:selected`
+                      event with a `false` value, this cell will uncheck its 
checkbox. In the
+                      event of a Backbone `backgrid:refresh` event, which is 
triggered when the
+                      body refreshes its rows, which can happen under a number 
of conditions
+                      such as paging or the columns were reset, this cell will 
still remember
+                      the previously selected models and trigger a Backbone 
`backgrid:select`
+                      event on them such that the SelectRowCells can recheck 
themselves upon
+                      refreshing.
+                      @param {Object} options
+                      @param {Backgrid.Column} options.column
+                      @param {Backbone.Collection} options.collection
+                   */
+                   initialize: function (options) {
+
+                     this.column = options.column;
+                     if (!(this.column instanceof Backgrid.Column)) {
+                       this.column = new Backgrid.Column(this.column);
+                     }
+
+                     var collection = this.collection;
+                     var selectedModels = this.selectedModels = {};
+                     this.listenTo(collection.fullCollection || collection,
+                                   "backgrid:selected", function (model, 
selected) {
+                       if (selected) selectedModels[model.id || model.cid] = 1;
+                       else {
+                         delete selectedModels[model.id || model.cid];
+                         this.checkbox().prop("checked", false);
+                       }
+                       if (_.keys(selectedModels).length === 
(collection.fullCollection|| collection).length) {
+                         this.checkbox().prop("checked", true);
+                       }
+                     });
+
+                     this.listenTo(collection.fullCollection || collection, 
"remove", function (model) {
+                       delete selectedModels[model.id || model.cid];
+                       if ((collection.fullCollection || collection).length 
=== 0) {
+                         this.checkbox().prop("checked", false);
+                       }
+                     });
+
+                     this.listenTo(collection, "backgrid:refresh", function () 
{
+                       if ((collection.fullCollection || collection).length 
=== 0) {
+                         this.checkbox().prop("checked", false);
+                       }
+                       else {
+                         var checked = this.checkbox().prop("checked");
+                         for (var i = 0; i < collection.length; i++) {
+                           var model = collection.at(i);
+                           if (checked || selectedModels[model.id || 
model.cid]) {
+                             model.trigger("backgrid:select", model, true);
+                           }
+                         }
+                       }
+                     });
+
+                     var column = this.column, $el = this.$el;
+                     this.listenTo(column, "change:renderable", function 
(column, renderable) {
+                       $el.toggleClass("renderable", renderable);
+                     });
+
+                     if (Backgrid.callByNeed(column.renderable(), column, 
collection)) $el.addClass("renderable");
+                   },
+
+                   /**
+                      Propagates the checked value of this checkbox to all the 
models of the
+                      underlying collection by triggering a Backbone 
`backgrid:select` event on
+                      the models on the current page, passing each model and 
the current
+                      `checked` value of the checkbox in each event.
+                      A `backgrid:selected` event will also be triggered with 
the current
+                      `checked` value on all the models regardless of whether 
they are on the
+                      current page.
+                      This method triggers a 'backgrid:select-all' event on 
the collection
+                      afterwards.
+                   */
+                   onChange: function () {
+                     var checked = this.checkbox().prop("checked");
+
+                     var collection = this.collection;
+                     collection.each(function (model) {
+                       model.trigger("backgrid:select", model, checked);
+                     });
+
+                     if (collection.fullCollection) {
+                       collection.fullCollection.each(function (model) {
+                         if (!collection.get(model.cid)) {
+                           model.trigger("backgrid:selected", model, checked);
+                         }
+                       });
+                     }
+
+                     this.collection.trigger("backgrid:select-all", 
this.collection, checked);
+                   }
+
+                 });
+
+                 /**
+                    Convenient method to retrieve a list of selected models. 
This method only
+                    exists when the `SelectAll` extension has been included. 
Selected models
+                    are retained across pagination.
+                    @member Backgrid.Grid
+                    @return {Array.<Backbone.Model>}
+                 */
+                 Backgrid.Grid.prototype.getSelectedModels = function () {
+                   var selectAllHeaderCell;
+                   var headerCells = this.header.row.cells;
+                   for (var i = 0, l = headerCells.length; i < l; i++) {
+                     var headerCell = headerCells[i];
+                     if (headerCell instanceof SelectAllHeaderCell) {
+                       selectAllHeaderCell = headerCell;
+                       break;
+                     }
+                   }
+
+                   var result = [];
+                   if (selectAllHeaderCell) {
+                     var selectedModels = selectAllHeaderCell.selectedModels;
+                     var collection = this.collection.fullCollection || 
this.collection;
+                     for (var modelId in selectedModels) {
+                       result.push(collection.get(modelId));
+                     }
+                   }
+
+                   return result;
+                 };
+
+                 /**
+                    Convenient method to deselect the selected models. This 
method is only
+                    available when the `SelectAll` extension has been included.
+                    @member Backgrid.Grid
+                  */
+                 Backgrid.Grid.prototype.clearSelectedModels = function () {
+                   var selectedModels = this.getSelectedModels();
+                   for (var i = 0, l = selectedModels.length; i < l; i++) {
+                     var model = selectedModels[i];
+                     model.trigger("backgrid:select", model, false);
+                   }
+                 };
+
 });

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/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 6320028..1c7d803 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
@@ -142,6 +142,8 @@ define(function(require) {
                                accountStatus                                   
: 'Account Status',
                                ActiveStatus_STATUS_ENABLED     : 'Enabled',
                                ActiveStatus_STATUS_DISABLED    : 'Disabled',
+                               VisibilityStatus_IS_VISIBLE     : 'Visible',
+                               VisibilityStatus_IS_HIDDEN      : 'Hidden',
                                commonNameForCertificate                : 
'Common Name For Certificate',
                                status                                          
        : 'Status',
                                userListing                                     
        : 'User List',
@@ -206,6 +208,7 @@ define(function(require) {
                                topologyName                                    
: 'Topology Name',
                                serivceName                                     
        : 'Service Name',
                                ipAddress                                       
        : 'IP Address',
+                               isVisible                       : 'Visible',
                                delegatedAdmin                                  
: 'Delegate Admin',
                                policyId                                        
        : 'Policy ID'
                        },
@@ -213,8 +216,8 @@ define(function(require) {
                                add                                             
        : 'Add',
                                save                                            
: 'Save',
                                cancel                                          
: 'Cancel',
-                               addMore                                         
: 'Add More..'
-                               
+                               addMore                                         
: 'Add More..',
+                               setVisibility               : 'Set Visibility' 
                                
                        },
                        // h1, h2, h3, fieldset, title
@@ -301,7 +304,8 @@ define(function(require) {
                                preventNavPolicyForm : 'Policy form edit is in 
progress. Please save/cancel changes before navigating away!',
                                preventNavRepositoryForm : 'Repository form 
edit is in progress. Please save/cancel changes before navigating away!',
                                preventNavUserForm : 'User form edit is in 
progress. Please save/cancel changes before navigating away!',
-                               preventNavGroupForm : 'Group form edit is in 
progress. Please save/cancel changes before navigating away!'
+                               preventNavGroupForm : 'Group form edit is in 
progress. Please save/cancel changes before navigating away!',
+                               preventNavUserList : 'Some Users/Groups have 
been edited. Kindly save your changes before navigating away!'
                                
                        },      
                        validationMessages : {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/utils/XAEnums.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/utils/XAEnums.js 
b/security-admin/src/main/webapp/scripts/utils/XAEnums.js
index 1a28c11..ce842f7 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAEnums.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAEnums.js
@@ -73,6 +73,11 @@ define(function(require) {
                ACT_STATUS_NO_LOGIN:{value:7, label:'No login privilege', 
rbkey:'xa.enum.ActivationStatus.ACT_STATUS_NO_LOGIN', tt: 
'lbl.ActivationStatus_ACT_STATUS_NO_LOGIN'}
        });
 
+       XAEnums.VisibilityStatus = mergeParams(XAEnums.VisibilityStatus, {
+               STATUS_HIDDEN:{value:0, label:'Hidden', 
rbkey:'xa.enum.VisibilityStatus.IS_HIDDEN', tt: 
'lbl.VisibilityStatus_IS_HIDDEN'},
+               STATUS_VISIBLE:{value:1, label:'Visible', 
rbkey:'xa.enum.VisibilityStatus.IS_VISIBLE', tt: 
'lbl.VisibilityStatus_IS_VISIBLE'}
+       });
+
        XAEnums.ActiveStatus = mergeParams(XAEnums.ActiveStatus, {
                STATUS_DISABLED:{value:0, label:'Disabled', 
rbkey:'xa.enum.ActiveStatus.STATUS_DISABLED', tt: 
'lbl.ActiveStatus_STATUS_DISABLED'},
                STATUS_ENABLED:{value:1, label:'Enabled', 
rbkey:'xa.enum.ActiveStatus.STATUS_ENABLED', tt: 
'lbl.ActiveStatus_STATUS_ENABLED'},

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/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 2f3b3d7..fd39935 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
@@ -525,6 +525,7 @@ define(function(require) {
                
                var callbackCommon = {
                search       : function(query, searchCollection) {
+                                                       collection.VSQuery = 
query;
                                                        
search(searchCollection, serverAttrName, searchOpt,collection);
                                           },
                facetMatches :  function(callback) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/views/common/FormInputItemList.js
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/scripts/views/common/FormInputItemList.js 
b/security-admin/src/main/webapp/scripts/views/common/FormInputItemList.js
index fdc6ec2..ca1ebc4 100644
--- a/security-admin/src/main/webapp/scripts/views/common/FormInputItemList.js
+++ b/security-admin/src/main/webapp/scripts/views/common/FormInputItemList.js
@@ -172,7 +172,7 @@ define(function(require) {
                                        url: "service/xusers/groups",
                                        dataType: 'json',
                                        data: function (term, page) {
-                                               return {name : term};
+                        return {name : term, isVisible : 
XAEnums.VisibilityStatus.STATUS_VISIBLE.value};
                                        },
                                        results: function (data, page) { 
                                                var results = [] , selectedVals 
= [];

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/views/common/UserPermissionList.js
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/scripts/views/common/UserPermissionList.js 
b/security-admin/src/main/webapp/scripts/views/common/UserPermissionList.js
index b4f93cb..fce1963 100644
--- a/security-admin/src/main/webapp/scripts/views/common/UserPermissionList.js
+++ b/security-admin/src/main/webapp/scripts/views/common/UserPermissionList.js
@@ -229,7 +229,7 @@ define(function(require) {
                                        url: "service/xusers/users",
                                        dataType: 'json',
                                        data: function (term, page) {
-                                               return {name : term};
+                                               return {name : term, isVisible 
: XAEnums.VisibilityStatus.STATUS_VISIBLE.value};
                                        },
                                        results: function (data, page) { 
                                                var results = 
[],selectedVals=[];

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/views/common/XATableLayout.js
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/scripts/views/common/XATableLayout.js 
b/security-admin/src/main/webapp/scripts/views/common/XATableLayout.js
index 35f4b4e..5556559 100644
--- a/security-admin/src/main/webapp/scripts/views/common/XATableLayout.js
+++ b/security-admin/src/main/webapp/scripts/views/common/XATableLayout.js
@@ -145,6 +145,13 @@ define(function(require){
                initializePlugins: function(){
                },
 
+        getGridObj : function(){
+                       if (this.rTableList.currentView){
+                return this.rTableList.currentView;
+                       }
+                       return null;
+               },
+
                renderTable : function(){
                        var that = this;
                        this.rTableList.show(new Backgrid.Grid(this.gridOpts));

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/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 fc57134..b938c66 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
@@ -198,7 +198,7 @@ define(function(require) {
                                        url: url,
                                        dataType: 'json',
                                        data: function (term, page) {
-                                               return {name : term};
+                                               return {name : term, isVisible 
: XAEnums.VisibilityStatus.STATUS_VISIBLE.value};
                                        },
                                        results: function (data, page) { 
                                                var results = [] , selectedVals 
= [];
@@ -517,4 +517,4 @@ define(function(require) {
                },
        });
 
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js 
b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
index 988f57c..bcbb3e0 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
@@ -151,7 +151,7 @@ define(function(require){
                        var that = this;
                        var accessType = 
this.rangerServiceDefModel.get('accessTypes').filter(function(val) { return val 
!== null; });
                        this.userList = new VXUserList();
-                       var params = {sortBy : 'name'};
+                       var params = {sortBy : 'name', isVisible : 
XAEnums.VisibilityStatus.STATUS_VISIBLE.value};
                        this.userList.setPageSize(100,{fetch:false});
                        this.userList.fetch({
                                cache :true,

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js 
b/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
index e1f8e70..161a09a 100644
--- a/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
+++ b/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
@@ -57,6 +57,7 @@ define(function(require){
                visualSearch: '.visual_search',
                btnShowMore : '[data-id="showMore"]',
                        btnShowLess : '[data-id="showLess"]',
+               btnSave         : '[data-id="save"]'
        },
 
                /** ui events hash */
@@ -65,6 +66,7 @@ define(function(require){
                        events['click '+this.ui.tab+' li a']  = 'onTabChange';
                        events['click ' + this.ui.btnShowMore]  = 'onShowMore';
                        events['click ' + this.ui.btnShowLess]  = 'onShowLess';
+                       events['click ' + this.ui.btnSave]  = 'onSave';
                        return events;
                },
 
@@ -77,13 +79,30 @@ define(function(require){
 
                        _.extend(this, _.pick(options, 'groupList','tab'));
                        this.showUsers = this.tab == 'usertab' ? true : false;
+
+                       this.chgFlags = [];
+                       this.showUsers = true;
+
+                       if(_.isUndefined(this.groupList)){
+                               this.groupList = new VXGroupList();
+                       }
+
                        this.bindEvents();
                },
 
                /** all events binding here */
                bindEvents : function(){
+                       var that = this;
+            this.listenTo(this.collection,"backgrid:selected", 
this.onModelChange);
+            this.listenTo(this.groupList,"backgrid:selected", 
this.onModelChange);
                        /*this.listenTo(this.model, "change:foo", 
this.modelChanged, this);*/
                        /*this.listenTo(communicator.vent,'someView:someEvent', 
this.someEventHandler, this)'*/
+                       this.collection.on('change', function(){
+                               that.preventNavigation();
+                       });
+                       this.groupList.on('change', function(){
+                               that.preventNavigation();
+                       });
                },
 
                /** on render callback */
@@ -95,18 +114,85 @@ define(function(require){
                                this.renderUserTab();
                        this.addVisualSearch();
                },
+
+               preventNavigation : function(){
+            
XAUtil.preventNavigation(localization.tt('dialogMsg.preventNavUserList'),this.rTableList.$el);
+                       
this.rTableList.$el.find('table').addClass('dirtyField');
+                       //this.ui.btnSave.removeClass('disabled');
+               },
+
+               allowNavigation : function(){
+                       XAUtil.allowNavigation();
+                       
this.rTableList.$el.find('table').removeClass('dirtyField');
+                       //this.ui.btnSave.addClass('disabled');
+               },
+
+               onModelChange : function(model, selected){
+                       /*var that = this;
+                       if(! (model.id in that.chgFlags)){
+                               that.chgFlags[model.id] = true;
+                       } else {
+                that.chgFlags[model.id] ^= true;
+            }
+
+                       if (_.some(that.chgFlags)){
+                that.preventNavigation();
+                       } else {
+                that.allowNavigation();
+                       }*/
+               },
                onTabChange : function(e){
+                       var that = this;
+                       this.chgFlags = [];
                        this.showUsers = $(e.currentTarget).attr('href') == 
'#users' ? true : false;
-                       if(this.showUsers){
+                       if(this.showUsers){                             
                                this.renderUserTab();
                                this.addVisualSearch();
                        }
-                       else{
+                       else{                           
                                this.renderGroupTab();
                                this.addVisualSearch();
                        }
                        $(this.rUserDetail.el).hide();
                },
+               onSave : function(e){
+                       var that = this;
+                       var updateReq = {};
+                       var collection = this.showUsers ? this.collection : 
this.groupList;
+
+                       collection.changed_models().each(function(m){
+                               m.toServer();
+                               updateReq[m.get('id')] = m.get('isVisible');
+                       });
+
+                       var clearCache = function(coll){
+                _.each(Backbone.fetchCache._cache, function(url, val){
+                   var urlStr = coll.url;
+                   if((val.indexOf(urlStr) != -1)){
+                       Backbone.fetchCache.clearItem(val);
+                   }
+                });
+                coll.fetch({reset: true, cache : false});
+                       }
+                       if(this.showUsers){
+                               collection.setUsersVisibility(updateReq, {
+                                       success : function(){
+                                               that.chgFlags = [];
+                                               that.allowNavigation();
+                                               clearCache(collection);
+                                       }
+                               });
+                       } else {
+                           collection.setGroupsVisibility(updateReq, {
+                                       success : function(){
+                                               that.chgFlags = [];
+                                               that.allowNavigation();
+                                               clearCache(collection);
+                                       }
+                });
+                       }
+
+               },
                renderUserTab : function(){
                        var that = this;
                        if(_.isUndefined(this.collection)){
@@ -141,10 +227,26 @@ define(function(require){
                },
                renderUserListTable : function(){
                        var that = this;
-                       /*var tableRow = Backgrid.Row.extend({
+                       var tableRow = Backgrid.Row.extend({
+
+                               render: function () {
+                               tableRow.__super__.render.apply(this, 
arguments);
+                               if (this.model.get("isVisible") == 0) {
+                                       this.el.classList.add("tr-inactive");
+                               }
+                               return this;
+                               },                              
                                events: {
-                                       'click' : 'onClick'
+                                       'change' : 'onClickCheckbox'
+                               },
+                               onClickCheckbox: function(e) {
+                                       if (this.model.get("isVisible") == 0) {
+                                               
this.el.classList.add("tr-inactive");                                           
+                                       } else {
+                                               
this.el.classList.remove("tr-inactive");
+                                       };
                                },
+                               /*
                                initialize : function(){
                                        var that = this;
                                        var args = 
Array.prototype.slice.apply(arguments);
@@ -180,14 +282,14 @@ define(function(require){
                                                  console.log('error..');
                                          }
                                   });
-                               }
-                       });*/
+                               } */
+                       });
                        this.rTableList.show(new XATableLayout({
                                columns: this.getColumns(),
                                collection: this.collection,
                                includeFilter : false,
                                gridOpts : {
-//                                     row: tableRow,
+                                       row: tableRow,
                                        header : XABackgrid,
                                        emptyText : 'No Users found!'
                                }
@@ -198,6 +300,16 @@ define(function(require){
                getColumns : function(){
                        var cols = {
                                
+                               isVisible : {
+                                       label : 
localization.tt("lbl.isVisible"),
+                                       //cell : 
Backgrid.SelectCell.extend({className: 'cellWidth-1'}),
+                                       cell: "select-row",
+                                   headerCell: "select-all",
+                                       click : false,
+                                       drag : false,
+                                       editable : false,
+                                       sortable : false
+                               },
                                name : {
                                        label   : 
localization.tt("lbl.userName"),
                                        href: function(model){
@@ -205,8 +317,7 @@ define(function(require){
                                        },
                                        editable:false,
                                        sortable:false,
-                                       cell :'uri'
-                                               
+                                       cell :'uri'                             
                
                                },
                                emailAddress : {
                                        label   : 
localization.tt("lbl.emailAddress"),
@@ -364,6 +475,16 @@ define(function(require){
                getGroupColumns : function(){
                        var cols = {
                                
+                isVisible : {
+                                       label : 
localization.tt("lbl.isVisible"),
+                                       //cell : 
Backgrid.SelectCell.extend({className: 'cellWidth-1'}),
+                                       cell: "select-row",
+                                   headerCell: "select-all",
+                                       click : false,
+                                       drag : false,
+                                       editable : false,
+                                       sortable : false
+                               },
                                name : {
                                        label   : 
localization.tt("lbl.groupName"),
                                        href: function(model){
@@ -392,7 +513,7 @@ define(function(require){
                                        drag : false,
                                        editable:false,
                                        sortable:false,
-                               }
+                               },
                                /*status : {
                                        label : localization.tt("lbl.status"),
                                        cell    : 
Backgrid.HtmlCell.extend({className: 'cellWidth-1'}),
@@ -419,10 +540,12 @@ define(function(require){
                        if(this.showUsers){
                                placeholder = 
localization.tt('h.searchForYourUser');   
                                coll = this.collection;
-                               searchOpt = ['User Name','Email 
Address','Role','User Source'];//,'Start Date','End Date','Today'];
+                               searchOpt = ['User Name','Email 
Address','Visibility', 'Role','User Source'];//,'Start Date','End 
Date','Today'];
                                var userRoleList = 
_.map(XAEnums.UserRoles,function(obj,key){return {label:obj.label,value:key};});
-                               serverAttrName  = [{text : "User Name", label 
:"name"},{text : "Email Address", label :"emailAddress"},
+                               serverAttrName  = [     {text : "User Name", 
label :"name"},
+                                                                       {text : 
"Email Address", label :"emailAddress"},
                                                   {text : "Role", label 
:"userRoleList", 'multiple' : true, 'optionsArr' : userRoleList},
+                                                       {text : "Visibility", 
label :"isVisible", 'multiple' : true, 'optionsArr' : 
XAUtil.enumToSelectLabelValuePairs(XAEnums.VisibilityStatus)},
                                                   {text : "User Source", label 
:"userSource", 'multiple' : true, 'optionsArr' : 
XAUtil.enumToSelectLabelValuePairs(XAEnums.UserTypes)},
                                                                ];
                                                  // {text : 'Start Date',label 
:'startDate'},{text : 'End Date',label :'endDate'},
@@ -430,18 +553,20 @@ define(function(require){
                        }else{
                                placeholder = 
localization.tt('h.searchForYourGroup');
                                coll = this.groupList;
-                               searchOpt = ['Group Name','Group 
Source'];//,'Start Date','End Date','Today'];
+                               searchOpt = ['Group Name','Group Source', 
'Visibility'];//,'Start Date','End Date','Today'];
                                serverAttrName  = [{text : "Group Name", label 
:"name"},
+                                                  {text : "Visibility", label 
:"isVisible", 'multiple' : true, 'optionsArr' : 
XAUtil.enumToSelectLabelValuePairs(XAEnums.VisibilityStatus)},
                                                   {text : "Group Source", 
label :"groupSource", 'multiple' : true, 'optionsArr' : 
XAUtil.enumToSelectLabelValuePairs(XAEnums.GroupTypes)},];
                                
                                                   //{text : 'Start Date',label 
:'startDate'},{text : 'End Date',label :'endDate'},
                                                   //{text : 'Today',label 
:'today'}];
 
                        }
+                       var query = (!_.isUndefined(coll.VSQuery)) ? 
coll.VSQuery : '';
                        var pluginAttr = {
                                      placeholder :placeholder,
                                      container : this.ui.visualSearch,
-                                     query     : '',
+                                     query     : query,
                                      callbacks :  { 
                                          valueMatches :function(facet, 
searchTerm, callback) {
                                                                switch (facet) {
@@ -454,6 +579,9 @@ define(function(require){
                                                                        case 
'Group Source':
                                                                                
callback(XAUtil.hackForVSLabelValuePairs(XAEnums.GroupTypes));
                                                                                
break;          
+                                                                       case 
'Visibility':
+                                                                               
callback(XAUtil.hackForVSLabelValuePairs(XAEnums.VisibilityStatus));
+                                                                               
break;
                                                                        /*case 
'Start Date' :
                                                                                
setTimeout(function () { XAUtil.displayDatepicker(that.ui.visualSearch, 
callback); }, 0);
                                                                                
break;
@@ -489,6 +617,7 @@ define(function(require){
 
                /** on close */
                onClose: function(){
+                       XAUtil.allowNavigation();
                }
 
        });

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/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 57ce781..5f8e580 100644
--- a/security-admin/src/main/webapp/styles/xa.css
+++ b/security-admin/src/main/webapp/styles/xa.css
@@ -1763,4 +1763,19 @@ margin-top: -29px;
 }
 .margin-left-5{
        margin-left:5px;
+}
+.tr-inactive {
+  background-color: #F5F5F5;
+}
+.tr-inactive a {
+  color: #CCC;
+}
+.tr-inactive td span.label{
+  background-color: #BCBCBC;
+  color: #fff;
+  font-weight: normal;
+  text-shadow: none;
+}
+td.select-row-cell {
+  text-align: center;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html 
b/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
index 421ef53..21006b1 100644
--- a/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
+++ b/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
@@ -45,8 +45,10 @@
                <div class="clearfix">
                        <a href="#!/user/create" class="btn btn-primary 
btn-right" type="button" data-id="addNewUser"> {{tt 'lbl.addNewUser'}} </a>
                        <a href="#!/group/create" class="btn btn-primary 
btn-right" type="button" data-id="addNewGroup" style="display:none;"> {{tt 
'lbl.addNewGroup'}} </a>
+            <a href="javascript:void(0)" class="_allowNav btn btn-primary 
btn-right" type="button" data-id="save" style="display:block;" > {{tt 
'btn.setVisibility'}} </a>
                </div>
                <div data-id="r_tableList" class="clickable">
+          <b class="_prevNav"></b>
                </div>
        </div>
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2a309b5c/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
----------------------------------------------------------------------
diff --git 
a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java 
b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
index b05ebb4..4ae1d02 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
@@ -18,6 +18,7 @@ package org.apache.ranger.biz;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 
 import org.apache.ranger.common.ContextUtil;
@@ -30,6 +31,7 @@ import org.apache.ranger.db.XXGroupDao;
 import org.apache.ranger.db.XXGroupUserDao;
 import org.apache.ranger.db.XXUserDao;
 import org.apache.ranger.entity.XXGroup;
+import org.apache.ranger.entity.XXUser;
 import org.apache.ranger.security.context.RangerContextHolder;
 import org.apache.ranger.security.context.RangerSecurityContext;
 import org.apache.ranger.service.XGroupService;
@@ -59,7 +61,9 @@ import org.mockito.runners.MockitoJUnitRunner;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestXUserMgr {
 
-       private static Long userId = 1L;
+       private static Long userId = 10L;
+       
+       private static Integer emptyValue;
 
        @InjectMocks
        XUserMgr xUserMgr = new XUserMgr();
@@ -166,7 +170,75 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test13CreateXGroup() {
+       public void test13ModifyUserVisibilitySetOne() {
+               XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
+               XXUser xxUser = Mockito.mock(XXUser.class);
+               VXUser vxUser = vxUser();
+               
+               
Mockito.when(xUserService.updateResource(vxUser)).thenReturn(vxUser);           
+               HashMap<Long, Integer> visibilityMap = new HashMap<Long, 
Integer>();
+               Integer value = 1;
+               visibilityMap.put(userId, value);
+               
+               Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
+               Mockito.when(xxUserDao.getById(userId)).thenReturn(xxUser);
+               
Mockito.when(xUserService.populateViewBean(xxUser)).thenReturn(vxUser);
+               
+               xUserMgr.modifyUserVisibility(visibilityMap);
+               Assert.assertEquals(value, vxUser.getIsVisible());
+               Assert.assertEquals(userId, vxUser.getId());
+               Mockito.verify(xUserService).updateResource(vxUser);
+               Mockito.verify(daoManager).getXXUser();
+               Mockito.verify(xUserService).populateViewBean(xxUser);
+       }
+       
+       @Test
+       public void test14ModifyUserVisibilitySetZero() {
+               XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
+               XXUser xxUser = Mockito.mock(XXUser.class);
+               VXUser vxUser = vxUser();
+               
+               
Mockito.when(xUserService.updateResource(vxUser)).thenReturn(vxUser);           
+               HashMap<Long, Integer> visibilityMap = new HashMap<Long, 
Integer>();
+               Integer value = 0;
+               visibilityMap.put(userId, value);
+               
+               Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
+               Mockito.when(xxUserDao.getById(userId)).thenReturn(xxUser);
+               
Mockito.when(xUserService.populateViewBean(xxUser)).thenReturn(vxUser);
+               
+               xUserMgr.modifyUserVisibility(visibilityMap);           
+               Assert.assertEquals(value, vxUser.getIsVisible());
+               Assert.assertEquals(userId, vxUser.getId());
+               Mockito.verify(xUserService).updateResource(vxUser);
+               Mockito.verify(daoManager).getXXUser();
+               Mockito.verify(xUserService).populateViewBean(xxUser);
+       }
+       
+       @Test
+       public void test15ModifyUserVisibilitySetEmpty() {
+               XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
+               XXUser xxUser = Mockito.mock(XXUser.class);
+               VXUser vxUser = vxUser();
+               
+               
Mockito.when(xUserService.updateResource(vxUser)).thenReturn(vxUser);           
+               HashMap<Long, Integer> visibilityMap = new HashMap<Long, 
Integer>();
+               visibilityMap.put(userId, emptyValue);
+               
+               Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
+               Mockito.when(xxUserDao.getById(userId)).thenReturn(xxUser);
+               
Mockito.when(xUserService.populateViewBean(xxUser)).thenReturn(vxUser);
+               
+               xUserMgr.modifyUserVisibility(visibilityMap);           
+               Assert.assertEquals(emptyValue, vxUser.getIsVisible());
+               Assert.assertEquals(userId, vxUser.getId());
+               Mockito.verify(xUserService).updateResource(vxUser);
+               Mockito.verify(daoManager).getXXUser();
+               Mockito.verify(xUserService).populateViewBean(xxUser);
+       }
+
+       @Test
+       public void test16CreateXGroup() {
                setup();
                VXGroup vXGroup = new VXGroup();
                vXGroup.setId(userId);
@@ -195,7 +267,7 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test14UpdateXGroup() {
+       public void test17UpdateXGroup() {
                XXGroupDao xxGroupDao = Mockito.mock(XXGroupDao.class);
                setup();
                VXGroup vXGroup = new VXGroup();
@@ -220,7 +292,84 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test15createXGroupUser() {
+       public void test18ModifyGroupsVisibilitySetOne() {
+               XXGroupDao xxGroupDao = Mockito.mock(XXGroupDao.class);         
+               VXGroup vXGroup = new VXGroup();
+               vXGroup.setId(userId);
+               vXGroup.setDescription("group test");
+               vXGroup.setName("grouptest");
+
+               XXGroup xxGroup = new XXGroup();                
+               HashMap<Long, Integer> groupVisibilityMap = new HashMap<Long, 
Integer>();
+               Integer value = 1;
+               groupVisibilityMap.put(userId, value);
+               
+               Mockito.when(daoManager.getXXGroup()).thenReturn(xxGroupDao);
+               
Mockito.when(xxGroupDao.getById(vXGroup.getId())).thenReturn(xxGroup);
+               
Mockito.when(xGroupService.populateViewBean(xxGroup)).thenReturn(vXGroup);
+               
Mockito.when(xGroupService.updateResource(vXGroup)).thenReturn(vXGroup);
+       
+               xUserMgr.modifyGroupsVisibility(groupVisibilityMap);
+               Assert.assertEquals(value, vXGroup.getIsVisible());
+               Assert.assertEquals(userId, vXGroup.getId());           
+               Mockito.verify(daoManager).getXXGroup();
+               Mockito.verify(xGroupService).populateViewBean(xxGroup);
+               Mockito.verify(xGroupService).updateResource(vXGroup);
+       }
+       
+       @Test
+       public void test19ModifyGroupsVisibilitySetZero() {
+               XXGroupDao xxGroupDao = Mockito.mock(XXGroupDao.class);         
+               VXGroup vXGroup = new VXGroup();
+               vXGroup.setId(userId);
+               vXGroup.setDescription("group test");
+               vXGroup.setName("grouptest");
+
+               XXGroup xxGroup = new XXGroup();                
+               HashMap<Long, Integer> groupVisibilityMap = new HashMap<Long, 
Integer>();
+               Integer value = 0;
+               groupVisibilityMap.put(userId, value);
+               
+               Mockito.when(daoManager.getXXGroup()).thenReturn(xxGroupDao);
+               
Mockito.when(xxGroupDao.getById(vXGroup.getId())).thenReturn(xxGroup);
+               
Mockito.when(xGroupService.populateViewBean(xxGroup)).thenReturn(vXGroup);
+               
Mockito.when(xGroupService.updateResource(vXGroup)).thenReturn(vXGroup);
+       
+               xUserMgr.modifyGroupsVisibility(groupVisibilityMap);
+               Assert.assertEquals(value, vXGroup.getIsVisible());
+               Assert.assertEquals(userId, vXGroup.getId());           
+               Mockito.verify(daoManager).getXXGroup();
+               Mockito.verify(xGroupService).populateViewBean(xxGroup);
+               Mockito.verify(xGroupService).updateResource(vXGroup);
+       }
+       
+       @Test
+       public void test20ModifyGroupsVisibilitySetEmpty() {
+               XXGroupDao xxGroupDao = Mockito.mock(XXGroupDao.class);         
+               VXGroup vXGroup = new VXGroup();
+               vXGroup.setId(userId);
+               vXGroup.setDescription("group test");
+               vXGroup.setName("grouptest");
+
+               XXGroup xxGroup = new XXGroup();                
+               HashMap<Long, Integer> groupVisibilityMap = new HashMap<Long, 
Integer>();
+               groupVisibilityMap.put(userId, emptyValue);
+               
+               Mockito.when(daoManager.getXXGroup()).thenReturn(xxGroupDao);
+               
Mockito.when(xxGroupDao.getById(vXGroup.getId())).thenReturn(xxGroup);
+               
Mockito.when(xGroupService.populateViewBean(xxGroup)).thenReturn(vXGroup);
+               
Mockito.when(xGroupService.updateResource(vXGroup)).thenReturn(vXGroup);
+       
+               xUserMgr.modifyGroupsVisibility(groupVisibilityMap);
+               Assert.assertEquals(emptyValue, vXGroup.getIsVisible());
+               Assert.assertEquals(userId, vXGroup.getId());           
+               Mockito.verify(daoManager).getXXGroup();
+               Mockito.verify(xGroupService).populateViewBean(xxGroup);
+               Mockito.verify(xGroupService).updateResource(vXGroup);
+       }
+       
+       @Test
+       public void test21createXGroupUser() {
                VXGroupUser vxGroupUser = new VXGroupUser();
                vxGroupUser.setId(userId);
                vxGroupUser.setName("group user test");
@@ -263,13 +412,13 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test16GetXUserGroups() {
+       public void test22GetXUserGroups() {
                VXGroupList dbVXGroupList = xUserMgr.getXUserGroups(userId);
                Assert.assertNotNull(dbVXGroupList);
        }
 
        @Test
-       public void test17GetXGroupUsers() {
+       public void test23GetXGroupUsers() {
                VXUserList dbVXUserList = 
xUserMgr.getXGroupUsers(userId);VXGroup vXGroup = new VXGroup();
                vXGroup.setId(userId);
                vXGroup.setDescription("group test");
@@ -278,7 +427,7 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test18GetXUserByUserName() {
+       public void test24GetXUserByUserName() {
                VXUser vxUser = vxUser();
                String userName = "test";
 
@@ -295,7 +444,7 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test19CreateXUserWithOutLogin(){
+       public void test25CreateXUserWithOutLogin(){
                VXUser vxUser = vxUser();
        
                Mockito.when(xUserService.createXUserWithOutLogin(vxUser))
@@ -314,7 +463,7 @@ public class TestXUserMgr {
        }
        
        @Test
-       public void test20CreateXGroupWithoutLogin(){
+       public void test26CreateXGroupWithoutLogin(){
 
                VXGroup vXGroup = new VXGroup();
                vXGroup.setId(userId);
@@ -334,7 +483,7 @@ public class TestXUserMgr {
        }
        
        @Test
-       public void test21DeleteXGroup() {
+       public void test27DeleteXGroup() {
                XXGroupDao xxGroupDao = Mockito.mock(XXGroupDao.class);
 
                VXGroupUserList vxGroupUserList = new VXGroupUserList();
@@ -352,7 +501,7 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test22DeleteXUser() {
+       public void test28DeleteXUser() {
                XXGroupUserDao xxGroupDao = Mockito.mock(XXGroupUserDao.class);
                XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
                VXGroupUserList vxGroupUserList = new VXGroupUserList();
@@ -373,7 +522,7 @@ public class TestXUserMgr {
        }
 
        @Test
-       public void test23deleteXGroupAndXUser() {
+       public void test29deleteXGroupAndXUser() {
                VXUser vxUser = vxUser();
                VXGroup vxGroup = new VXGroup();
                VXGroupUserList vxGroupUserList = new VXGroupUserList();
@@ -397,7 +546,7 @@ public class TestXUserMgr {
        }
        
        @Test
-       public void test24CreateVXUserGroupInfo(){
+       public void test30CreateVXUserGroupInfo(){
        
                VXUserGroupInfo vXUserGroupInfo = new VXUserGroupInfo();
                VXUser vXUser = new VXUser();

Reply via email to