Cliquet provides a mechanism to handle authorization on the stored objects
.
Authorization isn't complicated, but requires the introduction of a few terms so that explanations are easier to follow:
- Object:
The data that is stored into Cliquet.
objects
usually match the resources you defined; For one resource there are twoobjects
: resource's collection and resource's records.- Principal:
An entity that can be authenticated.
principals
can be individual people, computers, services, or any group of such things.- Permission:
An action that can be authorized or denied. read, write, create are
permissions
.- Access Control Entity (ACE):
An association of a
principal
, anobject
and apermission
. For instance, (Alexis, article, write).- Access Control List (ACL):
A list of Access Control Entities (
ACE
).
By default, the resources defined by Cliquet are public, and records are isolated by user. But it is also possible to define protected resources, which will required the user to have access to the requested resource.
from cliquet import authorization
from cliquet import resource
@resource.register(factory=authorization.RouteFactory)
class Toadstool(resource.ProtectedResource):
mapping = MushroomSchema()
In this example, a route factory is registered. Route factories are explained in more details below.
A protected resource, in addition to the data
property of request / responses, takes a permissions
property which contains the list of principals
that are allowed to access or modify the current object
.
During the creation of the object
, the permissions
property is stored in the permission backend, and upon access, it checks the current principal
has access the the object, with the correct permission.
The route factory decides which permission
is required to access one resource or another. Here is a summary of the permissions
that are defined by the default route factory Cliquet defines:
Method | :term:permission |
---|---|
POST | create |
GET / HEAD | read |
PUT | create if it doesn't exist, write otherwise |
PATCH | write |
DELETE | write |
Route factories are best described in the pyramid documentation
cliquet.authorization.RouteFactory
Upon access, the authorization policy is asked if any of the current list of principals
has access to the current resource. By default, the authorization policy Cliquet checks in the permission
backend for the current object
.
It is possible to extend this behavior, for instance if there is an inheritance tree between the defined resources (some ACEs
should give access to its child objects
).
In case the application should define its own inheritance tree, it should also define its own authorization policy.
To do so, subclass the default AuthorizationPolicy
and add a specific get_bound_permission
method.
from cliquet import authorization
from pyramid.security import IAuthorizationPolicy
from zope.interface import implementer
@implementer(IAuthorizationPolicy)
class AuthorizationPolicy(authorization.AuthorizationPolicy):
def get_bound_permissions(self, *args, **kwargs):
"""Callable that takes an object id and a permission and returns
a list of tuples (<object id>, <permission>)."""
return build_permissions_set(*args, **kwargs)
cliquet.authorization.AuthorizationPolicy
The ACLs
are stored in a permission
backend. Currently, permission backends exists for Redis and PostgreSQL, as well as a in memory one. It is of course possible to add you own permission backend, if you whish to store your permissions
related data in a different database.
cliquet.permission.PermissionBase