My system has cases that belong to users. Users are part of departments. The setup is that users can access all the cases that belong to users that are in the same department as the user is.
Issue is: If I am UserX and I am part of DepartmentA, and there is also UserY who is part of the same department, and also DepartmentB, and a third UserZ who is only part of DepartmentB. Query like this allows UserX to get access to UserZ cases, through UserY:
query {
me {
id
name
department {
cases {
id
user {
id
name
department {
cases {
... ends up listing cases belonging to departments that the user should not have access to
}
}
}
}
}
}
}
So my question is, how do I control users access to only return the cases that they have access to, no matter in what "context" the cases are being requested in. What I would do in a RESTful API is to just get a list of allowed IDs that the user can access, and filter through that, but I'm not sure if that is the right way to approach in a graphql solution.
I really hope my question makes sense, and thank you for reading it.
Use the @can
directive for field authorization and the @guard
directive for authentication:
type Department {
cases: [Case] @hasMany @guard @can(ability: "readCase", resolved: true)
}
Then, define the rule with a standard Laravel Gate (ex. AuthServiceProvider.php
):
Gate::define('readCase', function (User $user, Case $case) {
return $case->department->is($user->department);
});
PS: There are other ways to achieve what you want. Ex. custom resolvers, limit field query depth with @complexity
, etc. But I think @can
is the most elegant for your use case.