caps.models
caps.models.agent
- class Agent(*args, **kwargs)[source]
Bases:
ModelAn agent is the one executing an action. It can either be related to a specific user (anonymous included) or group.
A user can impersonate multiple agent.
- 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.
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.childrenis aReverseManyToOneDescriptorinstance.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.
- 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.
- property is_anonymous: bool
Return True when Agent targets anonymous users.
- is_default
If True, use this Agent as user’s default.
- objects = <django.db.models.manager.ManagerFromAgentQuerySet object>
- access
Public Share to agent.
- user
Agent targets this user.
- user_id
- class AgentQuerySet(model=None, query=None, using=None, hints=None)[source]
Bases:
QuerySet
caps.models.capability
- CanOne: TypeAlias = django.contrib.auth.models.Permission | int | tuple[str, int | django.contrib.contenttypes.models.ContentType | type]
Describe lookup for a capability’s permission.
It either can be:
A Permission or a permission id;
A tuple with Permission codename, and content type (id, ContentType instance, or model class);
It is used by
CapabilityQuerySet.can()
- CanMany: TypeAlias = django.contrib.auth.models.Permission | int | tuple[str, int | django.contrib.contenttypes.models.ContentType | type] | collections.abc.Iterable[django.contrib.auth.models.Permission | int | tuple[str, int | django.contrib.contenttypes.models.ContentType | type]]
Describe lookup value for multiple capabilities’ description.
It is used by
CapabilityQuerySet.can()
- class Capability(*args, **kwargs)[source]
Bases:
ModelA single capability providing permission for executing a single action.
It is linked to an object by a
Share. The Share is the entry point for user to address/access the object. The capability represent what he can do.This model is provided as abstract model whose implementation MUST provide a
Shareforeign key to aShare(reverse relation: capabilities). The foreign key is nullable,Nonehave special meaning: it represents default assigned capabilities to newly created root Share instances. They can be fetched usingCapabilityQuerySet.get_initials().See
Sharedocumentation for more information.It is recommanded to
select_relatedpermission in order to readnameandcodename.Derivation
Capability can derived: it means the permission is shared to another agent. To be allowed to share,
max_derivemust be greater than 0. When sharing only a lower value is allowed to the new capability’s field.Lets see what it does:
from models import MyObject permission = Permission.objects.all().first() cap = MyObject.Capability(permission=permission, max_derive=2) # `cap` is not saved, we don't core to provide a Share for this example. # providing no max_derive defaults to 0 cap_1 = cap.derive(0) assert cap_1.max_derive == 0 # this raises PermissionDenied cap_1.derive() # max_derive reduced by 1 cap_1 = cap.derive() assert cap_1.max_derive == 1 cap_2 = cap_1.derive() assert cap_2.max_derive == 0
- class Meta[source]
Bases:
object- abstract = False
- unique_together = (('Share', 'permission_id'),)
- can_derive(max_derive=None)[source]
Return True if this capability can be derived.
- Return type:
bool- Parameters:
max_derive (None | int)
- derive(max_derive=None, Share=None, **kwargs)[source]
Derive a new capability from self (without checking existence in database).
- Return type:
- Parameters:
max_derive (
None|int) – when value is None, it will based the value on self’s py:attr:max_derive minus 1.**kwargs –
extra initial argument of the new Capability
:return the new unsaved Capability.
- Yield PermissionDenied:
when Capability derivation is not allowed.
- Parameters:
max_derive (None | int)
- Return type:
Return related Share class.
- is_derived(capability=None)[source]
Return True if capability is derived from this one.
- Return type:
bool- Parameters:
capability (Capability)
- max_derive
Maximum allowed derivations.
- objects
- permission
Related permission
- permission_id
- class CapabilityQuerySet(model=None, query=None, using=None, hints=None)[source]
Bases:
QuerySetQueryset and manager used by Capability models.
- can(permissions)[source]
Filter using provided permission.
When permission is an iterable, it will perform an OR conditional statement between all provided values.
- Parameters:
permissions (CanMany) – permissions to filter.
- Return type:
- static can_one_lookup(permission, paccessix='permission__')[source]
Return lookup for one permission.
- Return type:
dict[str,str|int]- Parameters:
permission (CanOne) – to get lookup for.
paccessix – paccessix keys with this value.
:return lookup argument dictionnary.
- Yield ValueError:
on unsupported
permissiontypes.- Parameters:
permission (CanOne)
- Return type:
dict[str, str | int]
caps.models.capability_set
- class CapabilitySet[source]
Bases:
objectBase class to handle set of capabilities.
This class should not be used per se.
- Cap: int | tuple[int, int]
Capability information, as tuple of
(permission_id, max_derive)or single permission id (thenmax_derive is None).
- Capability: type[Capability] | Permission
Capability class to use. It must be set in order to use CapabilitySet.
- Caps: Iterable[CapabilitySet.Cap]
Many capability information.
- capabilities: Iterable[Capability] = None
Capabilities contained in the CapabilitySet.
- create_capabilities(caps, **kwargs)[source]
Create multiple capabilities based on descriptors.
- Parameters:
caps – capabilities’ informations
**kwargs –
extra initial arguments
- Return type:
list[CapabilitySet.Capability]
:return a list of unsaved capabilities instances.
- create_capability(cap, **kwargs)[source]
Create a single (unsaved) capability.
- Parameters:
cap – capability information
**kwargs –
extra initial arguments
- Return type:
CapabilitySet.Capability
:return the new unsaved capability instance.
- derive_caps(caps=None, raises=False, defaults={})[source]
Derive capabilities from this set.
When caps is provided, it will only derive allowed derivations for declared capabilities.
When caps is not provided, it derives all allowed capabilities of the set.
The created capabilities are not saved to the db.
- Parameters:
source – capabilities to derive
caps – specify which capabilities to derive
raises – if True, raise exception when there are denied derivation.
defaults – initial arguments to pass to all generated capabilities.
- Return type:
list[Capability]
:return the list of derived capabilities. :yield PermissionDenied: when there are unauthorized derivation and :py:param:`raises` is True.
- get_capabilities()[source]
- Return type:
Iterable[Capability]
- get_capability(codename)[source]
Get capability by name or None.
- Return type:
Capability|None- Parameters:
codename (str)
- get_capability_kwargs(cap, defaults)[source]
From provided
capdescription, return a tuple with permission id andCapability.derive()arguments.We return a tuple because permission id can not be provided to the derive method.
- Parameters:
cap – the capability descriptor;
**kwargs –
extra arguments to pass down to the method;
defaults (dict[str, Any])
- Return type:
tuple[int, dict[str, Any]]
- is_derived(other)[source]
Return True if capabilities iterable is a subset of self.
Set is a subset of another one if and only if: - all capabilities of subset are in set and derived from set (cf. Capability.is_subset) - there is no capability inside subset that are not in set.
- Return type:
bool- Parameters:
other (CapabilitySet)
caps.models.object
- class Object(*args, **kwargs)[source]
Bases:
ModelAn object accessible through Shares.
It can have a member Share (subclass of caps.models.Share) that is used as object’s specific Share. If none is provided, a it will be generated automatically for concrete classes.
The
Capabilityconcrete model class will be set at creation, when the relatedShareis created.This provides:
Shareconcrete model accessible from theObjectconcrete subclass;Capabilityconcrete model accessible from theObjectconcrete subclass;
- Capability
alias of
ObjectShareCapability
alias of
ObjectShare
- objects
Return Share to this object for receiver provided to ObjectQuerySet’s access() or accesses().
- class ObjectBase(name, bases, attrs)[source]
Bases:
NestedBaseMetaclass for Object model classes.
It subclass Share if no Share member is provided.
- classmethod create_nested_class(new_class, name, attrs={})[source]
Provide target ForeignKey on nested Share model.
-
nested_name:
str|None= 'Share' Attribute and class name of the nested class. If not provided, takes it from
nested_class
- class ObjectQuerySet(model=None, query=None, using=None, hints=None)[source]
Bases:
QuerySetQuerySet for Objects.
- access(receiver, uuid, accesses=None)[source]
Return Share for provided receiver and uuid.
This method annotates the Object with
agent_Share_setwhose value is set to relevant Share(s). This allows to useShareproperty.Please accesser to
ShareQuerySet.access()for more information.- Parameters:
receiver (
Agent|Iterable[Agent] |None) – the Share’s receiveruuid (
UUID) – Share uuidaccesses (
ShareQuerySet|None) – use this Share QuerySet
- Return type:
- accesses(receiver, uuids, accesses=None)[source]
Return Shares for provided receiver and uuids.
Please accesser to
access()andShareQuerySet.accesses()for more information.- Parameters:
receiver (
Agent|Iterable[Agent] |None) – the Share’s receiveruuids (
Iterable[UUID]) – Share uuidsaccesses (
ShareQuerySet|None) – use this Share QuerySet
- Return type:
caps.models.nested
- class NestedBase(name, bases, attrs)[source]
Bases:
ModelBaseThis metaclass allows to create nested model class based from parent one.
By default, the method will first look for an existing declaration. If none is found it will create one with only the declared
nested_classas base. This means that you must manually declare any other parent class:class Nested: pass class ParentBase(NestedBase): nested_class = Nested @classmethod def create_nested_class(cls, name, attrs={}): return super(Parent, cls).create_nested_class( name, {"custom_field": ForeignKey()} ) class Parent(metaclass=NestedBase): pass class A(Parent): # you must declare its bases class Nested(Nested): # customize code here pass class C(A, B): # you need to be explicit class Nested(A.Nested): pass
- classmethod create_nested_class(new_class, name, attrs={})[source]
Create the nested class for the provided container one to-be-created.
- Parameters:
new_class (
type[object]) – the parent class that just has been createdname (
str) – nested class nameattrs (
dict[str,Any]) – nested class attributes
- Return type:
type
:return the newly created class.
- classmethod get_nested_class(new_class)[source]
Get nested model class or creates a new one.
- Parameters:
new_class (type[object])
-
nested_class:
type[object] = None Nested class base to create.
-
nested_name:
str|None= None Attribute and class name of the nested class. If not provided, takes it from
nested_class
-
new_name:
str= '{class_name}{nested_name}' Name format for newly created classes.
- 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 intoset (
dict[str,Any]) – attributes to set to the classdefaults (
dict[str,Any]) – attributes to set to the class if not present
- Return type:
type
:return the Meta class.