Disable as Spam - admin-only option to handle spammers
This implements a convenient way to handle spam users, mimicking the steps the admins already do manually: Performed tasks: * Disable Account * Real Name -> "spam" * Title -> "" * Icon → "" * Blurb → "" * Profile Picture → default This is disabling the account using the same functionality as the "Disable User" button. And on top of that it replaces the account real name with "spam" and wipe the other personal information. Note that this doesn't delete any posts from the user. Reviewers: sergey https://developer.blender.org/D11904
This commit is contained in:
@@ -2166,6 +2166,7 @@ phutil_register_library_map(array(
|
||||
'PasteSearchConduitAPIMethod' => 'applications/paste/conduit/PasteSearchConduitAPIMethod.php',
|
||||
'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php',
|
||||
'PeopleCreateUsersCapability' => 'applications/people/capability/PeopleCreateUsersCapability.php',
|
||||
'PeopleDisableSpamUsersCapability' => 'applications/people/capability/PeopleDisableSpamUsersCapability.php',
|
||||
'PeopleDisableUsersCapability' => 'applications/people/capability/PeopleDisableUsersCapability.php',
|
||||
'PeopleHovercardEngineExtension' => 'applications/people/engineextension/PeopleHovercardEngineExtension.php',
|
||||
'PeopleMainMenuBarExtension' => 'applications/people/engineextension/PeopleMainMenuBarExtension.php',
|
||||
@@ -4167,6 +4168,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleRenameController' => 'applications/people/controller/PhabricatorPeopleRenameController.php',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleRevisionsProfileMenuItem.php',
|
||||
'PhabricatorPeopleSearchEngine' => 'applications/people/query/PhabricatorPeopleSearchEngine.php',
|
||||
'PhabricatorPeopleSpamController' => 'applications/people/controller/PhabricatorPeopleSpamController.php',
|
||||
'PhabricatorPeopleTasksProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleTasksProfileMenuItem.php',
|
||||
'PhabricatorPeopleTestDataGenerator' => 'applications/people/lipsum/PhabricatorPeopleTestDataGenerator.php',
|
||||
'PhabricatorPeopleTransactionQuery' => 'applications/people/query/PhabricatorPeopleTransactionQuery.php',
|
||||
@@ -5059,6 +5061,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorUserCustomFieldNumericIndex' => 'applications/people/storage/PhabricatorUserCustomFieldNumericIndex.php',
|
||||
'PhabricatorUserCustomFieldStringIndex' => 'applications/people/storage/PhabricatorUserCustomFieldStringIndex.php',
|
||||
'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
|
||||
'PhabricatorUserDisableSpamTransaction' => 'applications/people/xaction/PhabricatorUserDisableSpamTransaction.php',
|
||||
'PhabricatorUserDisableTransaction' => 'applications/people/xaction/PhabricatorUserDisableTransaction.php',
|
||||
'PhabricatorUserEditEngine' => 'applications/people/editor/PhabricatorUserEditEngine.php',
|
||||
'PhabricatorUserEditor' => 'applications/people/editor/PhabricatorUserEditor.php',
|
||||
@@ -8473,6 +8476,7 @@ phutil_register_library_map(array(
|
||||
'PasteSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleDisableSpamUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleDisableUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||
'PeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
@@ -10790,6 +10794,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleRenameController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorPeopleSpamController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleTasksProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleTestDataGenerator' => 'PhabricatorTestDataGenerator',
|
||||
'PhabricatorPeopleTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
@@ -11860,6 +11865,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorUserCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
|
||||
'PhabricatorUserCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
|
||||
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorUserDisableSpamTransaction' => 'PhabricatorUserTransactionType',
|
||||
'PhabricatorUserDisableTransaction' => 'PhabricatorUserTransactionType',
|
||||
'PhabricatorUserEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorUserEditor' => 'PhabricatorEditor',
|
||||
|
@@ -58,6 +58,7 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
|
||||
=> 'PhabricatorPeopleDisableController',
|
||||
'(?P<via>disable)/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorPeopleDisableController',
|
||||
'spam/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleSpamController',
|
||||
'empower/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleEmpowerController',
|
||||
'delete/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleDeleteController',
|
||||
'rename/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleRenameController',
|
||||
@@ -99,6 +100,9 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
|
||||
PeopleDisableUsersCapability::CAPABILITY => array(
|
||||
'default' => PhabricatorPolicies::POLICY_ADMIN,
|
||||
),
|
||||
PeopleDisableSpamUsersCapability::CAPABILITY => array(
|
||||
'default' => PhabricatorPolicies::POLICY_ADMIN,
|
||||
),
|
||||
PeopleBrowseUserDirectoryCapability::CAPABILITY => array(),
|
||||
);
|
||||
}
|
||||
|
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
final class PeopleDisableSpamUsersCapability
|
||||
extends PhabricatorPolicyCapability {
|
||||
|
||||
const CAPABILITY = 'people.disable_spam.users';
|
||||
|
||||
public function getCapabilityName() {
|
||||
return pht('Can Disable Spammers');
|
||||
}
|
||||
|
||||
public function describeCapabilityRejection() {
|
||||
return pht('You do not have permission to handle spam users.');
|
||||
}
|
||||
|
||||
}
|
@@ -93,6 +93,10 @@ final class PhabricatorPeopleProfileManageController
|
||||
PeopleDisableUsersCapability::CAPABILITY);
|
||||
$can_disable = ($has_disable && !$is_self);
|
||||
|
||||
$has_disable_spam_capability = $this->hasApplicationCapability(
|
||||
PeopleDisableSpamUsersCapability::CAPABILITY);
|
||||
$can_disable_spam = ($has_disable_spam_capability && !$is_self);
|
||||
|
||||
$id = $user->getID();
|
||||
|
||||
$welcome_engine = id(new PhabricatorPeopleWelcomeMailEngine())
|
||||
@@ -193,6 +197,14 @@ final class PhabricatorPeopleProfileManageController
|
||||
->setWorkflow(true)
|
||||
->setHref($this->getApplicationURI('disable/'.$id.'/')));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-shield')
|
||||
->setName(pht('Disable as Spam'))
|
||||
->setDisabled(!$can_disable_spam)
|
||||
->setWorkflow(true)
|
||||
->setHref($this->getApplicationURI('spam/'.$id.'/')));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-times')
|
||||
|
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorPeopleSpamController
|
||||
extends PhabricatorPeopleController {
|
||||
|
||||
public function shouldRequireAdmin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->requireApplicationCapability(
|
||||
PeopleDisableUsersCapability::CAPABILITY);
|
||||
|
||||
$actor = $viewer;
|
||||
$done_uri = $this->getApplicationURI("manage/{$id}/");
|
||||
|
||||
if ($viewer->getPHID() == $user->getPHID()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Something Stays Your Hand'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Try as you might, you find you can not disable your own account.'))
|
||||
->addCancelButton($done_uri, pht('Curses!'));
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
// Disable the account.
|
||||
if (!$user->getIsDisabled()) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorUserTransaction())
|
||||
->setTransactionType(PhabricatorUserDisableTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(true);
|
||||
|
||||
id(new PhabricatorUserTransactionEditor())
|
||||
->setActor($actor)
|
||||
->setActingAsPHID($viewer->getPHID())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($user, $xactions);
|
||||
}
|
||||
|
||||
// Set profile info to spam and blank to everything else.
|
||||
{
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorUserTransaction())
|
||||
->setTransactionType(PhabricatorUserDisableSpamTransaction::TRANSACTIONTYPE);
|
||||
|
||||
id(new PhabricatorUserTransactionEditor())
|
||||
->setActor($actor)
|
||||
->setActingAsPHID($viewer->getPHID())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($user, $xactions);
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
||||
}
|
||||
|
||||
$title = pht('Disable as Spam?');
|
||||
$short_title = pht('Disable as Spam');
|
||||
|
||||
$body = pht(
|
||||
'Is %s\'s profile spam?<br />All the profile info will be erased and '.
|
||||
'they will no longer be able to access Phabricator.',
|
||||
phutil_tag('strong', array(), $user->getUsername()));
|
||||
|
||||
$submit = pht('Disable as Spam');
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle($title)
|
||||
->setShortTitle($short_title)
|
||||
->appendParagraph($body)
|
||||
->addCancelButton($done_uri)
|
||||
->addSubmitButton($submit);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorUserDisableSpamTransaction
|
||||
extends PhabricatorUserTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'user.disable_spam';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
$user = $object;
|
||||
return (string)$user->getRealName();
|
||||
}
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
// Deliberately not using 'spam'.
|
||||
// This way we can use this button even for accounts that
|
||||
// have been already manually renamed to 'spam'.
|
||||
// Otherwise when the name clash with the existing name
|
||||
// none of the changes happens.
|
||||
return 'disabled_spam';
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$user = $object;
|
||||
$user->setRealName('spam');
|
||||
$profile = $user->loadUserProfile();
|
||||
$profile->setBlurb('');
|
||||
$profile->setTitle('');
|
||||
$profile->setIcon('');
|
||||
|
||||
$file = PhabricatorFile::loadBuiltin($user, 'profile.png');
|
||||
$user->setProfileImagePHID($file->getPHID());
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s set this user as spam.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function shouldHideForFeed() {
|
||||
// Don't publish feed stories about handling spam.
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
|
||||
// You must have the "Can Disable Spam Users" permission to disable a user as spam.
|
||||
$this->requireApplicationCapability(
|
||||
PeopleDisableSpamUsersCapability::CAPABILITY);
|
||||
|
||||
if ($this->getActingAsPHID() === $object->getPHID()) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht('You can not disable your own account as spam.'));
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function getRequiredCapabilities(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user