laravel-doctrine / extensions

Extensions integration for Doctrine2 and Laravel
http://laraveldoctrine.org/
MIT License
48 stars 24 forks source link

Blameable does not work when using guards other than default. #35

Closed garret-gunter closed 6 years ago

garret-gunter commented 6 years ago

Description

The Blameable extension uses the ResolveUserDecorator class when listening to the events. When the ResolveUserDecorator is initially created, the auth guard at that moment is stored. In the __call() method, the stored auth guard is used to check if the user is authenticated. Then uses that guard to determine the current user. That user is then stored in the updatedBy and createdBy fields.


    /**
     * @param  string $method
     * @param  array  $params
     * @return mixed
     */
    public function __call($method, $params)
    {
        if ($this->auth->check()) {
            call_user_func([$this->wrapped, $this->userSetterMethod], $this->auth->user());
        }
        return call_user_func_array([$this->wrapped, $method], $params);
    }

Expected Behavior

The currently logged in user should be saved to the fields as an association.

Actual Behavior

A null value is being saved when using non-default guards. This is because Laravel uses the default auth guard initially, but the auth guard is later changed as route, controller, and other settings are loaded. The extension will use the default auth guard even if alternative auth guards (e.g. 'auth:api' ) are later loaded. Since the default guard might not authenticate with the given credentials, Blameable will believe the user was never authenticated and won't set the field's value.

Possible Fix

Use the Auth facade to check if the user is authenticated and to retrieve the user. When the extension is loaded, do not pass the guard to it.


    /**
     * @param  string $method
     * @param  array  $params
     * @return mixed
     */
    public function __call($method, $params)
    {

        if (\Auth::check()) {
            call_user_func([$this->wrapped, $this->userSetterMethod], \Auth::user());
        }

        return call_user_func_array([$this->wrapped, $method], $params);
    }

Steps to Reproduce

  1. Use an alternative guard for a given route.
  2. Use credentials that will not be authenticated by the default guard.
  3. Persist an entity that has a blameable on create field.
  4. The given entity will not be persisted with a user set for createdBy.

Context

Anything created or updated by a user that is authenticated by non-default guard will not save createdBy and updatedBy fields. It still works for anything created or updated using the default guard.

qskousen commented 6 years ago

This affected me also, and your auth guard fix branch fixed it for me. Glad you used app to load auth so it doesn't rely on facades.