swisnl/json-api-server

Authenticated but unauthorized user access

Closed this issue · 6 comments

I am still tinkering around setup, playing with Insomnia making requests etc.
During this I noticed that my test user gets data, however I did not assign permissions to it.

So I decided to make some tests

    /** @test */
    public function it_creates_an_sample_authenticated()
    {
        Passport::actingAs($this->user);
        // added this to check
        $this->assertTrue($this->user->hasPermissionTo(SamplePermissions::CREATE_SAMPLE));

        $response = $this->post($this->baseUrl);
        $response->assertStatus(201);
    }
    
    // new test to check
    /** @test */
    public function it_creates_an_sample_authenticated_but_unauthorized()
    {
        // create another user without permissions assigned
        Passport::actingAs($user = factory(User::class)->create());
        $this->assertFalse($user->hasPermissionTo(SamplePermissions::CREATE_SAMPLE));

        $response = $this->post($this->baseUrl);
        // assert fails, because request succeeds and 201 is returned
        $response->assertStatus(401);
    }

I did add the Policy to Providers as described here

Did I miss something?

This is mostly just default Laravel which is generated in a file for you to use. The default generated Policy uses the method $user->tokenCan which is Laravel passport.

So if you want to do it Laravel only check out wirting policies or perhaps combine with something like spatie/laravel-permission.

I am sorry, I do not follow. Am I getting this right?

Generated test case already use spatie/laravel-permission e.g.

$this->user->givePermissionTo(SamplePermissions::RETRIEVE_SAMPLE);

Are You saying that this is only in tests and actually nothing uses them, nor checks the permissions?

But policy checks Laravel passport scopes?

I included spatie/laravel-permission in my setup, because it appeared to be required by tests.
This means that I do not need spatie/laravel-permission and should have rewritten the tests to use Passport scopes?

Ok, i did some assumptions there, sorry, the colleage who wrote this isn't here at the moment.

From what i see happening by default the config doesn't enable the permission checks. Is you look at https://github.com/swisnl/json-api-server/blob/master/config/laravel_api.php#L42 you see by default permissions aren't checked. When i enable the checks it does return the following for me if i return false in the the policy, and the normal result when i return true.

{
  errors: [
    {
      status: "403",
      title: "Forbidden",
      detail: "This action is forbidden"
    }
  ]
}

Ah, that was the missing part! Thank you!

Also I replaced all tokenCan() with hasPermissionTo() in the Policy class, so this would work as tests expect it to. Or one could do it the other way around I suppose.

And indeed 403 is more correct response in this case.

@liepumartins did this fix this issue?

The settings in config file did, yes.