caps.models

caps.models.agent

class Agent(*args, **kwargs)[source]

Bases: Model

An agent is the one executing an action. It can either be related to a specific user (anonymous included) or group.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

clean()[source]

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

concreteowned_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

group

Agent targets this group. Related name: ‘agents’.

group_id
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_agent(user)[source]

Return True if user can act as this agent.

This methods also check based on user’s group and anonymity.

Parameters:

user (User)

property is_anonymous: bool

Return True when Agent targets anonymous users.

objects = <django.db.models.manager.ManagerFromAgentQuerySet object>
user

Agent targets this user. Related name: ‘agents’.

user_id
uuid

Public access to agent.

class AgentQuerySet(model=None, query=None, using=None, hints=None)[source]

Bases: QuerySet

group(group)[source]

Filter by group.

Return type:

AgentQuerySet

Parameters:

group (Group)

user(user, strict=False)[source]

Filter by user or its groups.

Parameters:
  • user (User) – User

  • strict (bool) – if False, search on user’s groups.

Return type:

AgentQuerySet

caps.models.access

class Access(*args, **kwargs)[source]

Bases: Model

Access are the entry point to access an Owned.

Access provides a set of capabilities for specific receiver. The concrete sub-model MUST provide the target foreign key to an Owned.

There are two kind of access:

  • root: the root access from which all other accesses to object are derived. Created from the create() class method. It has no origin and there can be only one root access per :py:class:`Owned` instance.

  • derived: access derived from root or another derived. Created from the derive() method.

This class enforce fields validation at save() and bulk_create().

Concrete Access

This model is implemented as an abstract in order to have a access specific to each model (see Owned abstract model). The actual concrete class is created when Owned is subclassed by a concrete model.

class Meta[source]

Bases: object

abstract = False
unique_together = (('origin', 'receiver', 'target'),)
async ashare(receiver, grants=None, **kwargs)[source]

Create a new saved access shared from self (async).

See get_share() for arguments.

Parameters:
  • receiver (Agent)

  • grants (dict[str, int] | None)

emitter

Agent receiving capability.

emitter_id
expiration

Date of expiration.

get_absolute_url()[source]
get_all_permissions(user)[source]

Return allowed permissions for this user.

Return type:

set[str]

Parameters:

user (User)

classmethod get_object_class()[source]

Return related Owned class.

get_share(receiver, grants=None, **kwargs)[source]

Return new access shared from self. The object is not saved.

Parameters:
  • receiver (Agent) – the receiver

  • grants (dict[str, int] | None) – optional granted permissions

  • **kwargs

    extra initial arguments

Yield PermissionDenied:

when access expired or no grant is shareable.

get_share_grants(grants=None, **kwargs)[source]

Return grants for shared access.

Return type:

dict[str, int]

Parameters:

grants (dict[str, int] | None)

get_share_kwargs(receiver, kwargs)[source]

Return initial argument for a derived access from self.

Parameters:

receiver (Agent)

grants

Allowed permissions as a dict of {"permission": allowed_reshare}.

The integer value of allowed_reshare determines the amount of reshare can be done.

has_perm(user, permission)[source]

Return True if access grants the provided permission.

Return type:

bool

Parameters:
  • user (User)

  • permission (str)

property is_expired

Return True if Access is expired.

is_valid(raises=False)[source]

Check Access values validity, throwing exception on invalid values.

:returns True if valid, otherwise raise ValueError :yield ValueError: when access is invaldi

Return type:

bool

Parameters:

raises (bool)

objects
origin

Source access in accesses chain.

origin_id
receiver

Agent receiving capability.

receiver_id
save(*a, **kw)[source]

Save the current instance. Override this in a subclass if you want to control the saving process.

The ‘force_insert’ and ‘force_update’ parameters can be used to insist that the “save” must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.

share(receiver, grants=None, **kwargs)[source]

Create a new saved access shared from self.

See get_share() for arguments.

Parameters:
  • receiver (Agent)

  • grants (dict[str, int] | None)

uuid

Public access id used in API.

class AccessQuerySet(model=None, query=None, using=None, hints=None)[source]

Bases: QuerySet

QuerySet for Access classes.

access(receiver, uuid)[source]

Access by uuid and receiver(s).

Note that receiver is provided as first parameter in order to enforce its usage. It however can be None: this only should be used when queryset has already been filtered by receiver.

Parameters:
  • receiver (Agent | Iterable[Agent] | None) – the agent that retrieving the access.

  • uuid (UUID) – the access uuid to fetch.

Yield DoesNotExist:

when the access is not found.

Return type:

AccessQuerySet

accesses(receiver, uuids)[source]

Accesss by many uuid and receiver(s).

Please accesser to AccessQuerySet.access() for more information.

Parameters:
  • receiver (Agent | Iterable[Agent] | None) – the agent that retrieving the access.

  • uuids (Iterable[UUID]) – an iterable of uuids to fetch

Return type:

AccessQuerySet

agent(agent)[source]

Filter accesses that agent is either receiver or emitter..

