Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

What happen with --user option in Drush 9? #3396

Closed
RoSk0 opened this issue Feb 19, 2018 · 12 comments
Closed

What happen with --user option in Drush 9? #3396

RoSk0 opened this issue Feb 19, 2018 · 12 comments

Comments

@RoSk0
Copy link
Contributor

RoSk0 commented Feb 19, 2018

Hi,

I was deploying new project today and faced with issue. Our deployment system has a step to put site in maintenance mode which look like this drush -u 1 -l http://address -r /var/www/drupal/project/current -y sset system.maintenance_mode 1 for Drupal 8. When this step was executed instead of usual OK message I received

[Symfony\Component\Console\Exception\CommandNotFoundException] 
Command "1" is not defined.

I have spent some tome and come to point where I can see from docs that I need to Drush 9 with 8.4+ and Drush 8 for everything else. That is fine, but... Global --user option was removed by #2696 but how we should replace this behaviour with Drush 9? Any links to docs or blog posts about this is greatly appreciated.

@weitzman
Copy link
Member

Just remove -u 1.

@hamrant
Copy link

hamrant commented Mar 12, 2018

@weitzman Hi, this is not fixed problem.
For example I need to run some custom drush commands as root user, because default drush user(
anonymous) have no access to some site parts. I have checked and Drush 9 still run commands as anonymous user.

For now I see only one solution - manual user login in drush command:
user_login_finalize(User::load(1));
but it looks pretty dirty

@RoSk0
Copy link
Contributor Author

RoSk0 commented Mar 12, 2018

Hi @hamrant ,

As I discovered later there is a new recommended approach now. If your Drush command requires some privileges you should use \Drupal\Core\Session\AccountSwitcher service. Docs here https://www.drupal.org/node/2377441

@hamrant
Copy link

hamrant commented Mar 12, 2018

Hi @RoSk0, thanks for quick response. Ok, I will use AccountSwitcher instead

@seth-shaw-unlv
Copy link

@RoSk0 & @hamrant

Please forgive my unfamiliarity with drush, but how exactly do you use AccountSwitcher with it? Will using the AccountSwitcher in a drush php-script command retain that user for subsequent drush commands?

Examples would be greatly appreciated.

@hamrant
Copy link

hamrant commented May 13, 2018

@seth-shaw-unlv yes, you need to use it inside drush command. Example:

drush.services.yml

services:
  my_demo.commands:
    class: \Drupal\my_demo\Commands\DemoCommands
    arguments: ['@account_switcher']
    tags:
      - { name: drush.command }

DemoCommands.php

<?php

namespace Drupal\my_demo\Commands;

use Drupal\Core\Session\UserSession;
use Drush\Commands\DrushCommands;
use Drupal\Core\Session\AccountSwitcherInterface;

/**
 * A Drush commandfile.
 *
 * In addition to this file, you need a drush.services.yml
 * in root of your module, and a composer.json file that provides the name
 * of the services file to use.
 *
 * See these files for an example of injecting Drupal services:
 *   - http://cgit.drupalcode.org/devel/tree/src/Commands/DevelCommands.php
 *   - http://cgit.drupalcode.org/devel/tree/drush.services.yml
 */
class DemoCommands extends DrushCommands {

  /**
   * The account switcher service.
   *
   * @var \Drupal\Core\Session\AccountSwitcherInterface
   */
  protected $accountSwitcher;

  /**
   * SimplesitemapCommands constructor.
   *
   * @param \Drupal\Core\Session\AccountSwitcherInterface $account_switcher
   *   The account switching service.
   */
  public function __construct(AccountSwitcherInterface $account_switcher) {
    $this->accountSwitcher = $account_switcher;
  }

  /**
   * Some demo drush command.
   *
   * @usage drush run-demo
   *   Run demo command.
   *
   * @command run:demo
   * @aliases run-demo
   */
  public function demo() {
    // Switch to root user (--user option was removed from drush 9).
    $this->accountSwitcher->switchTo(new UserSession(['uid' => 1]));
    // Do here logic related to command.
    // ...
    // Switch account back.
    $this->accountSwitcher->switchBack();
  }

}

@seth-shaw-unlv
Copy link

Thanks @hamrant.

@adam-vessey
Copy link

A warning regarding using the described account switching as I've been bitten by it: The switched account is not presently inherited by subprocesses... so any contained drush_backend_batch_process() invocations or similar will proceed without the switched user.

@greg-1-anderson
Copy link
Member

If you really wanted to, you could use a @hook init to switch to a new user session for all commands. Maybe you could even enable / disable it via an environment variable.

@them-roc
Copy link

@adam-vessey
I managed to batch subprocesses with a specific user by setting
\Drupal::currentUser()->setAccount(User::load(some_uid))
This however is marked to be highly discouraged and I wonder if that warning can be ignored in case of a drush batch?

@greg-1-anderson
could you please give an example for this hook_init?

@halisonfernandes
Copy link
Contributor

halisonfernandes commented Jan 10, 2022

It's possible to do the following within a batch subprocess:

$accountSwitcher = \Drupal::service('account_switcher');
$accountSwitcher->switchTo(new UserSession(['uid' => 1]));

@dravenk
Copy link

dravenk commented Nov 4, 2022

@seth-shaw-unlv yes, you need to use it inside drush command. Example:

drush.services.yml

services:
  my_demo.commands:
    class: \Drupal\my_demo\Commands\DemoCommands
    arguments: ['@account_switcher']
    tags:
      - { name: drush.command }

DemoCommands.php

<?php

namespace Drupal\my_demo\Commands;

use Drupal\Core\Session\UserSession;
use Drush\Commands\DrushCommands;
use Drupal\Core\Session\AccountSwitcherInterface;

/**
 * A Drush commandfile.
 *
 * In addition to this file, you need a drush.services.yml
 * in root of your module, and a composer.json file that provides the name
 * of the services file to use.
 *
 * See these files for an example of injecting Drupal services:
 *   - http://cgit.drupalcode.org/devel/tree/src/Commands/DevelCommands.php
 *   - http://cgit.drupalcode.org/devel/tree/drush.services.yml
 */
class DemoCommands extends DrushCommands {

  /**
   * The account switcher service.
   *
   * @var \Drupal\Core\Session\AccountSwitcherInterface
   */
  protected $accountSwitcher;

  /**
   * SimplesitemapCommands constructor.
   *
   * @param \Drupal\Core\Session\AccountSwitcherInterface $account_switcher
   *   The account switching service.
   */
  public function __construct(AccountSwitcherInterface $account_switcher) {
    $this->accountSwitcher = $account_switcher;
  }

  /**
   * Some demo drush command.
   *
   * @usage drush run-demo
   *   Run demo command.
   *
   * @command run:demo
   * @aliases run-demo
   */
  public function demo() {
    // Switch to root user (--user option was removed from drush 9).
    $this->accountSwitcher->switchTo(new UserSession(['uid' => 1]));
    // Do here logic related to command.
    // ...
    // Switch account back.
    $this->accountSwitcher->switchBack();
  }

}

Work for me. Thank you.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants