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

Policy & include #96

Closed
bbprojectnet opened this issue Jun 29, 2021 · 13 comments
Closed

Policy & include #96

bbprojectnet opened this issue Jun 29, 2021 · 13 comments

Comments

@bbprojectnet
Copy link

Hi,

For example, i have resource users with patient relation. When i return false in user policy in viewPatient method i can't GET /users/id/patient. It's ok.

But... i can still do that: GET /users/id?include=patient

Shouldn't this also be forbidden?

@lindyhopchris
Copy link
Contributor

As per #98 this is because the authorizer/policy authorizes the controller action, not individual parts of the request. However our implementation is flexible enough that you can add this logic if it is needed for your application.

For this, either use the authorize method on the Query and/or QueryCollection classes, or write your own authorizer.

@bbprojectnet
Copy link
Author

Like in #98, it's sounds like security issue. What is the point of using policy for relationship when still exists method to skip this? It should be handled by library it self.

@lindyhopchris
Copy link
Contributor

So this is too complex to implement in the way you're proposing. Let's say there's a posts resource, and the client includes comments.user - how would you propose that is authorised? I can see how it would be easy to authorise the comments relationship but then are you expecting it to load every single comment to then authorise whether the user relationship can be read on each comment? To me that seems completely overkill, inefficient, plus would require huge re-wiring of the package... because at the moment, the comments relationship is loaded after authorisation.

@lindyhopchris
Copy link
Contributor

Plus it starts to get even more complex if the client includes comments.user.profile.country. I just can't envisage a scenario where we'd want to go down the route of loading each segment of the include path, iterating through it to authorise each sub-relationship.

@bbprojectnet
Copy link
Author

bbprojectnet commented Jul 1, 2021

Yes, it's comples issue. Maybe something like viewAnyName()? and than explode comments.user.profile.country and call this method for 4 policies? It's only concept, probably stupid ;) but for now, it's just don't work corretly.

If you don't want to user see some page, you build login page, auhtorization, etc. You don't want the user to be able to enter there by other way.
So, if you don't want to the user to view some relationship resource, you create policy and you also don't want to show this relationship by other way ;)

@lindyhopchris
Copy link
Contributor

Exploding it an calling it for 4 policies would be hideously complex, as the relationships aren't eager-loaded at the point the authorizer is called. Plus you'd have to call the authorization method N+1 times for each to-many relationship. Which has the potential to be hiddeously slow. Basically, this is why I've never structured an API resource to have field-level authorization: we always structure the API to have resource-level authorization.

Not saying what you're trying to do is wrong; just saying it's far too complex for this package to implement. It is however supported, you'd just have to write your own authorizer.

This is now all explained in the docs here:
https://laraveljsonapi.io/docs/1.0/requests/authorization.html#relationship-authorization

@bbprojectnet
Copy link
Author

OK, i'm trying to stick to this behaviour but I ran into another problem:

I marked my one of relation as hidden, to prevent accessing this relation via include - it works fine, but now, when i try to access /api/resource/id/relation i got an error:

Unexpected relationship A on resource B.

It also happend when You just try to include any non-existing relationship. I think this should not generate an error (500).

How do I hide the relationship from the main resource leaving access via the url?

@bbprojectnet
Copy link
Author

I got it, cannotEagerLoad ;) Sorry for a trouble.

Btw. I still argue that include random string should not throw a exception.

@lindyhopchris
Copy link
Contributor

Random string throws an exception is the correct behaviour. A non-included relationship should be rejected at the validation stage, and result in a 400 response to the client with a specific message about the relationship not being an include path. So the exception being thrown is correct, because the validation stage should have rejected it.

I've definitely seen those validation exceptions so not sure why it isn't rejecting on your resource?

@bbprojectnet
Copy link
Author

Yes, error 400 will be fine, but i got 500 in that case.

Steps to reproduce:

  • define resource relation route
  • mark any relation as hidden in schema
  • try to access /api/resource/id/relation

@lindyhopchris
Copy link
Contributor

Oh no hang on, I didn't fully understand what you were saying.

Hidden only hides the field within the resource's JSON. It won't affect the relationship routes... because if you don't want a relationship to be accessible via its route, you just don't register the route.

If you are getting a 500 when you are not expecting it, please can you create a separate issue and provide a full stack trace of the exception that is causing the 500?

@bbprojectnet
Copy link
Author

bbprojectnet commented Jul 14, 2021

Hidden only hides the field within the resource's JSON. It won't affect the relationship routes... because if you don't want a relationship to be accessible via its route, you just don't register the route.

Correct.

If you are getting a 500 when you are not expecting it, please can you create a separate issue and provide a full stack trace of the exception that is causing the 500?

Yes, of course: #105

Btw. Thanks for your time and responses, the library which you create is great and I really appreciate what you do. In past i create 4 projects based on it and now i trying to learn and use the new version - which is not easy sometimes. So, once again, thanks a lot! :)

@lindyhopchris
Copy link
Contributor

No problem, thanks for the feedback!

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

2 participants