signoffs.core.signoffs#

A Signoff defines the business and presentation logic for collecting a single “signature”

Signoff Types are registered subclasses of AbstractSignoff - they define the behaviour for a Signoff. Persistence layer for Signoff state is provided by a Signet model - one concrete Signet model can back any number of Signoff Types - can think of a Signoff instance as the strategy for managing a Signet instance.

Module Contents#

Classes#

AbstractSignoff

Defines the abstract semantics for a Signoff and serves as base class for all concrete Signoff Types.

BaseSignoff

A base Signoff Type to be used as abstract base class to register concrete Signoff Types Concrete Types will require a concrete Signet Model to back the signoff.

DefaultSignoffBusinessLogic

Defines the default business logic for signing and revoking a Signoff instance

SignoffLogic

Public API: Alias for `DefaultSignoffBusinessLogic

Functions#

sign_signoff

Force signature onto given signoff for given user and save its signet, regardless of permissions or signoff state

revoke_signoff

Force revoke the given signoff for user regardless of permissions or signoff state.

API#

signoffs.core.signoffs.sign_signoff(signoff, user, commit=True, **kwargs)[source]#

Force signature onto given signoff for given user and save its signet, regardless of permissions or signoff state

kwargs are passed directly to save - use commit=False to sign without saving.

signoffs.core.signoffs.revoke_signoff(signoff, user, reason='', revokeModel=None, **kwargs)[source]#

Force revoke the given signoff for user regardless of permissions or signoff state.

@param revokeModel: if supplied, create record of revocation, otherwise just delete the signet.

class signoffs.core.signoffs.AbstractSignoff(signet=None, subject=None, **kwargs)[source]#

Defines the abstract semantics for a Signoff and serves as base class for all concrete Signoff Types.

A Signoff Type (i.e. subclass of AbstractSignoff) defines the behaviours for a specific type of signoff.

A Signoff instance represents a timestamped agreement by a User, persisted by a Signet model instance. Signoffs are pure code objects, not stored in the DB - they define application logic, not application data. A Signoff Type defines:

  • how the Signet is labelled and rendered,

  • what permission is required to sign or revoke it,

  • what forms are used to sign and revoke them, etc. The default meta-data and services can be overridden in a subclass or passed to .register() factory. Signoff Types are registered in the signoffs.registry.signoffs registry where they can be retrieved by id

Caution

Signet records are stored in DB with a reference to Signoff.id Be cautions not to change or delete id’s that are in-use.

Initialization

Construct a Signoff instance backed by the given signet or an instance of cls.signetModel(**kwargs)

subject is optional: the object this signoff is signing off on - set by SignoffField but otherwise unused.

id: str#

‘signoff.abstract’

signetModel: signoffs.core.signoffs.signet_type#

None

logic: signoffs.core.signoffs.SignoffLogic#

None

revokeModel: signoffs.core.signoffs.revoke_type#

None

label: str = <Multiline-String>#
render: signoffs.core.renderers.SignoffRenderer#

None

forms: signoffs.core.forms.SignoffFormsManager#

None

urls: signoffs.core.urls.SignoffUrlsManager#

None

classmethod register(id, **kwargs)[source]#

Create, register, and return a new subclass of cls with overrides for given kwargs attributes

Standard mechanism to define new Signoff types, typically in my_app/models.py or my_app/signoffs.py Usage:

    MySignoff = AbstractSignoff.register('my_signoff_type', label='Sign it!', ...)
classmethod validate()[source]#

Run any class validation that must pass before class can be registered. Invoked by registry.

classmethod get_signetModel()[source]#

Always use this accessor as the signetModel attribute may be an “app.Model” label

classmethod get_signet_queryset()[source]#

Return a base (unfiltered) queryset of ALL signets for this Signoff Type

classmethod get_revoked_signets_queryset()[source]#

Return a base (unfiltered) queryset of ALL revoked signets for this Signoff Type

classmethod get_revokeModel()[source]#

Always use this accessor as the revokeModel attributed may be an “app.Model” label

classmethod get(queryset=None, **filters)[source]#

Return the saved signoff that matches filters or a new signoff with these initial values if none exists

Raises MultipleObjectsReturned if more than one signoff matches filter criteria.

classmethod create(user, **kwargs)[source]#

Create and return a signoff signed by given user

property subject#

The object being signed off on, if provided.

Subclass with signet FK relations may want to override this to access the signet related object. subject is set by model Fields for convenient access to owner obj, but value is not used by core logic.

property slug#

A slugified version of the signoff id, for places where a unique identifier slug is required

property signet_model#

Return the signoff model for this type

property revoke_model#

Return the revoke model for this type

get_new_signet(**initial_values)[source]#

Get a new, unsaved signet instance for this signoff type, with given optional initial values

__str__()[source]#
__eq__(other)[source]#
matches(other)[source]#

Return True iff this signoff is of same type as other, which may be a signoff instance or a str

get_signet_defaults(user)[source]#

Return a dictionary of default values for fields this signoff’s signet -

Called during signoff.sign - provides default values that will NOT override values already set on the signet. See signets.get_signet_defaults for further docs.

classmethod is_permitted_signer(user)[source]#

return True iff user has permission to sign a signoff of this Type

can_sign(user)[source]#

return True iff this signoff instance can be signed by given user

sign_if_permitted(user, commit=True, **kwargs)[source]#

Sign for given user and save signet, if self.can_sign(user), raise PermissionDenied otherwise

kwargs are passed directly to sign_method - use commit=False to sign without saving.

sign(user, commit=True, **kwargs)[source]#

Sign for given user and save signet, regardless of permissions or signoff state

kwargs are passed directly to sign_method - use commit=False to sign without saving.

classmethod is_permitted_revoker(user)[source]#

Return True iff user has permission to revoke signoffs of this Type

can_revoke(user)[source]#

Return True iff this signoff can be revoked by given user

revoke_if_permitted(user, reason='', **kwargs)[source]#

Revoke this signoff for user if they have permission, otherwise raise PermissionDenied

revoke(user, reason='', **kwargs)[source]#

Revoke this signoff regardless of permissions or signoff state - careful!

Prefer to use revoke_if_permitted to enforce business rules.

property signatory#

Return the user who signed, or AnonymousUser if signed but no signatory, None if not yet signed

property sigil#

Return the “sigil” on this signoff if it is signed, None otherwise

property sigil_label#

Return a label for the “sigil” on this signoff, if it is signed, None otherwise

property timestamp#

Return the timestamp on this signoff if it is signed, None otherwise

has_user()[source]#

return True iff this signoff has a user-relation

can_save()[source]#

return True iff this signoff’s signet is ready to be saved

update(**attrs)[source]#

Update signet model fields with any attrs that match by name

validate_save()[source]#

Raise PermissionDenied if this Signoff cannot be saved, otherwise just pass.

save(*args, **kwargs)[source]#

Attempt to save a Signet with the provided associated data for this Signoff

is_signed()[source]#

return True if this Signoff has been signed but not revoked

is_revoked()[source]#

return True if this Signoff has been revoked

classmethod has_object_relation()[source]#
class signoffs.core.signoffs.BaseSignoff(signet=None, subject=None, **kwargs)[source]#

Bases: signoffs.core.signoffs.AbstractSignoff

A base Signoff Type to be used as abstract base class to register concrete Signoff Types Concrete Types will require a concrete Signet Model to back the signoff.

Tip

Register new Signoff Types with:: BaseSignoff.register(...)

Initialization

Construct a Signoff instance backed by the given signet or an instance of cls.signetModel(**kwargs)

subject is optional: the object this signoff is signing off on - set by SignoffField but otherwise unused.

id#

‘signoffs.base-signoff’

signetModel#

None

revokeModel#

None

label#

‘I consent’

class signoffs.core.signoffs.DefaultSignoffBusinessLogic(perm=None, sign_method=None, revoke_perm=None, revoke_method=None)[source]#

Defines the default business logic for signing and revoking a Signoff instance

Note

SignoffBusinessLogic should not encode contextual (e.g., approval or approval process) business logic.

Initialization

Override default actions / permissions, or None to use class default

perm: signoffs.core.signoffs.opt_str = <Multiline-String>#
sign_method: Callable#

None

revoke_perm: signoffs.core.signoffs.opt_str = <Multiline-String>#
revoke_method: Callable#

None

classmethod mixin(*mixins)[source]#

Return a subclass of this class with the given mixin classes mixed in

is_permitted_signer(signoff_type, user)[source]#

Return True iff user has permission to sign a signoff of given type

can_sign(signoff, user)[source]#

Return True iff the signoff instance can be signed by given user

sign_if_permitted(signoff, user, commit=True, **kwargs)[source]#

Sign signoff for given user and save signet, if self.can_sign(user) raises PermissionDenied otherwise kwargs are passed directly to save - use commit=False to sign without saving.

sign(signoff, user, commit=True, **kwargs)[source]#

Sign signoff for given user and save signet, regardless of permissions or signoff state - careful!

kwargs are passed directly to save - use commit=False to sign without saving. Prefer to use sign_if_permitted to enforce business rules.

is_permitted_revoker(signoff_type, user)[source]#

return True iff user has permission to revoke signoffs of given type

can_revoke(signoff, user)[source]#

return True iff the signoff can be revoked by given user

revoke_if_permitted(signoff, user, reason='', **kwargs)[source]#

Revoke the signoff for user if they have permission, otherwise raise PermissionDenied

revoke(signoff, user, reason='', **kwargs)[source]#

Revoke the signoff regardless of permissions or signoff state - careful!

kwargs are passed directly to concrete revoke_method. Prefer to use revoke_if_permitted to enforce business rules.

class signoffs.core.signoffs.SignoffLogic(perm=None, sign_method=None, revoke_perm=None, revoke_method=None)[source]#

Bases: signoffs.core.signoffs.DefaultSignoffBusinessLogic

Public API: Alias for `DefaultSignoffBusinessLogic

