Closed juanwilde closed 6 years ago
@JuanWilde That's one of the correct approaches and the easiest one. In all the cases you can always extend the repository of a specific entity and modify the functionality but that requires changes in the config and is better for more advanced stuff. In the listener approach you just grab the filters from the request and using replaceFilter method put the owner_id in the filters Make sure you add it on the root filter so no one can bypass the condition using an OR condition Cheers
Thanks! That is what I thought. To replace all 'user_id' keys in the request filters with the id of the logged user.
This can be closed! ;)
Glad I could help
Sorry to ask again but I only want to double check this.
In my case I want to check if one of the root filters contains the path user.id
and in that case, replace it with the userId in the TokenStorage.
As you told me, the important thing is to put the filter in the root, so I understand that if someone put an OR condition y other level of the json filter he wont be able to retrieve other users info, right.
This is how my listener method looks like:
/**
* @param CollectionRequest $request
*
* @return CollectionRequest|void
*/
public function onGetCollectionRequest(CollectionRequest $request)
{
$authUserFilter = new ExpressionFilter('user.id', 'eq', (string) $this->getUser()->getId());
$request->getConstraint()->getFilterCollection()->addFilter($authUserFilter);
$totalRootFilters = count($request->getConstraint()->getFilters());
for ($i = 0; $i < $totalRootFilters; $i ++) {
/** @var ExpressionFilter $current */
$current = $request->getConstraint()->getFilters()[$i];
if ($current instanceof ExpressionFilter && 'user.id' === $current->getPath()->getFullPath()) {
$request->getConstraint()->getFilterCollection()->replaceFilter($i, $authUserFilter);
}
}
}
And this is an example of trying to retrieve non owned data:
e448f6a0-9fd2-49bd-875f-52e04996625e
is the authenticated userId (the JWT token)
68e19179-6f99-4980-8404-b22f4f435d27
is another userId in the application
http://app.es:86/api/expenses?include=user&filter=[
{
"type":"neq",
"path":"user.id",
"value":"e448f6a0-9fd2-49bd-875f-52e04996625e"
},
{
"type":"or",
"filters":[
{
"type":"eq",
"path":"user.id",
"value":"68e19179-6f99-4980-8404-b22f4f435d27"
},
{
"type":"neq",
"path":"user.id",
"value":"e448f6a0-9fd2-49bd-875f-52e04996625e"
}
]
}
]
Makes sense?
Thanks again!
Hi Well in my opinion you should directly reject the request if someone tries to pass the user In your application its not an expected behaviour to get the user filter in the application
I need to add a security layer when getting collections. I have an application to manage domestic accounting and I want to filter by logged user. For example, if you are logged into the application and you get all your expenses I want to know how to filter that.
I guess I need to check something in the onGetCollectionRequest() listener method, but I am not sure which is the best practice for this. Because I think if you are logged and you know another userId you can retrieve his data.
Thanks in advance!