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

incubator-ranger git commit: RANGER-888 : Provide support to delete Users and Groups from Ranger Admin UI

Repository: incubator-ranger
Updated Branches:
  refs/heads/ranger-0.5 514ed055f -> 7cb59517e


RANGER-888 : Provide support to delete Users and Groups from Ranger Admin UI

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


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

Branch: refs/heads/ranger-0.5
Commit: 7cb59517efc2eac2637d5a2c9eca106ec01a0951
Parents: 514ed05
Author: Pradeep Agrawal <pr...@freestoneinfotech.com>
Authored: Fri Apr 15 17:33:08 2016 +0530
Committer: Gautam Borad <ga...@apache.org>
Committed: Fri Apr 15 18:23:45 2016 +0530

----------------------------------------------------------------------
 .../java/org/apache/ranger/biz/XUserMgr.java    | 19 ++++-
 .../java/org/apache/ranger/rest/XUserREST.java  | 41 +++++++++
 .../webapp/scripts/model_bases/VXGroupBase.js   | 12 ++-
 .../webapp/scripts/model_bases/VXUserBase.js    | 12 ++-
 .../scripts/views/users/UserTableLayout.js      | 89 +++++++++++++++++++-
 .../templates/users/UserTableLayout_tmpl.html   |  3 +
 6 files changed, 167 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7cb59517/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 e05a58e..f9911f9 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
@@ -1592,7 +1592,7 @@ public class XUserMgr extends XUserMgrBase {
 		if (logger.isDebugEnabled()) {
 			logger.debug("Force delete status="+force+" for user="+vXUser.getName());
 		}
-
+		restrictSelfAccountDeletion(vXUser.getName().trim());
 		SearchCriteria searchCriteria = new SearchCriteria();
 		searchCriteria.addParam("xUserId", id);
 		VXGroupUserList vxGroupUserList = searchXGroupUsers(searchCriteria);
@@ -1813,4 +1813,21 @@ public class XUserMgr extends XUserMgrBase {
 	        }
 	        return createdXUser;
 	}
