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 #4541: Add again uid and mail options for user commands #4542

Merged
merged 4 commits into from Dec 15, 2021
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
164 changes: 98 additions & 66 deletions src/Drupal/Commands/core/UserCommands.php
Expand Up @@ -119,22 +119,19 @@ public function renderRolesCell($key, $cellData, FormatterOptions $options)
* @command user:block
*
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases ublk,user-block
* @usage drush user:block user3
* Block the users whose name is user3
*/
public function block($names)
public function block($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
$account->block();
$account->save();
$this->logger->success(dt('Blocked user(s): !user', ['!user' => $name]));
} else {
$this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
}
}
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->block();
$account->save();
$this->logger->success(dt('Blocked user(s): !user', ['!user' => $account->getAccountName()]));
}
}

Expand All @@ -144,22 +141,19 @@ public function block($names)
* @command user:unblock
*
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases uublk,user-unblock
* @usage drush user:unblock user3
* Unblock the users with name user3
*/
public function unblock($names)
public function unblock($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
$account->activate();
$account->save();
$this->logger->success(dt('Unblocked user(s): !user', ['!user' => $name]));
} else {
$this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
}
}
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->activate();
$account->save();
$this->logger->success(dt('Unblocked user(s): !user', ['!user' => $account->getAccountName()]));
}
}

Expand All @@ -171,25 +165,22 @@ public function unblock($names)
* @validate-entity-load user_role role
* @param string $role The machine name of the role to add.
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases urol,user-add-role
* @usage drush user-add-role "editor" user3
* Add the editor role to user3
*/
public function addRole($role, $names)
public function addRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
$account->addRole($role);
$account->save();
$this->logger->success(dt('Added !role role to !user', [
'!role' => $role,
'!user' => $name,
]));
} else {
$this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
}
}
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->addRole($role);
$account->save();
$this->logger->success(dt('Added !role role to !user', [
'!role' => $role,
'!user' => $account->getAccountName(),
]));
}
}

Expand All @@ -201,25 +192,22 @@ public function addRole($role, $names)
* @validate-entity-load user_role role
* @param string $role The name of the role to add
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases urrol,user-remove-role
* @usage drush user:remove-role "power user" user3
* Remove the "power user" role from user3
*/
public function removeRole($role, $names)
public function removeRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
$account->removeRole($role);
$account->save();
$this->logger->success(dt('Removed !role role from !user', [
'!role' => $role,
'!user' => $name,
]));
} else {
$this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
}
}
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->removeRole($role);
$account->save();
$this->logger->success(dt('Removed !role role from !user', [
'!role' => $role,
'!user' => $account->getAccountName(),
]));
}
}

Expand Down Expand Up @@ -279,29 +267,26 @@ public function createValidate(CommandData $commandData)
*
* @param string $names A comma delimited list of user names.
* @option delete-content Delete the user, and all content created by the user
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases ucan,user-cancel
* @usage drush user:cancel username
* Cancel the user account with the name username and anonymize all content created by that user.
* @usage drush user:cancel --delete-content username
* Delete the user account with the name username and delete all content created by that user.
*/
public function cancel($names, $options = ['delete-content' => false])
public function cancel($names, $options = ['delete-content' => false, 'uid' => self::REQ, 'mail' => self::REQ])
{
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
if ($options['delete-content']) {
$this->logger()->warning(dt('All content created by !name will be deleted.', ['!name' => $account->getAccountName()]));
}
if ($this->io()->confirm('Cancel user account?: ')) {
$method = $options['delete-content'] ? 'user_cancel_delete' : 'user_cancel_block';
user_cancel([], $account->id(), $method);
drush_backend_batch_process();
// Drupal logs a message for us.
}
} else {
$this->logger()->warning(dt('Unable to load user: !user', ['!user' => $name]));
}
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
if ($options['delete-content']) {
$this->logger()->warning(dt('All content created by !name will be deleted.', ['!name' => $account->getAccountName()]));
}
if ($this->io()->confirm('Cancel user account?: ')) {
$method = $options['delete-content'] ? 'user_cancel_delete' : 'user_cancel_block';
user_cancel([], $account->id(), $method);
drush_backend_batch_process();
// Drupal logs a message for us.
}
}
}
Expand Down Expand Up @@ -357,4 +342,51 @@ public function infoArray($account)
'uuid' => $account->uuid->value,
];
}

