1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 22:10:55 +01:00

Add an administrative tool for deleting users

Summary:
Allow administrators to delete accounts if they jump through enough hoops.

Also remove bogus caption about usernames being uneditable since we let admins edit those too now.

Test Plan: Tried to delete myself. Deleted a non-myself user.

Reviewers: csilvers, vrana

Reviewed By: csilvers

CC: aran

Maniphest Tasks: T1184

Differential Revision: https://secure.phabricator.com/D2767
This commit is contained in:
epriestley 2012-06-15 17:02:20 -07:00
parent 31fcd78c76
commit 957f9e2ec5
3 changed files with 163 additions and 2 deletions

View file

@ -271,6 +271,77 @@ final class PhabricatorUserEditor {
}
/**
* @task role
*/
public function deleteUser(PhabricatorUser $user, $disable) {
$actor = $this->requireActor();
if (!$user->getID()) {
throw new Exception("User has not been created yet!");
}
if ($actor->getPHID() == $user->getPHID()) {
throw new Exception("You can not delete yourself!");
}
$user->openTransaction();
$ldaps = id(new PhabricatorUserLDAPInfo())->loadAllWhere(
'userID = %d',
$user->getID());
foreach ($ldaps as $ldap) {
$ldap->delete();
}
$oauths = id(new PhabricatorUserOAuthInfo())->loadAllWhere(
'userID = %d',
$user->getID());
foreach ($oauths as $oauth) {
$oauth->delete();
}
$prefs = id(new PhabricatorUserPreferences())->loadAllWhere(
'userPHID = %s',
$user->getPHID());
foreach ($prefs as $pref) {
$pref->delete();
}
$profiles = id(new PhabricatorUserProfile())->loadAllWhere(
'userPHID = %s',
$user->getPHID());
foreach ($profiles as $profile) {
$profile->delete();
}
$keys = id(new PhabricatorUserSSHKey())->loadAllWhere(
'userPHID = %s',
$user->getPHID());
foreach ($keys as $key) {
$key->delete();
}
$emails = id(new PhabricatorUserEmail())->loadAllWhere(
'userPHID = %s',
$user->getPHID());
foreach ($emails as $email) {
$email->delete();
}
$log = PhabricatorUserLog::newLog(
$actor,
$user,
PhabricatorUserLog::ACTION_DELETE);
$log->save();
$user->delete();
$user->saveTransaction();
return $this;
}
/* -( Adding, Removing and Changing Email )-------------------------------- */

View file

@ -54,6 +54,7 @@ final class PhabricatorPeopleEditController
$nav->addFilter('cert', 'Conduit Certificate');
$nav->addSpacer();
$nav->addFilter('rename', 'Change Username');
$nav->addFilter('delete', 'Delete User');
if (!$user->getID()) {
$this->view = 'basic';
@ -83,6 +84,9 @@ final class PhabricatorPeopleEditController
case 'rename':
$response = $this->processRenameRequest($user);
break;
case 'delete':
$response = $this->processDeleteRequest($user);
break;
default:
return new Aphront404Response();
}
@ -231,8 +235,7 @@ final class PhabricatorPeopleEditController
->setName('username')
->setValue($user->getUsername())
->setError($e_username)
->setDisabled($is_immutable)
->setCaption('Usernames are permanent and can not be changed later!'))
->setDisabled($is_immutable))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Real Name')
@ -565,7 +568,93 @@ final class PhabricatorPeopleEditController
return array($errors, $panel);
}
private function processDeleteRequest(PhabricatorUser $user) {
$request = $this->getRequest();
$admin = $request->getUser();
if ($user->getPHID() == $admin->getPHID()) {
$error = new AphrontErrorView();
$error->setTitle('You Shall Journey No Farther');
$error->appendChild(
'<p>As you stare into the gaping maw of the abyss, something holds '.
'you back.</p>'.
'<p>You can not delete your own account.</p>');
return $error;
}
$e_username = true;
$username = null;
$errors = array();
if ($request->isFormPost()) {
$username = $request->getStr('username');
if (!strlen($username)) {
$e_username = 'Required';
$errors[] = 'You must type the username to confirm deletion.';
} else if ($username != $user->getUsername()) {
$e_username = 'Invalid';
$errors[] = 'You must type the username correctly.';
}
if (!$errors) {
id(new PhabricatorUserEditor())
->setActor($admin)
->deleteUser($user);
return id(new AphrontRedirectResponse())->setURI('/people/');
}
}
if ($errors) {
$errors = id(new AphrontErrorView())
->setTitle('Form Errors')
->setErrors($errors);
} else {
$errors = null;
}
$form = new AphrontFormView();
$form
->setUser($admin)
->setAction($request->getRequestURI())
->appendChild(
'<p class="aphront-form-instructions">'.
'<strong>Be careful when deleting users!</strong> '.
'If this user interacted with anything, it is generally better '.
'to disable them, not delete them. If you delete them, it will '.
'no longer be possible to search for their objects, for example, '.
'and you will lose other information about their history. Disabling '.
'them instead will prevent them from logging in but not destroy '.
'any of their data.'.
'</p>'.
'<p class="aphront-form-instructions">'.
'It is generally safe to delete newly created users (and test users '.
'and so on), but less safe to delete established users. If '.
'possible, disable them instead.'.
'</p>')
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Username')
->setValue($user->getUsername()))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Confirm')
->setValue($username)
->setName('username')
->setCaption("Type the username again to confirm deletion.")
->setError($e_username))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Delete User'));
$panel = new AphrontPanelView();
$panel->setHeader('Delete User');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return array($errors, $panel);
}
private function getRoleInstructions() {
$roles_link = phutil_render_tag(

View file

@ -28,6 +28,7 @@ final class PhabricatorUserLog extends PhabricatorUserDAO {
const ACTION_ADMIN = 'admin';
const ACTION_DISABLE = 'disable';
const ACTION_DELETE = 'delete';
const ACTION_CONDUIT_CERTIFICATE = 'conduit-cert';
const ACTION_CONDUIT_CERTIFICATE_FAILURE = 'conduit-cert-fail';