V8-archive: Changing password over the CLI doesn't work

Created on 26 Aug 2019  路  1Comment  路  Source: directus/v8-archive

Bug Report

I've been trying to change user password through CLI tool since I can't connect with an user created from the app (reported here #1199).

Steps to Reproduce

  1. Open your console
  2. Create a user with email [email protected] and password abc123. Set it active and add it a role (Admin or else)
  3. Start the CLI command php bin/directus user:password -e [email protected] -p abc123
  4. See the results (Error message)

Expected Behavior

  • We expect the password of the user with email [email protected] to get a new password (abc123)

Actual Behavior

The CLI command throw an error :

PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function Directus\Console\Common\User::__construct(), 1 passed in /var/www/html/src/core/Directus/Console/Modules/UserModule.php on line 65 and exactly 2 expected in /var/www/html/src/core/Directus/Console/Common/User.php:19
Stack trace:
#0 /var/www/html/src/core/Directus/Console/Modules/UserModule.php(65): Directus\Console\Common\User->__construct('/var/www/html')
#1 /var/www/html/src/core/Directus/Console/Modules/ModuleBase.php(61): Directus\Console\Modules\UserModule->cmdPassword(Array, Array)
#2 /var/www/html/src/core/Directus/Console/Cli.php(88): Directus\Console\Modules\ModuleBase->runCommand('password', Array, Array)
#3 /var/www/html/src/core/Directus/Console/Cli.php(64): Directus\Console\Cli->cmd()
#4 /var/www/html/bin/directus(10): Directus\Console\Cli->run()
#5 {main}
  thrown in /var/www/html/src/core/Directus/Console/Common/User.php on line 19

It seems a basic PHP error (it seems only).
Quoted files in the error:

Technical Details

  • Device: Docker
  • OS: Linux alpine
  • Web Server: x
  • PHP Version: 7.2.13
  • Database: MySQL x
  • Install Method: Get latest code cloned into my container
bug

Most helpful comment

Help for community purpose

Just in case, if you urgently need the password change feature, on my side I created a custom endpoint that cover the bug.

It can help the time the issue is fixed :


public/extensions/custom/lib/DirectusService.php

<?php

namespace Directus\Custom\Lib;

use Zend\Db\TableGateway\TableGateway;
use Directus\Services\ItemsService;
use Directus\Application\Application;

class DirectusService
{
    public function __construct($response)
    {
        $container = Application::getInstance()->getContainer();
        $this->acl = $container->get("acl");
        $this->auth = $container->get("auth");

        $this->directus = new ItemsService($container);
        $this->response = $response;

        return true;
    }

    /**
    * @param Array $data
    *
    * @return User
    */
    public function updateUserPassword($id, $password)
    {
        if (!$id) return ErrorsService::respond($this->response, "Can not update user password without id");
        if (!$password) return ErrorsService::respond($this->response, "Can not update user password without password");
        if (!$this->acl->isAdmin()) return ErrorsService::respond($this->response, "You need to be admin");

        $dbConnection = $dbConnection = Application::getInstance()->getContainer()->get("database");
        $tblUsers = new TableGateway("directus_users", $dbConnection);
        $updateUser = new \Zend\Db\Sql\Update("directus_users");
        $updateUser
            ->set([
                "password" => $this->auth->hashPassword($password)
            ])
            ->where(["id" => $id]);
        $tblUsers->updateWith($updateUser);

        return [ "success" => true ];
    }
}


public/extensions/custom/endpoints/user.php

<?php

use Directus\Application\Http\Request;
use Directus\Application\Http\Response;
use Directus\Custom\Lib\DirectusService;

require_once(__DIR__ . "/../lib/DirectusService.php");
require_once(__DIR__ . "/../lib/ErrorsService.php");

return [
    "password" => [
        "method" => "PATCH",
        "handler" => function (Request $request, Response $response) {
            $POST = $request->getParsedBody();
            $directus = new DirectusService($response);

            $user = null;
            $userId = null;

            if (isset($POST["email"])) {
                $user = $directus->getUserByEmail($POST["email"]);
                $userId = $user["id"];
            } else if (isset($POST["id"])) {
                $userId = $POST["id"];
            }

            $res = $directus->updateUserPassword($userId, $POST["password"]);
            return $response->withJson($res);
        }
    ]
];


public/extensions/custom/lib/ErrorsService.php

<?php

namespace Directus\Custom\Lib;

use Directus\Exception\MethodNotAllowedException;
use Directus\Application\Http\Response;

class ErrorsService
{
    /**
    * @param Response $response
    * @param String/Array $messages, texts to display for errors
    * @return Trigger response if error
    */
    public static function respond($response, $messages)
    {
        if (!$response) return null;
        $response = $response->withStatus(Response::HTTP_METHOD_NOT_ALLOWED);
        return [
            "error" => [
                "code" => MethodNotAllowedException::ERROR_CODE,
                "messages" => is_array($messages) ? $messages : [$messages]
            ]
        ];
    }
}


You can update user password (only if you are authentified as admin) : through
PATCH /_/custom/user/password

{
    "email": "[email protected]",
    "password": "123456"
}

or

{
    "id": "27",
    "password": "123456"
}

>All comments

Help for community purpose

Just in case, if you urgently need the password change feature, on my side I created a custom endpoint that cover the bug.

It can help the time the issue is fixed :


public/extensions/custom/lib/DirectusService.php

<?php

namespace Directus\Custom\Lib;

use Zend\Db\TableGateway\TableGateway;
use Directus\Services\ItemsService;
use Directus\Application\Application;

class DirectusService
{
    public function __construct($response)
    {
        $container = Application::getInstance()->getContainer();
        $this->acl = $container->get("acl");
        $this->auth = $container->get("auth");

        $this->directus = new ItemsService($container);
        $this->response = $response;

        return true;
    }

    /**
    * @param Array $data
    *
    * @return User
    */
    public function updateUserPassword($id, $password)
    {
        if (!$id) return ErrorsService::respond($this->response, "Can not update user password without id");
        if (!$password) return ErrorsService::respond($this->response, "Can not update user password without password");
        if (!$this->acl->isAdmin()) return ErrorsService::respond($this->response, "You need to be admin");

        $dbConnection = $dbConnection = Application::getInstance()->getContainer()->get("database");
        $tblUsers = new TableGateway("directus_users", $dbConnection);
        $updateUser = new \Zend\Db\Sql\Update("directus_users");
        $updateUser
            ->set([
                "password" => $this->auth->hashPassword($password)
            ])
            ->where(["id" => $id]);
        $tblUsers->updateWith($updateUser);

        return [ "success" => true ];
    }
}


public/extensions/custom/endpoints/user.php

<?php

use Directus\Application\Http\Request;
use Directus\Application\Http\Response;
use Directus\Custom\Lib\DirectusService;

require_once(__DIR__ . "/../lib/DirectusService.php");
require_once(__DIR__ . "/../lib/ErrorsService.php");

return [
    "password" => [
        "method" => "PATCH",
        "handler" => function (Request $request, Response $response) {
            $POST = $request->getParsedBody();
            $directus = new DirectusService($response);

            $user = null;
            $userId = null;

            if (isset($POST["email"])) {
                $user = $directus->getUserByEmail($POST["email"]);
                $userId = $user["id"];
            } else if (isset($POST["id"])) {
                $userId = $POST["id"];
            }

            $res = $directus->updateUserPassword($userId, $POST["password"]);
            return $response->withJson($res);
        }
    ]
];


public/extensions/custom/lib/ErrorsService.php

<?php

namespace Directus\Custom\Lib;

use Directus\Exception\MethodNotAllowedException;
use Directus\Application\Http\Response;

class ErrorsService
{
    /**
    * @param Response $response
    * @param String/Array $messages, texts to display for errors
    * @return Trigger response if error
    */
    public static function respond($response, $messages)
    {
        if (!$response) return null;
        $response = $response->withStatus(Response::HTTP_METHOD_NOT_ALLOWED);
        return [
            "error" => [
                "code" => MethodNotAllowedException::ERROR_CODE,
                "messages" => is_array($messages) ? $messages : [$messages]
            ]
        ];
    }
}


You can update user password (only if you are authentified as admin) : through
PATCH /_/custom/user/password

{
    "email": "[email protected]",
    "password": "123456"
}

or

{
    "id": "27",
    "password": "123456"
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

vuhrmeister picture vuhrmeister  路  3Comments

cdwmhcc picture cdwmhcc  路  3Comments

cdwmhcc picture cdwmhcc  路  3Comments

HashemKhalifa picture HashemKhalifa  路  3Comments

24js picture 24js  路  3Comments