Autodocumentation of the Actions module

Models

Django models for Actions and Permissioned Models.

class concord.actions.models.Action(*args, **kwargs)

Represents an action between an actor and a target.

All changes of state that go through the permissions system must do so via an Action instance.

Action instances must include information about the actor taking the action and the target of the action, among other information.

exception DoesNotExist
exception MultipleObjectsReturned
get_description()

Gets description of the action by reference to change_types set via change field, including the target.

get_targetless_description()

Gets description of the action by reference to change_types set via change field, without the target.

implement_action()

Perform an action defined by the Change object. Carries out its custom implementation using the actor and target.

save(*args, **kwargs)

If action is live (is_draft is False) check that target and actor are set.

property status

Gets status of Action from Resolution field.

take_action()

Runs the action through the permissions pipeline. If waiting on a condition, triggers that condition. If approved, implements action.

Returns itself and, optionally, the result of implementing the action.

class concord.actions.models.PermissionedModel(*args, **kwargs)

An abstract base class that represents permissions.

PermissionedModel is an abstract base class from which all models using the permissions system should inherit.

The PermissionedModel contains information about owners and their related permissions.

get_actions()

Provides a helper method for getting actions.

Returns all actions targeting the instance of the subclass which has inherited from PermissionedModel.

get_content_type()

Gets content type of the model.

The content type is helpful since PermissionedModels may be subclassed into a variety of other models.

get_name()

Gets name of Model. By default, gets string representation.

get_nested_objects()

Gets objects that the model is nested within.

Nested objects are often things like the owner of instance or, for example, a forum that a post is posted within.

Called by the permissions pipeline in permissions.py.

get_owner()

Gets owner of the permissioned model.

All permissioned models have an owner.

get_serialized_field_data()

Returns data that has been been serialized.

By default, the readable attributes of a permissioned model are all fields specified on the model. However, we cannot simply use self._meta.get_fields() since the field name is sometimes different than the attribute name, for instance with related fields that are called X but show up as X_set on the model.

classmethod get_settable_state_changes()

Returns a list of state_changes that can be set via permissions targeting this model.

This may include some permissions where the targets are other than this model. For instance, if this object owns another object, we may have set permissions for actions targeting the owned object.

get_unique_id()

Gets a unique ID for the model, consisting of the content type and pk.

save(*args, override_check=False, **kwargs)

Save permissions.

There are two things happening here:

1: Subtypes of BaseCommunity are the only children of PermissionedModel that

should be allowed to have a null owner. We check that here and raise an error if a non-community model has null values for owner fields.

2: A permissioned model’s save method can only be invoked by a descendant of

BaseStateChange, on update (create is fine). For now, we inspect who is calling us, but there may be a better long-term solution.

class concord.actions.models.TemplateModel(*args, **kwargs)

The template model allows users to apply sets of actions to their communities.

exception DoesNotExist
exception MultipleObjectsReturned
get_scopes()

Gets list of scopes the template model applies to.

get_supplied_fields()

Get supplied fields as dictionary.

get_supplied_form_fields()

Loads template supplied fields and gets their forms, using field_helper. Supplied fields typically have format like:

“field_x”: [“RoleListField”, None] “field_y”: [“IntegerField”, { “maximum”: 2 }]

get_template_breakdown(trigger_action=None, supplied_field_data=None)

Gets a breakdown of actions contained in the template, including data from trigger action and supplied field data if passed in.

property has_foundational_actions

Returns True if any of the actions in the action_list are foundational changes.

set_scopes(scopes)

Saves a list of scopes to the template model.

State Changes

Defines state changes for concord.actions.models, as well as the BaseStateChange object from which all state change objects inherit.

class concord.actions.state_changes.ApplyTemplateStateChange(template_model_pk, supplied_fields=None, is_foundational=False, original_creator_only=False)

State change object for applying a template.

classmethod check_configuration_is_valid(configuration)

Used primarily when setting permissions, this method checks that the supplied configuration is a valid one. By contrast, check_configuration checks a specific action against an already-validated configuration.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

classmethod get_configurable_fields()

