[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: tags:
- { name: console.command } - { 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: console.command.user.add:
class: phpbb\console\command\user\add class: phpbb\console\command\user\add
arguments: arguments:

View file

@ -82,6 +82,11 @@ $lang = array_merge($lang, array(
'CLI_DESCRIPTION_THUMBNAIL_GENERATE' => 'Generate all missing thumbnails.', 'CLI_DESCRIPTION_THUMBNAIL_GENERATE' => 'Generate all missing thumbnails.',
'CLI_DESCRIPTION_THUMBNAIL_RECREATE' => 'Recreate all 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' => 'Add a new user.',
'CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME' => 'Username of the new user', 'CLI_DESCRIPTION_USER_ADD_OPTION_USERNAME' => 'Username of the new user',
'CLI_DESCRIPTION_USER_ADD_OPTION_PASSWORD' => 'Password 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. // Additional help for commands.
$lang = array_merge($lang, array( $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_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: '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. 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.', 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);
}
}