-
Notifications
You must be signed in to change notification settings - Fork 6
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
Pass entity to checkAccess method to allow Symfony Voters check the r… #19
Pass entity to checkAccess method to allow Symfony Voters check the r… #19
Conversation
$request = $this->requestFactory->createEntityRequest($httpRequest->query, $resourceName, $id); | ||
$this->listenerManager->onGetEntityRequest($request, $resourceName); | ||
$repository = $this->getRepository($resourceName); | ||
$entity = $repository->fetchOneResource($id, $request->getRelationships()); | ||
|
||
$this->checkAccess($resourceName, ResourceConfig::ACTION_READ, $entity); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the same applies to update entity right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It is for read, update and delete to check if the entity is owned by the user given in the Token
@@ -600,7 +642,7 @@ private function setupJsonApiBaseUrl(Request $request, $pathPartsCount) | |||
$baseUrl = $request->getSchemeAndHttpHost().$request->getBaseUrl().$request->getPathInfo(); | |||
|
|||
$baseUrlParts = explode('/', $baseUrl); | |||
for ($i=0; $i<$pathPartsCount; $i++) { | |||
for ($i = 0; $i < $pathPartsCount; $i ++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$i ++ kind of looks wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is the PSR-2 code styling. I will remove this kind of styling before pushing changes
} | ||
$data['meta']['totalItems'] = $repository->countResourcesWithFilters( | ||
$request->getRelationships(), | ||
$request->getConstraint()->getFilterCollection() | ||
); | ||
|
||
$data['meta']['totalPages'] = (int) (abs($data['meta']['totalItems']-1)/$request->getConstraint()->getPerPage() + 1); | ||
$data['links'] = $this->buildLinks($httpRequest, $request->getConstraint()->getPageNumber(), $data['meta']['totalPages']); | ||
$data['meta']['totalPages'] = (int) (abs($data['meta']['totalItems'] - 1) / $request->getConstraint( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This formatting looks way too forced
Maybe you can move the calculation out to a function and that should fix the formatting also makes it more readable
Thanks for the PR |
Updated the code by adding logic to update and also delete an entity |
@@ -475,12 +476,12 @@ protected function getRepository($resourceName) | |||
} | |||
|
|||
/** | |||
* @param string $resourceName | |||
* @param string $action | |||
* @param string $resourceName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This formatting is not respecting the coding style used in the rest of the library
case ResourceConfig::ACTION_READ: | ||
$role = $resourceConfig->getReadRole(); | ||
break; | ||
default: | ||
throw new \LogicException('Invalid action passed'); | ||
} | ||
|
||
$this->denyAccessUnlessGranted($role, null, 'Unable to access this api!'); | ||
$this->denyAccessUnlessGranted($role, $entity, 'Unable to access this api!'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@juanwilde Not sure if this is actually going to be a major change or not
If I setup a simple project and say anyone user with ROLE_READ can get any objects and I don't put any voter what does denyAccessUnlessGranted returns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I see If you don't put any voter the library will work as always since $entity
is null by default. The problem is if we always pass null
in the entity param, we are not able to check some stuff.. This is a working example of what I mean
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
/** @var User|AnotherUser $user */
$user = $token->getUser();
if ($user instanceof Anotheruser) {
return false;
}
if (self::READ === $attribute) {
if ((null === $subject) || (null !== $subject && $subject->isOwnedBy($user))) {
return true;
}
}
if (self::CREATE === $attribute) {
return true;
}
if (self::UPDATE === $attribute || self::DELETE === $attribute) {
if ($subject->isOwnedBy($user)) {
return true;
}
}
return false;
}
With your approach the $subject
is always null and you can not perform any action like check if the logged user is the owner... Makes sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I tried the following thing. I have 2 entities, one goes throw a Voter and the other one not. The behaviour is the expected. I you try to get one object of the entity that doesn't have Voter, it works as soon as you define the ROLE_READ in the jade.yml
. And for the other one, the same but passing throw the voter after.
I mean. With these changes, the library still working fine if you only use jade.yml
and the listeners. But if you add a Voter it will work as well.
@juanwilde Sounds good |
Yes. I did it following the package instructions and everythink ok. Just a couple of deprecations notices
|
In case of getEntity we need to pass the entity to the checkAccess method in order to check some values within Symfony Voters (To check for example y the logged user is the owner of the requested entity