Gets the fields of a change object which may be configured when used in a Permission model.

classmethod get_configured_field_text(configuration)

Gets additional text for permissions item instance descriptions from configured fields.

implement(actor, target, action=None)

Implements the given template, relies on logic in apply_template.

validate(actor, target)

Method to check whether the data provided to a change object in an action is valid for the change object. Optional exclude_fields tells us not to validate the given field.

class concord.actions.state_changes.BaseStateChange

The BaseStateChange object is the object which all other state change objects inherit from. It has a variety of methods which must be implemented by those that inherit it.

all_context_instances(action)

Given the specific action that contains this change object, returns a dictionary with relevant model_instances. Used primarily by templates.

We always return the action, the owning group by its model name, and the action target by its model name, with the state change able to specify additional objects.

classmethod can_set_on_model(model_name)

Tests whether a given model, passed in as a string, is in allowable target.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

classmethod get_all_possible_targets()

Helper method, gets all permissioned models in system that are not abstract.

classmethod get_allowable_targets()

Returns the classes that an action of this type may target.

get_change_data()

Given the python Change object, generates a json list of field names and values. Does not include instantiated fields.

classmethod get_change_field_options()

Gets a list of required parameters passed in to init, used by templates. Does not include optional parameters, as this may break the template referencing them if they’re not there.

classmethod get_change_type()

Gets the full type of the change object in format ‘concord.package.state_changes.SpecificStateChange’

classmethod get_community_models()

Helper method which lets us use alternative community models as targets for community actions.

classmethod get_configurable_fields()

Gets the fields of a change object which may be configured when used in a Permission model.

classmethod get_configurable_form_fields()

Gets the configurable fields of a change object as form fields.

classmethod get_configured_field_text(configuration)

Gets additional text for permissions item instance descriptions from configured fields.

get_context_instances(action)

Method to be optionally overridden by State Changes, adding context instances.

classmethod get_context_keys()

Gets action as key by default, plus any context keys specified. If no context keys are specified and allowable_targets incldues only one model, grabs that model name as a valid context key.

classmethod get_preposition()

By default, we make changes “to” things but change types can override this default preposition with “for”, “with”, etc.

classmethod get_settable_classes()

Returns the classes that a permission with this change type may be set on. This overlaps with allowable targets, but also includes classes that allowable targets may be nested on. Most likely called by the validate method in AddPermissionStateChange.

implement(actor, target)

Method that carries out the change of state.

is_conditionally_foundational(action)

Some state changes are only foundational in certain conditions. Those state changes override this method to apply logic and determine whether a specific instance is foundational or not.

set_validation_error(message)

Helper method so all state changes don’t have to import ValidationError

validate(actor, target)

Method to check whether the data provided to a change object in an action is valid for the change object. Optional exclude_fields tells us not to validate the given field.

class concord.actions.state_changes.ChangeOwnerStateChange(new_owner_content_type, new_owner_id)

State change for changing which community owns the object. Not to be confused with state changes which change who the owners are within a community.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

get_new_owner()

Helper method to get model instance of new owner from params.

implement(actor, target)

Method that carries out the change of state.

validate(actor, target)

Method to check whether the data provided to a change object in an action is valid for the change object. Optional exclude_fields tells us not to validate the given field.

class concord.actions.state_changes.DisableFoundationalPermissionStateChange

State change object for disabling the foundational permission of a permissioned model.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

implement(actor, target)

Method that carries out the change of state.

class concord.actions.state_changes.DisableGoverningPermissionStateChange

State change object for disabling the governing permission of a permissioned model.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

implement(actor, target)

Method that carries out the change of state.

class concord.actions.state_changes.EnableFoundationalPermissionStateChange

State change object for enabling the foundational permission of a permissioned model.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

implement(actor, target)

Method that carries out the change of state.

class concord.actions.state_changes.EnableGoverningPermissionStateChange

State change object for enabling the governing permission of a permissioned model.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

implement(actor, target)

Method that carries out the change of state.

class concord.actions.state_changes.InputField(name, type, required, validate)
property name

Alias for field number 0

property required

