Weird policy behavior
Given the following policy:
I'd expect the call to
MyDomain.can_get_by_id?(user, resource)
to return false when user.organization_id == nil
but I'm getting a truthy value back.
What I'm doing wrong?14 Replies
Its a filter check, so all reads are "allowed"
It will just return nothing
If you want to change that:
You can make a policy that applies that check as a "strict" check.
Right now we don't have custom error messages for policies, but its on my short-list
so, should I just make sure the read action has a filter that is always applied instead of trying to restrict access via policies?
Solution
No, the way you're doing it makes sense.
It just depends on the behavior you want
Do you want a forbidden error if the user has no organization_id?
If so, use the example I showed.
If you want the user to be allowed to do it but get a not-found error, then use your original solution
The latter is often better as it protects from enumeration attacks, revealing the least amount of info possible about your system
You can do
MyDomain.can_get_by_id?(user, resource, data: [%Resource{id: the_id}])
if you want to use the first strategy
but you want to know if the user can read this particular piece of data.I just want to make sure users don't fetch info from other organizations. What I'm trying to model is, either the user is an admin or it can only read data from the org it belongs to
probably a 404 would be fine in my case
Perfect
Are you using the
can_..
stuff just for testing?
If so, then MyDomain.can_get_by_id?(user, resource, data: [%Resource{id: the_id}])
is the way to test "can I read this particular thing"yeah, given I was modeling using a policy.
I may have done something wrong
assert Organizations.can_get_organization_by_id?(users.admin, Organization, data: [organization1])
the above gives me this error:
here is the whole policies section
Ah
It expects the same args as actually calling it
except with an actor first
not sure if I understand what your are saying
in iex do
h Organizations.can_get_organization_by_id?
That function comes from your define :get_organization_by_id
which I assume has args: [:id]
can_get_organization_by_id?(actor, id, params_or_opts \\ %{}, opts \\ [])
btw, this read is defined as define :get_organization_by_id, action: :read, get_by: :id
which is based on the default read acionYep, makes sense
So this call you shared:
Is passing
Organization
as the id
Which is invalidah.. that makes total sense.
Thanks @Zach Daniel
🙇♂️ my pleasure 😄