[ticket/14561] User activate command

PHPBB3-14561
This commit is contained in:
Matt Friedman 2016-03-26 12:37:27 -07:00
parent 8a9429efa4
commit 91f1116e04
4 changed files with 368 additions and 0 deletions

View file

@ -220,6 +220,20 @@ services:
tags:
- { name: console.command }
console.command.user.activate:
class: phpbb\console\command\user\activate
arguments:
- '@user'
- '@dbal.conn'
- '@config'
- '@language'
- '@log'
- '@notification_manager'
- '%core.root_path%'
- '%core.php_ext%'
tags:
- { name: console.command }
console.command.user.add:
class: phpbb\console\command\user\add
arguments:

View file

@ -82,6 +82,11 @@ $lang = array_merge($lang, array(
'CLI_DESCRIPTION_THUMBNAIL_GENERATE' => 'Generate all missing thumbnails.',
'CLI_DESCRIPTION_THUMBNAIL_RECREATE' => 'Recreate all thumbnails.',
'CLI_DESCRIPTION_USER_ACTIVATE' => 'Activate (or deactivate) a user account.',
'CLI_DESCRIPTION_USER_ACTIVATE_USERNAME' => 'Username of the account to activate.',
'CLI_DESCRIPTION_USER_ACTIVATE_DEACTIVATE' => 'Deactivate the users account',
'CLI_DESCRIPTION_USER_ACTIVATE_ACTIVE' => 'The user is already active.',
'CLI_DESCRIPTION_USER_ACTIVATE_INACTIVE' => 'The user is already inactive.',
'CLI_DESCRIPTION_USER_ADD' => 'Add a new user.',
'CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME' => 'Username of the new user',
'CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD' => 'Password of the new user',
@ -135,6 +140,8 @@ $lang = array_merge($lang, array(
// Additional help for commands.
$lang = array_merge($lang, array(
'CLI_HELP_CRON_RUN' => $lang['CLI_DESCRIPTION_CRON_RUN'] . ' Optionally you can specify a cron task name to run only the specified cron task.',
'CLI_HELP_USER_ACTIVATE' => 'Activate a user account, or deactivate an account using the <info>--deactivate</info> option.
To optionally send an activation email to the user, use the <info>--send-email</info> option.',
'CLI_HELP_USER_ADD' => 'The <info>%command.name%</info> command adds a new user:
If this command is run without options, you will be prompted to enter them.
To optionally send an email to the new user, use the <info>--send-email</info> option.',

View file

@ -0,0 +1,223 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\console\command\user;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
class activate extends \phpbb\console\command\command
{
/** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbb\log\log_interface */
protected $log;
/** @var \phpbb\notification\manager */
protected $notifications;
/**
* phpBB root path
*
* @var string
*/
protected $phpbb_root_path;
/**
* PHP extension.
*
* @var string
*/
protected $php_ext;
/**
* Construct method
*
* @param \phpbb\user $user
* @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\config\config $config
* @param \phpbb\language\language $language
* @param \phpbb\log\log_interface $log
* @param \phpbb\notification\manager $notifications
* @param string $phpbb_root_path
* @param string $php_ext
*/
public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\language\language $language, \phpbb\log\log_interface $log, \phpbb\notification\manager $notifications, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->config = $config;
$this->language = $language;
$this->log = $log;
$this->notifications = $notifications;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
$this->language->add_lang('acp/users');
parent::__construct($user);
}
/**
* Sets the command name and description
*
* @return null
*/
protected function configure()
{
$this
->setName('user:activate')
->setDescription($this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE'))
->setHelp($this->language->lang('CLI_HELP_USER_ACTIVATE'))
->addArgument(
'username',
InputArgument::REQUIRED,
$this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_USERNAME')
)
->addOption(
'deactivate',
'd',
InputOption::VALUE_NONE,
$this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_DEACTIVATE')
)
->addOption(
'send-email',
null,
InputOption::VALUE_NONE,
$this->language->lang('CLI_DESCRIPTION_USER_ADD_OPTION_NOTIFY')
)
;
}
/**
* Executes the command user:activate
*
* Deletes a user from the database. An option to delete the user's posts
* is available, by default posts will be retained.
*
* @param InputInterface $input The input stream used to get the options
* @param OutputInterface $output The output stream, used to print messages
*
* @return int 0 if all is well, 1 if any errors occurred
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$name = $input->getArgument('username');
$mode = ($input->getOption('deactivate')) ? 'deactivate' : 'activate';
if (!$user_row = $this->get_user_data($name))
{
$io->error($this->language->lang('NO_USER'));
return 1;
}
// Check if the user is already active (or inactive)
if ($mode == 'activate' && $user_row['user_type'] != USER_INACTIVE)
{
$io->error($this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_ACTIVE'));
return 1;
}
else if ($mode == 'deactivate' && $user_row['user_type'] == USER_INACTIVE)
{
$io->error($this->language->lang('CLI_DESCRIPTION_USER_ACTIVATE_INACTIVE'));
return 1;
}
// Activate the user account
if (!function_exists('user_active_flip'))
{
require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
}
user_active_flip($mode, $user_row['user_id']);
// Notify the user upon activation
if ($mode == 'activate' && $this->config['require_activation'] == USER_ACTIVATION_ADMIN)
{
$this->send_notification($user_row, $input);
}
// Log and display the result
$msg = ($mode == 'activate') ? 'USER_ADMIN_ACTIVATED' : 'USER_ADMIN_DEACTIVED';
$log = ($mode == 'activate') ? 'LOG_USER_ACTIVE' : 'LOG_USER_INACTIVE';
$this->log->add('admin', ANONYMOUS, '', $log, false, array($user_row['username']));
$this->log->add('user', ANONYMOUS, '', $log . '_USER', false, array(
'reportee_id' => $user_row['user_id']
));
$io->success($this->language->lang($msg));
return 0;
}
/**
* Send account activation notification to user
*
* @param array $user_row The user data array
* @param InputInterface $input The input stream used to get the options
* @return null
*/
protected function send_notification($user_row, InputInterface $input)
{
$this->notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']);
if ($input->getOption('send-email'))
{
if (!class_exists('messenger'))
{
require($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext);
}
$messenger = new \messenger(false);
$messenger->template('admin_welcome_activated', $user_row['user_lang']);
$messenger->set_addresses($user_row);
$messenger->anti_abuse_headers($this->config, $this->user);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($user_row['username']))
);
$messenger->send(NOTIFY_EMAIL);
}
}
/**
* Get the user's data from the database
*
* @param string $name A user name
* @return mixed The user's data array if they exist, false otherwise.
*/
protected function get_user_data($name)
{
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($name)) . "'";
$result = $this->db->sql_query_limit($sql, 1);
$user_row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
return $user_row;
}
}

View file

@ -0,0 +1,124 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use phpbb\console\command\user\activate;
class phpbb_console_command_user_activate_test extends phpbb_database_test_case
{
protected $db;
protected $config;
protected $user;
protected $language;
protected $log;
protected $notifications;
protected $command_name;
protected $phpbb_root_path;
protected $php_ext;
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml');
}
public function setUp()
{
global $config, $db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, $phpEx;
$auth = $this->getMock('\phpbb\auth\auth');
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$config = $this->config = new \phpbb\config\config(array());
$db = $this->db = $this->new_dbal();
$this->language = $this->getMockBuilder('\phpbb\language\language')
->disableOriginalConstructor()
->getMock();
$this->language->expects($this->any())
->method('lang')
->will($this->returnArgument(0));
$user = $this->user = $this->getMock('\phpbb\user', array(), array(
$this->language,
'\phpbb\datetime'
));
$this->log = $this->getMockBuilder('\phpbb\log\log')
->disableOriginalConstructor()
->getMock();
$this->notifications = $this->getMockBuilder('\phpbb\notification\manager')
->disableOriginalConstructor()
->getMock();
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $phpEx;
parent::setUp();
}
public function activate_test_data()
{
return array(
// Test an inactive user
array('Test', false, 'USER_ADMIN_ACTIVATED'),
array('Test', true, 'CLI_DESCRIPTION_USER_ACTIVATE_INACTIVE'),
// Test an active user
array('Test 2', false, 'CLI_DESCRIPTION_USER_ACTIVATE_ACTIVE'),
array('Test 2', true, 'USER_ADMIN_DEACTIVED'),
// Test a non existent user
array('Foo', false, 'NO_USER'),
array('Foo', true, 'NO_USER'),
);
}
/**
* @dataProvider activate_test_data
*/
public function test_activate($username, $deactivate, $expected)
{
$command_tester = $this->get_command_tester();
$command_tester->execute(array(
'command' => $this->command_name,
'username' => $username,
'--deactivate' => $deactivate,
));
$this->assertContains($expected, $command_tester->getDisplay());
}
public function get_command_tester()
{
$application = new Application();
$application->add(new activate(
$this->user,
$this->db,
$this->config,
$this->language,
$this->log,
$this->notifications,
$this->phpbb_root_path,
$this->php_ext
));
$command = $application->find('user:activate');
$this->command_name = $command->getName();
return new CommandTester($command);
}
}