Search code examples
laravelauthorizationpolicies

Laravel (7) Resource Policies don't work with CamelCase, get a 403 for view policy (show in controller)


Here a two examples, first for ResourceController (return 200 - ok ), second for ResourceLogsController (returns 403 - not authorized )

api.php

// RESOURCES
Route::apiResource('resources','Api\ResourceController');

// RESOURCELOGS
Route::apiResource('resourcelogs','Api\ResourceLogController');

AuthServiceProvider:

use App\Policies\ResourcePolicy;
use App\Policies\ResourceLogPolicy;

// ...

    protected $policies = [
        Resource::class => ResourcePolicy::class,
        ResourceLog::class => ResourceLogPolicy::class
    ];

ResourceController:

    public function __construct()
    {
      $this->middleware('auth:api');
      $this->authorizeResource(Resource::class, 'resource');
    }

    public function index(Resource $resource)
    {
      dd('authorization ok');
    }

    public function show(Resource $resource)
    {
      dd('authorization ok');
    }

ResourceLogController:

    public function __construct()
    {
      $this->middleware('auth:api');
      $this->authorizeResource(ResourceLog::class, 'resourcelog');
    }

    public function index(ResourceLog $resourceLog)
    {
      dd('authorization ok');
    }

    public function show(ResourceLog $resourceLog)
    {
      dd('no authorization here');
    }

ResourcePolicies: Just returns a simple true as a test

class ResourcePolicy
{
    use HandlesAuthorization;

    public function viewAny(User $user)
    {
        return true;
    }

    public function view(User $user, Resource $resource)
    {
        return true;
    }

ResourceLogPolicies: just returns a simple true as a test


class ResourceLogPolicy
{
    use HandlesAuthorization;

    public function viewAny(User $user)
    {
        return true;
    }

    public function view(User $user, ResourceLog $resourceLog)
    {
        return true;
    }

I tried changing the second parameter in $this->authorizeLogResource for lower case, chamelcase etc..

$this->authorizeResource(ResourceLog::class, 'resourcelog'); $this->authorizeResource(ResourceLog::class, 'App\ResourceLog'); // = Too few arguments to function App\Policies\ResourceLogPolicy::view(), 1 passed

I do see resource and not resourceLog under Middleware...

enter image description here


Solution

  • Answer with the help of taylorotwell himself:

    In router:

    Route::apiResource('resourceLogs','Api\ResourceLogController');
    

    Controller:

    public function __construct()
    {
      $this->middleware('auth:api');
      $this->authorizeResource(ResourceLog::class, 'resourceLog'); 
    }
    

    Method:

    public function show(ResourceLog $resourceLog)
    {
    return new ResourceLogResource($resourceLog);
    }
    

    'resourceLogs' in Route and authorizeResource + $resourceLog (!) need to have the same casing.