Repository: incubator-ranger Updated Branches: refs/heads/master 66c303489 -> 2836dea0b
RANGER-888 : Provide support to delete Users and Groups from Ranger Admin UI Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/2836dea0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/2836dea0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/2836dea0 Branch: refs/heads/master Commit: 2836dea0b2ff4ed42e0130086d07e183b03362fc Parents: 66c3034 Author: Pradeep Agrawal <[email protected]> Authored: Wed Mar 23 15:59:43 2016 +0530 Committer: Gautam Borad <[email protected]> Committed: Wed Mar 23 18:05:48 2016 +0530 ---------------------------------------------------------------------- .../java/org/apache/ranger/biz/XUserMgr.java | 20 ++++- .../java/org/apache/ranger/rest/XUserREST.java | 42 +++++++++ .../webapp/scripts/model_bases/VXGroupBase.js | 15 +++- .../webapp/scripts/model_bases/VXUserBase.js | 14 ++- .../scripts/views/users/UserTableLayout.js | 91 +++++++++++++++++++- .../templates/users/UserTableLayout_tmpl.html | 3 + 6 files changed, 177 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2836dea0/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 5aed040..e9c8394 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 @@ -1601,7 +1601,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); @@ -1781,4 +1781,22 @@ public class XUserMgr extends XUserMgrBase { policyItems.removeAll(itemsToRemove); } } + + 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/2836dea0/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..1441ff5 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,45 @@ 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/2836dea0/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..96e0946 100644 --- a/security-admin/src/main/webapp/scripts/model_bases/VXGroupBase.js +++ b/security-admin/src/main/webapp/scripts/model_bases/VXGroupBase.js @@ -87,9 +87,20 @@ 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/2836dea0/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..db6d511 100644 --- a/security-admin/src/main/webapp/scripts/model_bases/VXUserBase.js +++ b/security-admin/src/main/webapp/scripts/model_bases/VXUserBase.js @@ -24,7 +24,6 @@ define(function(require){ var XABaseModel = require('models/XABaseModel'); var XAGlobals = require('utils/XAGlobals'); - var VXUserBase = XABaseModel.extend( /** @lends VXUserBase.prototype */ { @@ -41,7 +40,18 @@ 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/2836dea0/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 e2b2f85..ecd97e8 100644 --- a/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js +++ b/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js @@ -35,6 +35,8 @@ define(function(require){ 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 +65,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 +78,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; }, @@ -205,7 +209,9 @@ define(function(require){ this.renderUserListTable(); _.extend(this.collection.queryParams, XAUtil.getUserDataParams()) this.collection.fetch({ - cache:true, + //cache:true, + reset: true, + cache: false // data : XAUtil.getUserDataParams(), }).done(function(){ if(!_.isString(that.ui.addNewGroup)){ @@ -225,7 +231,9 @@ define(function(require){ this.groupList.selectNone(); this.renderGroupListTable(); this.groupList.fetch({ - cache:true + //cache:true, + reset:true, + cache: false }).done(function(){ that.ui.addNewUser.hide(); that.ui.addNewGroup.show(); @@ -469,6 +477,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 that = this; var coll,placeholder; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2836dea0/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">