Initialization

Override default actions / permissions, or None to use class default

signoffs.contrib.signets.signoffs#

Some basic Signoff Types backed by the Signet models defined in this package

Add "signoffs.contrib.signets" to settings.INSTALLED_APPS

Module Contents#

Classes#

SimpleSignoff

A basic Signoff Type that can be used out-of-the-box for simple use-cases where any user can sign off

RevokableSignoff

A SimpleSignoff that stores a “receipt” when a signoff is revoked

IrrevokableSignoff

A SimpleSignoff that can never be revoked

API#

class signoffs.contrib.signets.signoffs.SimpleSignoff(signet=None, subject=None, **kwargs)#

Bases: signoffs.core.signoffs.BaseSignoff

A basic Signoff Type that can be used out-of-the-box for simple use-cases where any user can sign off

Uses DefaultSignoffBusinessLogic - unrestricted: anyone can sign or revoke. Backed by signoffs.contrib.signets.models.Signet model.

Initialization

Construct a Signoff instance backed by the given signet or an instance of cls.signetModel(**kwargs)

subject is optional: the object this signoff is signing off on - set by SignoffField but otherwise unused.

signetModel#

None

revokeModel#

None

label#

‘I consent’

class signoffs.contrib.signets.signoffs.RevokableSignoff(signet=None, subject=None, **kwargs)#

Bases: signoffs.contrib.signets.signoffs.SimpleSignoff

A SimpleSignoff that stores a “receipt” when a signoff is revoked

Initialization

Construct a Signoff instance backed by the given signet or an instance of cls.signetModel(**kwargs)

subject is optional: the object this signoff is signing off on - set by SignoffField but otherwise unused.

revokeModel#

None

class signoffs.contrib.signets.signoffs.IrrevokableSignoff(signet=None, subject=None, **kwargs)#

Bases: signoffs.contrib.signets.signoffs.SimpleSignoff

A SimpleSignoff that can never be revoked

Initialization

Construct a Signoff instance backed by the given signet or an instance of cls.signetModel(**kwargs)

subject is optional: the object this signoff is signing off on - set by SignoffField but otherwise unused.

revoke_perm#

False

logic#

None