Alias for field number 2

property type

Alias for field number 1

property validate

Alias for field number 3

class concord.actions.state_changes.ViewStateChange(fields_to_include=None)

ViewStateChange is a state change which doesn’t actually change state. Instead, it returns the specified fields. It exists so we can wrap view permissions in the same model as all the other permissions.

check_configuration(action, permission)

All configurations must pass for the configuration check to pass.

classmethod check_configuration_is_valid(configuration)

Used primarily when setting permissions, this method checks that the supplied configuration is a valid one. By contrast, check_configuration checks a specific action against an already-validated configuration.

description_past_tense()

Returns the description of the state change object, in past tense.

description_present_tense()

Returns the description of the state change object, in present tense.

classmethod get_configurable_fields()

Gets the fields of a change object which may be configured when used in a Permission model.

implement(actor, target)

Gets data from specified fields, or from all fields, and returns as dictionary.

validate(actor, target)

Checks if any specified fields are not on the target and, if there are any, returns False.

Client

Client for making changes to models in Action.models, along with the BaseClient which other packages inherit from.

class concord.actions.client.ActionClient(actor=None, target=None)

The ActionClient provides access to Action and ActionContainer models.

Args:
actor: User Model

The User who the client is acting on behalf of. Optional, but required for many Client methods.

target: PermissionedModel Model

The target that the change will be implemented on. Optional, but required for many Client methods.

get_action_given_pk(pk)

Takes a pk (int) and returns the Action associated with it.

get_action_history_given_actor(actor=None) → django.db.models.query.QuerySet

Gets the action history of an actor. Accepts an User model passed in or, if no actor is passed in, uses the actor currently set on the client.

get_action_history_given_target(target=None) → django.db.models.query.QuerySet

Gets the action history of a target. Accepts a target model passed in or, if no target is passed in, uses the target currently set on the client.

get_foundational_actions_given_target(target=None) → django.db.models.query.QuerySet

Gets the action history of a target, filtered to include only foundational changes.

get_governing_actions_given_target(target=None) → django.db.models.query.QuerySet

Gets the action history of a target, filtered to only include actions resolved via the governing permission.

get_owning_actions_given_target(target=None) → django.db.models.query.QuerySet

Gets the action history of a target, filtered to only include actions resolved through foundational permission. Similar to filtering foundational_actions, but includes non-foundational actions taken on targets with the foundational permission enabled.

retake_action(action=None, pk=None)

Helper method to take an action (or, usually, retry taking an action) from the client.

class concord.actions.client.BaseClient(actor=None, target=None)

Contains behavior needed for all clients.

Args:
actor: User Model

The User who the client is acting on behalf of. Optional, but required for many Client methods.

target: PermissionedModel Model

The target that the change will be implemented on. Optional, but required for many Client methods.

change_is_valid(change)

Returns True if the change passed in is valid, given the Client’s actor and target, and False if it is not.

change_owner_of_target(new_owner) → Tuple[int, Any]

Changes the owner of the Client’s target.

Args:
new_owner: descendant of base Community Model

The new owner the target will be transferred to.

create_action(change)

Create an Action object using the change object passed in as well as the actor and target already set on the Client. Called by clients when making changes to state.

If the mode set on the client is “Mock”, creates a mock action intead and returns it. Mocks are mostly used by Templates.

create_and_take_action(change, proposed=False)

Creates an action and takes it.

disable_foundational_permission() → Tuple[int, Any]

Disables the foundational permission on a target. Foundational permission is typically disabled.

disable_governing_permission() → Tuple[int, Any]

Disables the governing permission on a target. This prevents governors from taking actions on the target unless they’re granted specific permissions. Governing permission is typically enabled.

enable_foundational_permission() → Tuple[int, Any]

Enables the foundational permission on a target. This overrides all specific permissions and governing permissions and requires changes to the target to be made by owners. Foundational permission is typically disabled.

enable_governing_permission() → Tuple[int, Any]

Enables the governing permission on a target. This allows anyone who is a governor to take any non-foundational action on the target. Governing permission is typically enabled.