+	public void restrictSelfAccountDeletion(String loginID) {
+		UserSessionBase session = ContextUtil.getCurrentUserSession();
+		if (session != null) {
+			if (!session.isUserAdmin()) {
+				throw restErrorUtil.create403RESTException("Operation denied. LoggedInUser= "+session.getXXPortalUser().getLoginId() + " isn't permitted to perform the action.");
+			}else{
+				if(!StringUtil.isEmpty(loginID) && loginID.equals(session.getLoginId())){
+					throw restErrorUtil.create403RESTException("Operation denied. LoggedInUser= "+session.getXXPortalUser().getLoginId() + " isn't permitted to delete his own profile.");
+				}
+			}
+		} else {
+			VXResponse vXResponse = new VXResponse();
+			vXResponse.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
+			vXResponse.setMsgDesc("Bad Credentials");
+			throw restErrorUtil.generateRESTException(vXResponse);
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7cb59517/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 0f5a462..1dd7e65 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
@@ -73,6 +73,7 @@ import org.apache.ranger.view.VXModuleDef;
 import org.apache.ranger.view.VXModuleDefList;
 import org.apache.ranger.view.VXPermMap;
 import org.apache.ranger.view.VXPermMapList;
+import org.apache.ranger.view.VXString;
 import org.apache.ranger.view.VXStringList;
 import org.apache.ranger.view.VXUser;
 import org.apache.ranger.view.VXUserGroupInfo;
@@ -1002,4 +1003,44 @@ public class XUserREST {
 		vXStringList=xUserMgr.getUserRolesByName(userName);
 		return vXStringList;
 	}
+
+	@DELETE
+	@Path("/secure/users/delete")
+	@Produces({ "application/xml", "application/json" })
+	@PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
+	public void deleteUsersByUserName(@Context HttpServletRequest request,VXStringList userList){
+		String forceDeleteStr = request.getParameter("forceDelete");
+		boolean forceDelete = false;
+		if(StringUtils.isNotEmpty(forceDeleteStr) && "true".equalsIgnoreCase(forceDeleteStr)) {
+			forceDelete = true;
+		}
+		if(userList!=null && userList.getList()!=null){
+			for(VXString userName:userList.getList()){
+				if(StringUtils.isNotEmpty(userName.getValue())){
+					VXUser vxUser = xUserService.getXUserByUserName(userName.getValue());
+					xUserMgr.deleteXUser(vxUser.getId(), forceDelete);
+				}
+			}
+		}
+	}
+
+	@DELETE
+	@Path("/secure/groups/delete")
+	@Produces({ "application/xml", "application/json" })
+	@PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
+	public void deleteGroupsByGroupName(@Context HttpServletRequest request,VXStringList groupList) {
+		String forceDeleteStr = request.getParameter("forceDelete");
+		boolean forceDelete = false;
+		if(StringUtils.isNotEmpty(forceDeleteStr) && "true".equalsIgnoreCase(forceDeleteStr)) {
+			forceDelete = true;
+		}
+		if(groupList!=null && groupList.getList()!=null){
+			for(VXString groupName:groupList.getList()){
+				if(StringUtils.isNotEmpty(groupName.getValue())){
+					VXGroup vxGroup = xGroupService.getGroupByGroupName(groupName.getValue());
+					xUserMgr.deleteXGroup(vxGroup.getId(), forceDelete);
+				}
+			}
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7cb59517/security-admin/src/main/webapp/scripts/model_bases/VXGroupBase.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/model_bases/VXGroupBase.js b/security-admin/src/main/webapp/scripts/model_bases/VXGroupBase.js
index 39de8db..ff73a18 100644
--- a/security-admin/src/main/webapp/scripts/model_bases/VXGroupBase.js
+++ b/security-admin/src/main/webapp/scripts/model_bases/VXGroupBase.js
@@ -87,8 +87,16 @@ define(function(require){
 		 */
 		initialize: function() {
 			this.modelName = 'VXGroupBase';
-		}
-
+		},
+		deleteGroups : function(groupNameValues, options){
+			var url = this.urlRoot  + '/delete?forceDelete=true';
+			options = _.extend({
+				data : JSON.stringify(groupNameValues),
+				contentType : 'application/json',
+				dataType : 'json',
+			}, options);
+		return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options);
+		},
 	}, {
 		// static class members
 	});

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7cb59517/security-admin/src/main/webapp/scripts/model_bases/VXUserBase.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/model_bases/VXUserBase.js b/security-admin/src/main/webapp/scripts/model_bases/VXUserBase.js
index c97a425..e06ba66 100644
--- a/security-admin/src/main/webapp/scripts/model_bases/VXUserBase.js
+++ b/security-admin/src/main/webapp/scripts/model_bases/VXUserBase.js
@@ -41,8 +41,16 @@ define(function(require){
 		 */
 		initialize: function() {
 			this.modelName = 'VXUserBase';
-		}
-
+		},
+		deleteUsers : function(userNameValues,options){
+			var url = this.urlRoot + '/delete?forceDelete=true';
+			options = _.extend({
+				data : JSON.stringify(userNameValues),
+				contentType : 'application/json',
+				dataType : 'json',
+			}, options);
+			return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options);
+		},
 	}, {
 		// static class members
 	});

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7cb59517/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 2908d3a..ccb29a3 100644
--- a/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
+++ b/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
@@ -34,7 +34,7 @@ define(function(require){
 	var VXUserList		= require('collections/VXUserList');
 	var XATableLayout	= require('views/common/XATableLayout');
 	var vUserInfo		= require('views/users/UserInfo');
-
+	var VXUser          = require('models/VXUser');
 	var UsertablelayoutTmpl = require('hbs!tmpl/users/UserTableLayout_tmpl');
 
 	var UserTableLayout = Backbone.Marionette.Layout.extend(
@@ -63,7 +63,8 @@ define(function(require){
 			visibilityDropdown		: '[data-id="visibilityDropdown"]',
 			activeStatusDropdown		: '[data-id="activeStatusDropdown"]',
 			activeStatusDiv		:'[data-id="activeStatusDiv"]',
-			addNewBtnDiv	: '[data-id="addNewBtnDiv"]'
+			addNewBtnDiv    : '[data-id="addNewBtnDiv"]',
+			deleteUser: '[data-id="deleteUserGroup"]'
     	},
 
 		/** ui events hash */
@@ -75,6 +76,7 @@ define(function(require){
 			events['click ' + this.ui.btnSave]  = 'onSave';
 			events['click ' + this.ui.visibilityDropdown +' li a']  = 'onVisibilityChange';
 			events['click ' + this.ui.activeStatusDropdown +' li a']  = 'onStatusChange';
+			events['click ' + this.ui.deleteUser] = 'onDeleteUser';
 			return events;
 		},
 
@@ -207,7 +209,8 @@ define(function(require){
 			this.renderUserListTable();
 			_.extend(this.collection.queryParams, XAUtil.getUserDataParams())
 			this.collection.fetch({
-				cache:true,
+				reset: true,
+				cache: false
 //				data : XAUtil.getUserDataParams(),
 			}).done(function(){
 				if(!_.isString(that.ui.addNewGroup)){
@@ -227,7 +230,8 @@ define(function(require){
 			this.groupList.selectNone();
 			this.renderGroupListTable();
 			this.groupList.fetch({
-				cache:true
+				reset:true,
+				cache: false
 			}).done(function(){
 				that.ui.addNewUser.hide();
 				that.ui.addNewGroup.show();
@@ -468,6 +472,83 @@ define(function(require){
 			};
 			return this.groupList.constructor.getTableCols(cols, this.groupList);
 		},
+
+		onUserGroupDeleteSuccess: function(jsonUsers,collection){
+			_.each(jsonUsers.vXStrings,function(ob){
+				var model = _.find(collection.models, function(mo){
+					if(mo.get('name') === ob.value)
+						return mo;
+					});
+				collection.remove(model.get('id'));
+			});
+		},
+
+		onDeleteUser: function(e){
+
+			var that = this;
+			var collection = that.showUsers ? that.collection : that.groupList;
+			var selArr = [];
+			var message = '';
+			_.each(collection.selected,function(obj){
+				selArr.push(obj.get('name'));
+			});
+			var  vXStrings = [];
+			var jsonUsers  = {};
+			for(var i in selArr) {
+				var item = selArr[i];
+				vXStrings.push({
+					"value" : item,
+				});
+			}
+			jsonUsers.vXStrings = vXStrings;
+
+			var total_selected = jsonUsers.vXStrings.length;
+
+			if(total_selected == 1) {
+				message = 'Are you sure you want to delete '+(that.showUsers ? 'user':'group')+' \''+jsonUsers.vXStrings[0].value+'\'?';
+			}
+			else {
+				message = 'Are you sure you want to delete '+total_selected+' '+(that.showUsers ? 'users':'groups')+'?';
+			}
+			if(total_selected > 0){
+				XAUtil.confirmPopup({
+					msg: message,
+					callback: function(){
+						XAUtil.blockUI();
+						if(that.showUsers){
+							var model = new VXUser();
+							model.deleteUsers(jsonUsers,{
+								success: function(response,options){
+									XAUtil.blockUI('unblock');
+									that.onUserGroupDeleteSuccess(jsonUsers,collection);
+									XAUtil.notifySuccess('Success','User deleted successfully!');
+									that.collection.selected = {};
+								},
+								error:function(response,options){
+									XAUtil.blockUI('unblock');
+									XAUtil.notifyError('Error', 'Error deleting User!');
+								}
+							});
+						}
+						else {
+							var model = new VXGroup();
+							model.deleteGroups(jsonUsers,{
+								success: function(response){
+									XAUtil.blockUI('unblock');
+									that.onUserGroupDeleteSuccess(jsonUsers,collection);
+									XAUtil.notifySuccess('Success','Group deleted successfully!');
+									that.groupList.selected  = {};
+								},
+								error:function(response,options){
+									XAUtil.blockUI('unblock');
+									XAUtil.notifyError('Error', 'Error deleting Group!');
+								}
+							});
+						}
+					}
+				});
+			}
+		},
 		addVisualSearch : function(){
 			var coll,placeholder, that = this;
 			var searchOpt = [], serverAttrName = [];

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7cb59517/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 5d38022..f7c90f3 100644
--- a/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
+++ b/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
@@ -30,6 +30,9 @@
 			<div class="visual_search"></div>
 		</div>
 		<div class="clearfix" data-id="addNewBtnDiv">
+			{{#isSystemAdmin .}}
+				<a href="javascript:void(0);" data-id="deleteUserGroup" title="Permanently delete selected users/groups" class="btn btn-primary btn-right btn-danger"><i class="icon-trash icon-large" /></a>
+			{{/isSystemAdmin}}
 			<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>
       <div class="btn-group btn-right">