Skip to content

Commit

Permalink
Update documentation for permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
tarsil committed Aug 30, 2023
1 parent 3be761c commit 5503107
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
31 changes: 29 additions & 2 deletions docs/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,37 @@ all the huge community of developer in mind to make a transition almost immediat

All the permission classes **must derive** from `BasePermission`.

The permissions **must** implement the `has_permission` and return `True` or `False`.

The permissions can also be `async` in case you need to run awaitables.

**An example of a permission for an user admin**.

```python
{!> ../docs_src/permissions/permissions.py !}
```

**An example of a permission for an user admin with async**.

```python hl_lines="25"
{!> ../docs_src/permissions/async/permissions.py !}
```

**An example of a permission for a project**

```python
{!> ../docs_src/permissions/simple_permissions.py !}
```

**An example of a permission for a project with async**

```python hl_lines="10"
{!> ../docs_src/permissions/async/simple_permissions.py !}
```

## Esmerald and permissions

Esmerald giving support to [Saffier ORM](./databases/saffier/motivation.md) also provides some default permissions
Esmerald giving support to [Saffier ORM](./databases/saffier/motivation.md) and [Edgy](./databases/edgy/motivation.md) also provides some default permissions
that can be linked to the models also provided by **Esmerald**.

### IsAdminUser and example of provided permissions
Expand Down Expand Up @@ -65,10 +81,21 @@ To use the `IsAdminUser`, `IsAuthenticated` and `IsAuthenticatedOrReadOnly` is a
of the endpoints under the class (endpoints under `/users`).
3. The `/users/admin` has a permission `IsAdmin` allowing only admin users to access the specific endpoint

### More on permissions

The permissions internally are checked from top down which means you can place permissios at any
given part of the [level](./application/levels.md) making it more dynamic and allowing to narrow
it down to a granular level that is managenable.

Internally, Esmerald runs all the validations and checks and on an application level, the only
thing you need to make sure is to **implement the `has_permission`** on any derived class of
[BasePermission](#basepermission-and-custom-permissions).

## Permissions summary

1. All permissions must inherit from `BasePermission`.
2. `BasePermission` has the `has_permission(request Request, apiview: "APIGateHandler").
2. `BasePermission` has the `has_permission(request Request, apiview: "APIGateHandler") and it can
be `async` or not.
3. The [handlers](./routing/handlers.md), [Gateway](./routing/routes.md#gateway),
[WebSocketGateway](./routing/routes.md#websocketgateway), [Include](./routing/routes#include)
and [Esmerald](./application/applications.md) can have as many permissions as you want.
27 changes: 27 additions & 0 deletions docs_src/permissions/async/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from esmerald import Request
from esmerald.permissions.base import BaseAbstractUserPermission
from esmerald.types import APIGateHandler


class IsUserAdmin(BaseAbstractUserPermission):
"""
Simply check if a user has admin access or not.
BaseAbstractUserPermission inherits from BasePermission.
"""

def is_user_authenticated(self, request: "Request") -> bool:
"""
Logic to check if the user is authenticated
"""
...

def is_user_staff(self, request: "Request") -> bool:
"""
Logic to check if user is staff
"""
...

async def has_permission(self, request: "Request", apiview: "APIGateHandler"):
super().has_permission(request, apiview)
return bool(request.user and self.is_user_staff(request))
12 changes: 12 additions & 0 deletions docs_src/permissions/async/simple_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from esmerald import BasePermission, Request
from esmerald.types import APIGateHandler


class IsProjectAllowed(BasePermission):
"""
Permission to validate if has access to a given project
"""

async def has_permission(self, request: "Request", apiview: "APIGateHandler"):
allow_project = request.headers.get("allow_access")
return bool(allow_project)

0 comments on commit 5503107

Please sign in to comment.