/**
* Get accounts from name variables or uid & mail options.
*
* @param string $names
* @param array $options
*
* @return array
* A array of loaded accounts.
* @throws \Exception
*/
protected function getAccounts($names = '', $options = [])
{
$accounts = [];
if ($mails = StringUtils::csvToArray($options['mail'])) {
foreach ($mails as $mail) {
if ($account = user_load_by_mail($mail)) {
$accounts[$account->id()] = $account;
} else {
$this->logger->warning(dt('Unable to load user: !mail', ['!mail' => $mail]));
}
}
}
if ($uids = StringUtils::csvToArray($options['uid'])) {
foreach ($uids as $uid) {
if ($account = User::load($uid)) {
$accounts[$account->id()] = $account;
} else {
$this->logger->warning(dt('Unable to load user: !uid', ['!uid' => $uid]));
}
}
}
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
$accounts[$account->id()] = $account;
} else {
$this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
}
}
}
if (empty($accounts)) {
throw new \Exception(dt('Unable to find any matching user'));
}

return $accounts;
}
}
63 changes: 58 additions & 5 deletions tests/functional/UserTest.php
Expand Up @@ -12,6 +12,7 @@ class UserCase extends CommandUnishTestCase
{

const NAME = 'example';
const MAIL = 'example@example.com';

public function setup(): void
{
Expand All @@ -23,9 +24,10 @@ public function setup(): void

public function testBlockUnblock()
{
$uid = 2;

$this->drush('user-block', [self::NAME]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$uid = 2;
$output = $this->getOutputFromJSON($uid);
$this->assertEquals(0, $output['user_status'], 'User is blocked.');

Expand All @@ -34,15 +36,38 @@ public function testBlockUnblock()
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$this->assertEquals(1, $output['user_status'], 'User is unblocked.');

// user-block user by uid.
$this->drush('user-block', [], ['uid' => $uid]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$this->assertEquals(0, $output['user_status'], 'User (id) is blocked.');

$this->drush('user-unblock', [], ['uid' => $uid]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$this->assertEquals(1, $output['user_status'], 'User (id) is unblocked.');


// user-block user by mail.
$this->drush('user-block', [], ['mail' => self::MAIL]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$this->assertEquals(0, $output['user_status'], 'User (mail) is blocked.');

$this->drush('user-unblock', [], ['uid' => $uid]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$this->assertEquals(1, $output['user_status'], 'User (mail) is unblocked.');
}

public function testUserRole()
{
$uid = 2;
// First, create the role since we use testing install profile.
$this->drush('role-create', ['test role']);
$this->drush('user-add-role', ['test role', self::NAME]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$uid = 2;
$output = $this->getOutputFromJSON($uid);
$expected = ['authenticated', 'test role'];
$this->assertEquals($expected, array_values($output['roles']), 'User has test role.');
Expand All @@ -53,6 +78,34 @@ public function testUserRole()
$output = $this->getOutputFromJSON($uid);
$expected = ['authenticated'];
$this->assertEquals($expected, array_values($output['roles']), 'User removed test role.');

// user-add-role by uid.
$this->drush('user-add-role', ['test role'], ['uid' => $uid]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$expected = ['authenticated', 'test role'];
$this->assertEquals($expected, array_values($output['roles']), 'User (id) has test role.');

// user-remove-role by uid
$this->drush('user-remove-role', ['test role'], ['uid' => $uid]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$expected = ['authenticated'];
$this->assertEquals($expected, array_values($output['roles']), 'User (id) removed test role.');

// user-add-role by mail.
$this->drush('user-add-role', ['test role'], ['mail' => self::MAIL]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$expected = ['authenticated', 'test role'];
$this->assertEquals($expected, array_values($output['roles']), 'User (mail) has test role.');

// user-remove-role by mail.
$this->drush('user-remove-role', ['test role'], ['mail' => self::MAIL]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$output = $this->getOutputFromJSON($uid);
$expected = ['authenticated'];
$this->assertEquals($expected, array_values($output['roles']), 'User (mail) removed test role.');
}

public function testUserPassword()
Expand Down Expand Up @@ -106,7 +159,7 @@ public function testUserLogin()
$this->assertStringContainsString('/user/reset/' . $uid, $url['path'], 'Login with uid option returned a valid reset URL');
// Test specific user by mail.
$uid = 2;
$mail = 'example@example.com';
$mail = self::MAIL;
$this->drush('user-login', [], $user_login_options + ['mail' => $mail]);
$output = $this->getOutput();
$url = parse_url($output);
Expand Down Expand Up @@ -138,11 +191,11 @@ public function testUserCancel()

public function userCreate()
{
$this->drush('user-create', [self::NAME], ['password' => 'password', 'mail' => "example@example.com"]);
$this->drush('user-create', [self::NAME], ['password' => 'password', 'mail' => self::MAIL]);
$this->drush('user-information', [self::NAME], ['format' => 'json']);
$uid = 2;
$output = $this->getOutputFromJSON($uid);
$this->assertEquals('example@example.com', $output['mail']);
$this->assertEquals(self::MAIL, $output['mail']);
$this->assertEquals(self::NAME, $output['name']);
$this->assertEquals(1, $output['user_status'], 'Newly created user is Active.');
$expected = ['authenticated'];
Expand Down