get_object_given_model_and_pk(model, pk)

Given a model string and a pk, returns the instance. Only works on Permissioned models.

get_target()

Gets the target of the client.

get_target_data(fields_to_include=None)

Gets information about the target after passing request through permissions pipeline. Supply fields_to_include, a list of field names as strings, to limit the data requested, otherwise returns all fields.

optionally_overwrite_target(target)

Helper method that takes in a target, which may be None, and overwrites the existing target only if not None.

refresh_target()

Re-populates model from database.

set_actor(actor)

Sets actor.

set_target(target=None, target_pk=None, target_ct=None)

Sets target of the client. Accepts either a target model or the target’s pk and ct and fetches, in which case it fetches the model from the Database. Target must be a permissioned model.

take_action(action, proposed=False)

If the action is a mock, invalid, or proposed, return without taking it, otherwise take the action.

validate_actor()

Helper method to check whether or not we’ve got an actor and whether they’re a user.

validate_target()

Helper method to check whether or not we’ve got a target and that it’s a permissioned model.

class concord.actions.client.TemplateClient(actor=None, target=None)

The TemplateClient provides access to the TemplateModel model.

Args:
actor: User Model

The User who the client is acting on behalf of. Optional, but required for many Client methods.

target: PermissionedModel Model

The target that the change will be implemented on. Optional, but required for many Client methods.

apply_template(template_model_pk, supplied_fields=None)

Applies a template to the target. If any of the actions in the template is a foundational change, changes the state change object’s attr to foundational so it goes through the foundational pipeline.

get_template(pk)

Gets template with supplied pk or returns None.

get_templates()

Gets all templates in database.

get_templates_for_scope(scope)

Gets template in the given scope.

Permissions Pipeline

This module implements the logic of the permission system.

The has_permission function is called by external callers, while the rest of the functions are used by has_permission.

concord.actions.permissions.check_conditional(action, community_or_permission, leadership_type=None)

Checks to see if a condition item has been created for the action.

Args:
action: Action Model

The Action which is being passed through the permissions pipeline.

community_or_permission: Model

Either community model or permission model.

leadership_type: str

Either “owner” or “governor”. Required if community_or_permission is community. ignored if community_or_permission is permission.

Returns a dict containing condition information if condition_item exists or, if condition item does not exist, the same dict structure populated by Nones.

concord.actions.permissions.check_specific_permission(permission, action)

Helper method called by specific permissions pipeline. Given a permission, checks to see if its active, if it has the right configuration, that the actor satisfies the permission, and whether the action has a condition that passes, in that order.

Returns:

True or False indicating whether permission passes Str or the role that the actor matched to, if it exists, or None Dict of the condition data from the condition set on the permission, or None

concord.actions.permissions.foundational_permission_pipeline(action)

Handles logic for foundational actions.

When an action is passed through the foundational pipeline, it is not passed through the governing or specific permission pipeline. So, if we don’t have the authority, we reject the action.

concord.actions.permissions.governing_permission_pipeline(action)

Checks whether the actor behind the action has governing permissions and if so, passes.

concord.actions.permissions.has_permission(action)

has_permission directs the flow of logic in the permissions pipeline. It returns information about whether the action has permsision to take the action and if there are any conditions that need to be triggered. It does not change the database and it does not alter the action object other than updating its resolution field and, optionally, adding a conditions_list attribute with source_ids for uncreated conditions.

If the foundational permission is enabled or the change type is a foundational change (like change_owner), we go into the foundational permission pipeline and no other pipeline.

If the governing permission is enabled, we try that pipeline. If the action is approved by the governing pipeline and we finish with the permission pipeline, otherwise we move on to the last option, the specific permission pipeline.

concord.actions.permissions.specific_permission_pipeline(action)

Checks the target for specific permissions matching the change type and configuration of the action.

If matching permissions are found, we check to see if the actor satisfies the permission. If the actor does satisfy, we look for conditions. If any permissions have no condition, the action is approved. If there are conditions, they are saved to the conditions list.

