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

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.

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

No branches or pull requests

9 participants