Return type:

AccessQuerySet

Parameters:

agent (Agent | Iterable[Agent])

available(agent=None)[source]

Return available accesses based on expiration and eventual user.

Return type:

AccessQuerySet

Parameters:

agent (Agent | Iterable[Agent] | None)

bulk_create(objs, *a, **kw)[source]

Check that objects are valid when saving models in bulk.

emitter(agent)[source]

Accesss for the provided emitter(s).

Return type:

AccessQuerySet

Parameters:

agent (Agent | Iterable[Agent])

expired(exclude=False)[source]

Filter by expiration.

Parameters:

exclude (bool) – if True, exclude instead of filter.

Return type:

AccessQuerySet

receiver(agent)[source]

Accesss for the provided receiver(s).

Return type:

AccessQuerySet

Parameters:

agent (Agent | Iterable[Agent])

caps.models.owned

class Owned(*args, **kwargs)[source]

Bases: Model

An object accessible through Accesss.

It can have a member Access (subclass of caps.models.Access) that is used as object’s specific access. If none is provided, a it will be generated automatically for concrete classes.

The Capability concrete model class will be set at creation, when the related Access is created.

This provides:

  • Access concrete model accessible from the Owned concrete subclass;

  • Capability concrete model accessible from the Owned concrete subclass;

Access

alias of OwnedAccess

class Meta[source]

Bases: object

abstract = False
access

Return Access to this object for receiver provided to OwnedQuerySet’s access() or accesses().

async ashare(receiver, grants=None, **kwargs)[source]

Share and save access to this object (async).

Return type:

Access

Parameters:
  • receiver (Agent)

  • grants (dict[str, int] | None)

classmethod check_root_grants()[source]

Lookup for declared permissions of root_grants, raising ValueError if there are declared permissions not present in database.

detail_url_name = None

Provide url name used for get_absolute_url.

get_absolute_url()[source]
Return type:

str

get_all_permissions(user)[source]

Return allowed permissions for this user.

Return type:

set[str]

get_share(receiver, grants=None, **kwargs)[source]

Share this object to this receiver, returning new unsaved Access.

Parameters:
  • receiver (Agent) – share’s receiver

  • grants (dict[str, int] | None) – allowed permissions (should be in root_grants)

  • **kwargs

    extra initial arguments

Return type:

Access

has_perm(user, perm)[source]

Return True if user has provided permission for object.

Return type:

bool

Parameters:

perm (str)

objects
owner

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

owner_id
root_grants = {}

This class attribute provide the default value for grant object. It should follows the structure of grants field, such as:

root_grants = {
    "auth.view_user": 1,
    "app.change_mymodel": 2
}
share(receiver, grants=None, **kwargs)[source]

Share and save access to this object.

See get_share() for parameters.

Return type:

Access

Parameters:
  • receiver (Agent)

  • grants (dict[str, int] | None)

uuid

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class OwnedBase(name, bases, attrs)[source]

Bases: NestedModelBase

Metaclass for Owned model classes.

It subclass Access if no Access member is provided.

classmethod create_nested_class(new_class, name, attrs={})[source]

Provide target ForeignKey on nested Access model.

nested_class

alias of Access

nested_name: str | None = 'Access'

Attribute and class name of the nested class. If not provided, takes it from nested_class

class OwnedQuerySet(model=None, query=None, using=None, hints=None)[source]

Bases: QuerySet

QuerySet for Owneds.

access(access, strict=False)[source]

Prefetch object with accesses from the provided queryset (as agent_accesses).

The items are annotated with access_uuid corresponding to the access.

Parameters:
  • access (AccessQuerySet | Access) – use this Access QuerySet or instance

  • strict (bool) – if True, filter only items with prefetched access

Return type:

OwnedQuerySet

Returns:

the annotated and prefetched queryset.

available(agents, accesses=None)[source]

Return object available to provided agents as owner or receiver (when accesses is provided).

It prefetch/annotates the resulting items using access(), if accesses is provided.

Parameters:
  • agents (Union[Agent, Iterable[Agent]]) – for the provided agent

  • accesses (AccessQuerySet | None) – use this queryset for accesses

caps.models.nested

class NestedModelBase(name, bases, attrs)[source]

Bases: NestedBase, ModelBase

This metaclass allows to create nested model class based from parent one.

See NestedBase for more information about usage.

classmethod create_nested_class(new_class, name, attrs={})[source]

Create the nested class for the provided container one to-be-created.

It ensures the Meta class to have default values based on the new class (for app_label, abstract, etc.).

Return type:

type

Parameters:
  • new_class (type[object])

  • name (str)

  • attrs (dict[str, Any])

classmethod set_meta(attrs, set={}, defaults={})[source]

Get or create new meta class assigning to it the provided attributes.

Parameters:
  • attrs (dict[str, Any]) – attribute to look into.

  • set (dict[str, Any]) – attributes to set to the class.

  • defaults (dict[str, Any]) – attributes to set to the class if not present.

Return type:

type

:return the Meta class.