If after this the action is not approved, we check to see whether the target is nested on another object which may have permissions set on it. For instance, the target may be a post in a forum, where the forum has an ‘edit post’ permission that applies across all posts. We go through the same process for each of the nested permissions.

At the end of all this, if any of these permissions pass, the action is approved. If any are waiting, the action is set to waiting. If none are approved or waiting, the action is rejected.

Utilities

Utility methods/classes for actions package. Contains some Concord-wide utility methods/classes as well.

class concord.actions.utils.Attributes

Hack to allow nested attributes on Changes.

class concord.actions.utils.Changes

Helper object which lets developers easily access change types.

class concord.actions.utils.Client(actor=None, target=None, limit_to=None)

Helper object which lets developers easily access all clients at once.

If supplied with actor and/or target, will instantiate clients with that actor and target.

limit_to is a list of client names, if supplied actors and targets will only be supplied to the specified clients.

property Community

Projects that use Concord may create a new model and client, descending from the Community model and CommunityClient. To handle this scenario, we look for Clients with an attribute community_model and, if something other than the CommunityClient exists, we use that. Users can override this behavior by explicitly setting community_client_override to whatever client they want to use.

get_clients()

Gets a list of client objects set as attributes on Client().

update_actor_on_all(actor)

Update actor for all clients.

update_target_on_all(target)

Update target for all clients.

class concord.actions.utils.MockAction(change, actor, target, resolution=None, unique_id=None)

Mock Actions are used in place of the Action django model in templates. They are easier to serialize, lack db-dependent fields like created_at, and crucially allow us to replace certain fields or subfields with references to either the trigger action, or action results from previous actions in an action container.

create_action_object(container_pk, save=True)

Creates an action object given the data set on MockAction plus the container_pk passed in.

property status

Gets status of Action from Resolution field.

concord.actions.utils.check_permissions_for_action_group(list_of_actions)

Takes in a list of MockActions, generated by clients in mock mode, and runs them through permissions pipeline.

concord.actions.utils.get_all_apps(return_as='app_configs')

Get all apps that are part of Concord and the app that is using it. Returns as list of app_configs by default, but can also be returned as app name string by passing ‘strings’ to return_as.

concord.actions.utils.get_all_clients()

Gets all clients descended from Base Client in Concord and the app using it.

concord.actions.utils.get_all_community_models()

Gets all non-abstract permissioned models with attr is_community equal to True.

concord.actions.utils.get_all_conditions()

Gets all possible condition models in Concord and the app using it.

concord.actions.utils.get_all_dependent_fields()

Goes through all PermissionedModels, plus Action, and gets a list of fields. TODO: also get their type, for use on front-end validation?

concord.actions.utils.get_all_foundational_state_changes()

Gets all state changes in Concord and app using it that are foundational.

concord.actions.utils.get_all_permissioned_models()

Gets all non-abstract permissioned models in the system.

concord.actions.utils.get_all_state_changes()

Gets all possible state changes in Concord and the app using it.

concord.actions.utils.get_all_templates()

Get all classes with TemplateLibraryObject as parent defined in template_library files, either in Concord or app using Concord.

concord.actions.utils.get_state_change_object(state_change_name)

Given a full name string, gets the state change object.

concord.actions.utils.get_state_changes_for_app(app_name)

Given an app name, gets state_changes as list of state change objects.

concord.actions.utils.get_state_changes_settable_on_model(model_class)

Gets all state changes a given model can be set on. If state_changes is not passed in, checks against all possible state_changes.

concord.actions.utils.process_field_type(field)

Helper method to inspect field and return appropriate type.

concord.actions.utils.replace_fields(*, action_to_change, mock_action, context)

Takes in the action to change and the mock_action, and looks for field on the mock_action which indicate that fields on the action to change need to be replaced. For the change field, and the change field only, also look for fields to replace within.

concord.actions.utils.replacer(key, value, context)

Given the value provided by mock_action, looks for fields that need replacing by finding strings with the right format, those that begin and end with {{ }}. Uses information in context object to replace those fields. In the special case of finding something referencing nested_trigger_action (always(?) in the context of a condition being set) it replaces nested_trigger_action with trigger_action.