Chapters
39 Chapters
|
4:45:13
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3, <8.0
Subscribe to download the code!Compatible PHP versions: ^7.1.3, <8.0
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
16.
ACL: Only Owners can PUT a CheeseListing
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
This tutorial works great for Symfony 5 and API Platform 2.5/2.6.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3, <8.0",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^2.1", // v2.4.5
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.13.2
"doctrine/doctrine-bundle": "^1.6", // 1.11.2
"doctrine/doctrine-migrations-bundle": "^2.0", // v2.0.0
"doctrine/orm": "^2.4.5", // v2.7.2
"nelmio/cors-bundle": "^1.5", // 1.5.6
"nesbot/carbon": "^2.17", // 2.21.3
"phpdocumentor/reflection-docblock": "^3.0 || ^4.0", // 4.3.1
"symfony/asset": "4.3.*", // v4.3.2
"symfony/console": "4.3.*", // v4.3.2
"symfony/dotenv": "4.3.*", // v4.3.2
"symfony/expression-language": "4.3.*", // v4.3.2
"symfony/flex": "^1.1", // v1.21.6
"symfony/framework-bundle": "4.3.*", // v4.3.2
"symfony/http-client": "4.3.*", // v4.3.3
"symfony/monolog-bundle": "^3.4", // v3.4.0
"symfony/security-bundle": "4.3.*", // v4.3.2
"symfony/twig-bundle": "4.3.*", // v4.3.2
"symfony/validator": "4.3.*", // v4.3.2
"symfony/webpack-encore-bundle": "^1.6", // v1.6.2
"symfony/yaml": "4.3.*" // v4.3.2
},
"require-dev": {
"hautelook/alice-bundle": "^2.5", // 2.7.3
"symfony/browser-kit": "4.3.*", // v4.3.3
"symfony/css-selector": "4.3.*", // v4.3.3
"symfony/maker-bundle": "^1.11", // v1.12.0
"symfony/phpunit-bridge": "^4.3", // v4.3.3
"symfony/stopwatch": "4.3.*", // v4.3.2
"symfony/web-profiler-bundle": "4.3.*" // v4.3.2
}
}
28 Comments
Hi,
I have an issue with test which checks if cheese listing can be changed via put method by user which isn't its owner. In response I have always 200 status code instead 403. It seems that settings for PUT operation are ignored and I don't know why (by ignoring I mean that I can write everything, e.g.
"blablabla"="is_granted('ROLE_USER') and object.getOwner() == user"instead of"security"="is_granted('ROLE_USER') and object.getOwner() == user"and no errors I'll have). I don't know what's going on. Please help me. I'm using API Platform 2.7 and Symfony 4.4Jakub
Again clearing cache helped. This time I forgot to set the cache cleaning in the test environment:
Issue closed.
Hey Jakub,
Awesome, an easy win ;)
Cheers!
Hi, i'm strugling with this "roles" update.
On the ressource ( named Pilot )
on the property this .
And i dont understand why this test
is failing ( and i should test 403 , not 401 but that does not change my problem :) )
Strange thing is the context returned is not showing this 200 ( still ROLE_USER )
Hey Cerpo!
Yea, this stuff is complex! But, hmm. This is, indeed a bit odd. From my perspective, I WOULD expect this situation to be successful. Your
Putoperation security isis_granted('ROLE_ADMIN') or object == user. So that should pass since the user is editing their own record. You have that same security on the property itself, so I would also expect that to work. Why are you expecting it to fail with 401/403?But, if I'm correct, then we would expect that the
rolesWOULD update in the response, which you correctly noted did NOT happen.So, I'm not sure what's happening. However, I do have one point that might help: If the
PUToperation security "passes", but theApiPropertysecurity "fails", I think (I am not 100% sure - this is a bit of a guess as I haven't used the property-level security yet) that the result would be a 200 status code, except that therolesproperty would "skip" being set. That feels a lot like what you're experiencing.Let me know if this helps :)
Cheers!
the result would be a 200 status code, except that the roles property would "skip" being set.
I can confirm that API platform behaves exactly like that for my
PATCH, with API Platformv3.2.11I have prohibited access to every single property one by one by
#[ApiProperty(security: "is_granted('ROLE_ADMIN')")]but allowed another role in PATCH itself by#[ApiResource(operations: [new Patch(security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_MANAGER')")])]and when "manager" tries to change anything, it changes nothing but responses byHTTP/1.1 200 OK.Hi Ryan, Thanks for the quick answer.
My goal is
Only admin change change user's role.
but reading you comment i can see that something's wrong with my decoration .
it should says
Voters ?
I think it's time the "Re-watch" .. sometimes details suddenly become obvious !
Quick update
I had some answers in the next chapters. ( AdminGroupsContextBuilder and phone / roles example ) . Both on a way to handle this and the explanation on code return 200, property ignored etc..
Thanks
Woo! Glad you got it worked out - my reply was too slow! Cheers :)
Custom error message
In newer versions it seems that `access_control_message` is now `security_message`. (yes, you said that 10 seconds after I mentioned it here)
In my case, it only worked as `security_post_denormalize_message`.
More info at the docs.
Hey Ricardo M.!
Thanks for posting this - I appreciate it :).I I'll add a note to mention this... I think in the next chapter when we mention
security_post_denormalize. Because, basically, if you usesecurity_post_denormalize(which we talk about in the next chapter), then you need to know to also usesecurity_post_denormalize_message.Cheers!
Hi there
i have created API platform 2.6 app and I'm using tests that extends ApiTestCase, so i'm creating some entities before POST call, but that EntityManager in that POST call don't "see" those new entites thus error: Item not found
Hey Daniel,
What do you do exactly when see that "Item not found" error? Are you sure the entities were stored in the database but entity manager does not see it? Can you go to the DB and make sure they really *are* in the database? Btw, in some cases in tests you need to call $entityManager->refresh() and pass an entity to it to sync changes in the DB with the object, otherwise entity manager won't see the changes.
I hope this helps!
Cheers!
Great tutorial, thank you.
I am trying all this out in an excisting api. Is there a way to turn foreign_key_checks of while testing? I use ReloadDatabaseTrait, but when i create a new record of an entity (e.g. new Contact), and i run phpunit, i get ' Cannot add or update a child row: a foreign key constraint fails '.
Thanks in advance.
Hey Annemieke,
"Cannot add or update a child row: a foreign key constraint fails" means that you're trying to input some new data into the DB but it conflicts with the data you already have in your DB. Please, check your DB (I suppose you need to look into test database as you said you run phpunit) and see what data you already have there and what data you're trying to input executing your test. It sounds like you need to empty your DB, i.e. clear the old data before filling it with new data.
Cheers!
Thank you Victor for your quick response. I hope you get payed well for this job.
I found the solution.
In my entity i <b>now</b> use
@ORM\Table(name='mytable').Before i used
@ORM\Table(name=<b>mydatabase</b>.mytable)I am indeed using the test database for test, but because of the orm\table with the database name in it, that won't work.
Thank you !!
Hey Annemieke,
I'm happy you figured out the problem and were able to fix it, well done!
Cheers!
Hi
I have noticed that in the current documentation , the entity properties are declared as public , but when I generate entities the properties are declared as private.
In the begining I have no problem, but now when I tried to protect an object with "object.owner == user" , I get this error
But when I make $owner as public or call getOwner() as you did "object.getOwner() == user", it works good.
Can you please tell us if declaring properties as public like they did in the documentation is dangerous for security or not ?
Thanks expert ;)
Hey hous04!
Short answer: make your properties private. I believe the main reason that you sometimes see public properties used in the API Platform docs is nothing more than... it's easier/shorter to write documentation using public properties than to use private properties and show the getters/setters. Private properties are better just because they're better from an object-oriented perspective.
That's interesting. You shouldn't get that error as long as you have a
getOwner()method. API Platform is smart enough to access a property directly if it's public or to use agetOwner()method if the property is not public and that method exists. That's exactly what we do in this tutorial: my properties are private, but I have the getter method.Let me know if that helps - or if you still get the error after adding the getter.
Cheers!
Hi
Yes expert, it's very helpful and good explication, thank you very much ;)
Thank you for this great tutorial!
I have a small feedback: I'd use `previous_object` rather than `object` in the is_granted expression.
While using object, a user could replace the owner field with their own url/id and "steal" the cheese listing.
What do you think?
Hey Paul Molin!
You're 100% correct - good attention to detail. We change to
previous_objectand talk about this in the next chapter :).Cheers!
Thanks weaverryan ! :)
Keep up the good work, Im' a big fan. :)
For some reason my test fails with error message
The content-type "application/x-www-form-urlencoded" is not supported.. In fact all my tests fail with this message. I just rancomposer updatebefore testing, could it be that this broke something? Setting'headers' => ['Content-Type' => 'application/json']doesn't seem to do anything....Hey Tobias I.
That's odd. Is it possible that something is doing an extra request in the middle of your test? Try detecting the request that is failing
Also, can you show me the piece of code where you perform the request?
Cheers!
I tried to reproduce on a fresh symfony project. I only created a user entity via the
bin/console make:usercommand and followed this this tutorial on setting up the test environment. This is my test class:`
namespace App\Tests\Functional;
use App\ApiPlatform\Test\ApiTestCase;
class UserResourceTest extends ApiTestCase
{
}
`
When I now run
bin/phpunit, I again get the same error (here is a <a href="https://puu.sh/EavYl/ab8557ca5e.png">screenshot</a>)composer show api-platform/coresays that I have version 2.4.6, so the 415 status code is expected. Since 2.4.6 you get a 415 instead of 406 when a faulty content type is used as stated in the <a href="https://github.com/api-platform/core/releases/tag/v2.4.6">release notes</a>. I am not sure what broke, but it's probably only in the test environment because the swagger ui gives me the corrent response and status codeHey Tobias I.
I found the reason of this problem. You can see my answer here: https://symfonycasts.com/sc...
Cheers!
ah perfect thank you so much :) works just as expected!
"Houston: no signs of life"
Start the conversation!