Base Classes

Abstract base classes for guardrail plugins. Plugin developers should subclass BasePermissionManager and BasePermissionSchemaFactory, and optionally BaseLoader as well.

class guardrail.core.models.BasePermissionManager(registry=<guardrail.core.registry._Registry object>)[source]

Abstract base class for permission managers. Concrete subclasses must implement CRUD operations (check, add, and remove permissions), as well as the _is_saved() check.

Parameters:registry (_Registry) – Optional registry object; use global registry if not provided.
get_permissions(agent, target, Agent=None, Target=None, custom=None)[source]

List all permissions record agent has on record target.

Parameters:
  • agent – Agent record
  • target – Target record
  • Agent – Optional agent schema; provide if permission is not directly related to agent
  • Target – Optional target schema; provide if permission is not directly related to target
  • custom – Optional callable for customizing permission queries; if provided, will be passed the original query, agent, target, and the permission join table
Returns:

Set of permission labels between agent and target

has_permission(agent, target, permission, Agent=None, Target=None, custom=None)[source]

Check whether record agent has permission permission on record target.

Parameters:
  • agent – Agent record
  • target – Target record
  • permission (str) – Permission
  • Agent – Optional agent schema; provide if permission is not directly related to agent
  • Target – Optional target schema; provide if permission is not directly related to target
  • custom – Optional callable for customizing permission queries; if provided, will be passed the original query, agent, target, and the permission join table
Returns:

Record agent has permission permission on record target

add_permission(agent, target, permission)[source]

Grant permission permission to record agent on record target.

Parameters:
  • agent – Agent record
  • target – Target record
  • permission (str) – Permission
Returns:

Created permission record

Raises:

PermissionExistsError if permission has already been granted

remove_permission(agent, target, permission)[source]

Revoke permission permission from record agent on record target.

Parameters:
  • agent – Agent record
  • target – Target record
  • permission (str) – Permission
Raises:

PermissionNotFound if permission has not been granted

_get_permission_schema(agent, target, Agent=None, Target=None)[source]

Look up join table linking agent and target, verifying that both records have been persisted.

Parameters:
  • agent – Agent record
  • target – Target record
  • Agent – Optional agent schema; provide if permission is not directly related to agent
  • Target – Optional target schema; provide if permission is not directly related to target
Returns:

Join table between agent and target

Raises:

RecordNotSaved if either record has not been persisted

Raises:

SchemaNotFound if no join table exists

_is_saved(record)[source]

Check whether record has been persisted. Note: For backends that do not require records to be persisted to operate on foreign-key relationships, this method should always return True.

Parameters:record – Record to check
Returns:record has been persisted
class guardrail.core.models.BasePermissionSchemaFactory(bases)[source]

Abstract base class for schema factories that create permission join tables. Concrete subclasses must implement _get_table_name() and _make_schema_dict().

Parameters:bases (tuple) – Base classes for created schema classes
_update_parents(agent, target, schema)[source]

Creating a permission join table may require mutating the agent and target schemas. By default, take no action.

Parameters:
  • agent – Agent schema class
  • target – Target schema class
  • schema – Created schema class
_make_schema_name(agent, target)[source]

Build class name for permission join table.

Parameters:
  • agent – Agent schema class
  • target – Target schema class
_make_table_name(agent, target)[source]

Build table name for permission join table.

Parameters:
  • agent – Agent schema class
  • target – Target schema class
_get_table_name(schema)[source]

Get table name for schema.

Parameters:schema – Schema class
_make_schema_dict(agent, target)[source]

Build class dictionary for permission join table.

Parameters:
  • agent – Agent schema class
  • target – Target schema class
Returns:

Dictionary of class members

Registry

class guardrail.core.registry._Registry[source]

Registry of schemas designated as permission agents and targets, as well as the permission tables linking each agent-target pair. Should be used as a singleton in ordinary use, but can be instantiated for use in tests.

agent(agent)[source]

Decorator that registers the decorated schema as a permission agent.

Example:

@registry.agent
class User(Base):
    id = sa.Column(sa.Integer, primary_key=True)
target(target)[source]

Decorator that registers the decorated schema as a permission target.

Example:

@registry.target
class Post(Base):
    id = sa.Column(sa.Integer, primary_key=True)
add_permission(agent, target, permission)[source]

Get the join table linking schemas agent and target.

Parameters:
  • agent – Agent schema class
  • target – Target schema class
  • schema – Permission join table
get_permission(agent, target)[source]

Get the join table linking schemas agent and target.

Parameters:
  • agent – Agent schema class
  • target – Target schema class
Returns:

Permission join table

Raises:

guardian.core.exceptions.SchemaNotFound if join table does not exist

make_schemas(factory)[source]

Create and register join tables linking all registered agent-target pairs.

Parameters:factory – Callable that takes agent and target schemas and returns the schema for a permission join table

Decorators

class guardrail.core.decorators.has_permission(permission, manager, agent_loader, target_loader, error_handler)[source]

Factory for permission-checking decorators. Should be subclassed or have arguments pre-filled with functools.partial.

Parameters:
  • permission – Permission value
  • manager – Permission manager
  • agent_loader – Callable that loads an agent from the args and kwargs passed to the decorated function
  • target_loader – Callable that loads a target from the args and kwargs passed to the decorated function
  • error_handler – Callable that handles error codes AGENT_NOT_FOUND, TARGET_NOT_FOUND, and FORBIDDEN
__call__(func)[source]

Decorator that checks permissions before calling func. Note: wrapped function will be called with the loaded agent and target.

Parameters:func – Callable to decorate
_check_permission(*args, **kwargs)[source]

Load agent and target records from agent_loader and target_loader, then check for the requested permission. Call error_handler if either loader returns None, or if permission is not present.

Extensions

SQLAlchemy

SQLAlchemy plugin for guardrail.

class guardrail.ext.sqlalchemy.SqlalchemyPermissionSchemaFactory(bases, cascade=False)[source]

Permission schema factory for use with SQLAlchemy.

Parameters:
  • bases (tuple) – Base classes for created schema classes
  • cascade (bool) – Database backend supports ON DELETE and ON UPDATE cascades; see _update_parents() for details

Peewee

Peewee plugin for guardrail.

class guardrail.ext.peewee.PeeweePermissionSchemaFactory(bases)[source]

Permission schema factory for use with Peewee.

Note: Peewee does not implement delete and update cascades outside the database backend, so care should be taken with deleting agent and target records when using a backend that does not support cascades (e.g. SQLite, MySQL using the MyISAM storage engine). In this case, use the recursive flag when deleting through Peewee:

agent.delete_instance(recursive=True)

Pony ORM

Pony plugin for guardrail.

Django ORM

Django plugin for guardrail. Note: Define permission schema factory in models.py so that Django migrations can detect permission schemas.

Custom object permissions backend for Django plugin

class guardrail.ext.django.backends.ObjectPermissionBackend[source]

Custom authentication backend for object-level permissions. Must be used in conjunction with a backend that handles the authenticate and get_user methods, such as the default django.contrib.auth.backends.ModelBackend.