Skip to content

Fix #1646 #859

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

Merged
merged 1 commit into from
Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions core/graphql.md
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ For the previous page, you would add the `startCursor` from the current page as
How do you know when you have reached the last page? It is the aim of the property `hasNextPage` or `hasPreviousPage` in `pageInfo`.
When it is false, you know it is the last page and moving forward or backward will give you an empty result.

## Security (`access_control`)
## Security

To add a security layer to your queries and mutations, follow the [security](security.md) documentation.

Expand All @@ -802,17 +802,17 @@ use ApiPlatform\Core\Annotation\ApiResource;

/**
* @ApiResource(
* attributes={"access_control"="is_granted('ROLE_USER')"},
* attributes={"security"="is_granted('ROLE_USER')"},
* collectionOperations={
* "post"={"access_control"="is_granted('ROLE_ADMIN')", "access_control_message"="Only admins can add books."}
* "post"={"security"="is_granted('ROLE_ADMIN')", "security_message"="Only admins can add books."}
* },
* itemOperations={
* "get"={"access_control"="is_granted('ROLE_USER') and object.owner == user", "access_control_message"="Sorry, but you are not the book owner."}
* "get"={"security"="is_granted('ROLE_USER') and object.owner == user", "security_message"="Sorry, but you are not the book owner."}
* },
* graphql={
* "query"={"access_control"="is_granted('ROLE_USER') and object.owner == user"},
* "delete"={"access_control"="is_granted('ROLE_ADMIN')"},
* "create"={"access_control"="is_granted('ROLE_ADMIN')"}
* "query"={"security"="is_granted('ROLE_USER') and object.owner == user"},
* "delete"={"security"="is_granted('ROLE_ADMIN')"},
* "create"={"security"="is_granted('ROLE_ADMIN')"}
* }
* )
*/
Expand Down
4 changes: 2 additions & 2 deletions core/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ class Question

### Access Control of Subresources

The `subresourceOperations` attribute also allows you to add an access control on each path with the attribute `access_control`.
The `subresourceOperations` attribute also allows you to add an access control on each path with the attribute `security`.

```php
<?php
Expand All @@ -479,7 +479,7 @@ The `subresourceOperations` attribute also allows you to add an access control o
* @ApiResource(
* subresourceOperations={
* "api_questions_answer_get_subresource"= {
* "access_control"="has_role('ROLE_AUTHENTICATED')"
* "security"="has_role('ROLE_AUTHENTICATED')"
* }
* }
* )
Expand Down
69 changes: 57 additions & 12 deletions core/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ use Symfony\Component\Validator\Constraints as Assert;
* Secured resource.
*
* @ApiResource(
* attributes={"access_control"="is_granted('ROLE_USER')"},
* attributes={"security"="is_granted('ROLE_USER')"},
* collectionOperations={
* "get",
* "post"={"access_control"="is_granted('ROLE_ADMIN')"}
* "post"={"security"="is_granted('ROLE_ADMIN')"}
* },
* itemOperations={
* "get"={"access_control"="is_granted('ROLE_USER') and object.owner == user"},
* "get"={"security"="is_granted('ROLE_USER') and object.owner == user"},
* "put"={"access_control"="is_granted('ROLE_USER') and previous_object.owner == user"},
* }
* )
Expand Down Expand Up @@ -78,7 +78,7 @@ if you really need to.
## Configuring the Access Control Message

By default when API requests are denied, you will get the "Access Denied" message.
You can change it by configuring the "access\_control\_message" attribute.
You can change it by configuring the "security\_message" attribute.

For example:

Expand All @@ -93,12 +93,12 @@ use ApiPlatform\Core\Annotation\ApiResource;
/**
* ...
* @ApiResource(
* attributes={"access_control"="is_granted('ROLE_USER')"},
* attributes={"security"="is_granted('ROLE_USER')"},
* collectionOperations={
* "post"={"access_control"="is_granted('ROLE_ADMIN')", "access_control_message"="Only admins can add books."}
* "post"={"security"="is_granted('ROLE_ADMIN')", "security_message"="Only admins can add books."}
* },
* itemOperations={
* "get"={"access_control"="is_granted('ROLE_USER') and object.owner == user", "access_control_message"="Sorry, but you are not the book owner."}
* "get"={"security"="is_granted('ROLE_USER') and object.owner == user", "security_message"="Sorry, but you are not the book owner."}
* }
* )
*/
Expand All @@ -114,17 +114,62 @@ Alternatively, using YAML:
# api/config/api_platform/resources.yaml
App\Entity\Book:
attributes:
access_control: 'is_granted("ROLE_USER")'
security: 'is_granted("ROLE_USER")'
collectionOperations:
post:
method: 'POST'
access_control: 'is_granted("ROLE_ADMIN")'
access_control_message: 'Only admins can add books.'
security: 'is_granted("ROLE_ADMIN")'
security_message: 'Only admins can add books.'
itemOperations:
get:
method: 'GET'
access_control: 'is_granted("ROLE_USER") and object.owner == user'
access_control_message: 'Sorry, but you are not the book owner.'
security: 'is_granted("ROLE_USER") and object.owner == user'
security_message: 'Sorry, but you are not the book owner.'
# ...
```

## Execute security after denormalization

The "security" attribute is executed before the object denormalization. For some cases, it might be useful to execute
a security after the denormalization.
To do so, prefer using "security\_post\_denormalize", which allows you to use the "previous\_object" as the original object:

```php
<?php
// src/Entity/Book.php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;

/**
* ...
* @ApiResource(
* attributes={"security"="is_granted('ROLE_USER')"},
* itemOperations={
* "get",
* "put"={"security_post_denormalize"="is_granted("ROLE_USER") and previous_object.owner == user"}
* }
* )
*/
class Book
{
// ...
}
```

Alternatively, using YAML:

```yaml
# api/config/api_platform/resources.yaml
App\Entity\Book:
attributes:
security: 'is_granted("ROLE_USER")'
itemOperations:
get: ~
put:
method: 'PUT'
security_post_denormalize: 'is_granted("ROLE_USER") and previous_object.owner == user'
# ...
```

Expand Down