Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: proper error handling when deleting users/groups is failing #41077

Merged
merged 1 commit into from Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/unreleased/41077
@@ -0,0 +1,4 @@
Bugfix: Proper error handling when deleting users or groups

https://github.com/owncloud/core/pull/41077
https://github.com/owncloud/core/pull/41075
81 changes: 9 additions & 72 deletions settings/js/users/deleteHandler.js
Expand Up @@ -16,8 +16,9 @@
* marking the object for deletion.
* @param {removeCallback} removeCallback the function to be called after
* successful delete.
* @param {undoCallback} undoCallback called after "undo" was clicked
*/
function DeleteHandler(endpoint, paramID, markCallback, removeCallback) {
function DeleteHandler(endpoint, paramID, markCallback, removeCallback, undoCallback) {
this.oidToDelete = false;
this.canceled = false;

Expand All @@ -26,69 +27,8 @@ function DeleteHandler(endpoint, paramID, markCallback, removeCallback) {

this.markCallback = markCallback;
this.removeCallback = removeCallback;
this.undoCallback = false;

this.notifier = false;
this.notificationDataID = false;
this.notificationMessage = false;
this.notificationPlaceholder = '%oid';
}

/**
* Number of milliseconds after which the operation is performed.
*/
DeleteHandler.TIMEOUT_MS = 7000;

/**
* Timer after which the action will be performed anyway.
*/
DeleteHandler.prototype._timeout = null;

/**
* enabled the notification system. Required for undo UI.
*
* @param {object} notifier Usually OC.Notification
* @param {string} dataID an identifier for the notifier, e.g. 'deleteuser'
* @param {string} message the message that should be shown upon delete. %oid
* will be replaced with the affected id of the item to be deleted
* @param {undoCallback} undoCallback called after "undo" was clicked
*/
DeleteHandler.prototype.setNotification = function(notifier, dataID, message, undoCallback) {
this.notifier = notifier;
this.notificationDataID = dataID;
this.notificationMessage = message;
this.undoCallback = undoCallback;

var dh = this;

$('#notification')
.off('click.deleteHandler_' + dataID)
.on('click.deleteHandler_' + dataID, '.undo', function () {
if ($('#notification').data(dh.notificationDataID)) {
var oid = dh.oidToDelete;
dh.cancel();
if(typeof dh.undoCallback !== 'undefined') {
dh.undoCallback(oid);
}
}
dh.notifier.hide();
});
};

/**
* shows the Undo Notification (if configured)
*/
DeleteHandler.prototype.showNotification = function() {
if(this.notifier !== false) {
if(!this.notifier.isHidden()) {
this.hideNotification();
}
$('#notification').data(this.notificationDataID, true);
var msg = this.notificationMessage.replace(
this.notificationPlaceholder, escapeHTML(decodeURIComponent(this.oidToDelete)));
this.notifier.showHtml(msg);
}
};
}

/**
* initializes the delete operation for a given object id
Expand All @@ -105,20 +45,14 @@ DeleteHandler.prototype.mark = function(oid) {
* initialized by mark(). On error, it will show a message via
* OC.dialogs.alert. On success, a callback is fired so that the client can
* update the web interface accordingly.
*
* @param {boolean} [keepNotification] true to keep the notification, false to hide
* it, defaults to false
*/
DeleteHandler.prototype.deleteEntry = function(keepNotification) {
DeleteHandler.prototype.deleteEntry = function() {
var deferred = $.Deferred();
if(this.oidToDelete === false) {
return deferred.resolve().promise();
}

var dh = this;
if(!keepNotification && $('#notification').data(this.notificationDataID) === true) {
dh.hideNotification();
}

var payload = {};
payload[dh.ajaxParamID] = dh.oidToDelete;
Expand All @@ -134,9 +68,12 @@ DeleteHandler.prototype.deleteEntry = function(keepNotification) {
dh.removeCallback(dh.oidToDelete);
},
error: function (jqXHR) {
OC.dialogs.alert(jqXHR.responseJSON.data.message, t('settings', 'Unable to delete {objName}', {objName: decodeURIComponent(dh.oidToDelete)}));
var msg = 'Unknown error';
if (jqXHR.responseJSON && jqXHR.responseJSON.data && jqXHR.responseJSON.data.message) {
msg = jqXHR.responseJSON.data.message;
}
OC.dialogs.alert(msg, t('settings', 'Unable to delete {objName}', {objName: decodeURIComponent(dh.oidToDelete)}));
dh.undoCallback(dh.oidToDelete);

}
});
};
8 changes: 2 additions & 6 deletions settings/js/users/groups.js
Expand Up @@ -6,6 +6,7 @@
*/

var GroupList;
var GroupDeleteHandler;

(function () {
GroupList = {
Expand Down Expand Up @@ -287,12 +288,7 @@ var GroupList;
initDeleteHandling: function () {
//set up handler
GroupDeleteHandler = new DeleteHandler('/settings/users/groups', 'groupname',
GroupList.hide, GroupList.remove);

var msg = escapeHTML(t('settings', 'deleted {groupName}', {groupName: '%oid'})) + '<span class="undo">' +
escapeHTML(t('settings', 'undo')) + '</span>';
GroupDeleteHandler.setNotification(OC.Notification, 'deletegroup', msg,
GroupList.remove);
GroupList.hide, GroupList.remove, GroupList.show);

//when to mark user for delete
this.$userGroupList.on('click', '.delete', function () {
Expand Down
9 changes: 1 addition & 8 deletions settings/js/users/users.js
Expand Up @@ -349,14 +349,7 @@ var UserList = {
initDeleteHandling: function() {
//set up handler
UserDeleteHandler = new DeleteHandler('/settings/users/users', 'username',
UserList.markRemove, UserList.remove);

//configure undo
OC.Notification.hide();
var msg = escapeHTML(t('settings', 'deleted {userName}', {userName: '%oid'})) + '<span class="undo">' +
escapeHTML(t('settings', 'undo')) + '</span>';
UserDeleteHandler.setNotification(OC.Notification, 'deleteuser', msg,
UserList.undoRemove);
UserList.markRemove, UserList.remove, UserList.undoRemove);

//when to mark user for delete
$userListBody.on('click', '.delete', function () {
Expand Down
4 changes: 1 addition & 3 deletions settings/tests/js/users/deleteHandlerSpec.js
Expand Up @@ -28,9 +28,7 @@ describe('DeleteHandler tests', function() {
var undoCallback;

function init(markCallback, removeCallback, undoCallback) {
var handler = new DeleteHandler('dummyendpoint.php', 'paramid', markCallback, removeCallback);
handler.setNotification(OC.Notification, 'dataid', 'removed %oid entry', undoCallback);
return handler;
return new DeleteHandler('dummyendpoint.php', 'paramid', markCallback, removeCallback, undoCallback);
}

beforeEach(function() {
Expand Down