Skip to content

Organization Permission Checking


Bases: AccessMixin, OrganizationMixin

Permission Checking

The base django permissions have not been modified with this app providing Multi-Tenancy. This is done by a mixin, that checks if the item is apart of an organization, if it is; confirmation is made that the user is part of the same organization and as long as they have the correct permission within the organization, access is granted.

How it works

The overall permissions system of django has not been modified with it remaining fully functional. The multi-tenancy has been setup based off of an organization with teams. A team to the underlying django system is an extension of the django auth group and for every team created a django auth group is created. THe group name is set using the following format: <organization>_<team name> and contains underscores _ instead of spaces.

A User who is added to an team as a "Manager" can modify the team members or if they have permission access.change_team which also allows the changing of team permissions. Modification of an organization can be done by the django administrator (super user) or any user with permission access._change_organization.

Items can be set as Global, meaning that all users who have the correct permission regardless of organization will be able to take action against the object.

Permissions that can be modified for a team have been limited to application permissions only unless adjust the permissions from the django admin site.

Multi-Tenancy workflow

The workflow is conducted as part of the view and has the following flow:

  1. Checks if user is member of organization the object the action is being performed on. Will also return true if the object has field is_global set to true.

  2. Fetches all teams the user is part of.

  3. obtains all permissions that are linked to the team.

  4. checks if user has the required permission for the action.

  5. confirms that the team the permission came from is part of the same organization as the object the action is being conducted on.

  6. ONLY on success of the above items, grants access.

Attributes

parent_model: str = None

Parent Model

This attribute defines the parent model for the model in question. The parent model when defined will be used as the object to obtain the permissions from.

parent_model_pk_kwarg: str = 'pk'

Parent Model kwarg

This value is used to define the kwarg that is used as the parent objects primary key (pk).

request = None

user_groups = []

permission_required: list = []

Permission required for the view

Not specifying this property adjusts the permission check logic so that you can use the permission_check() function directly.

An example of a get request....

def get(self, request, *args, **kwargs):

    if not request.user.is_authenticated:

            return self.handle_no_permission()

    if not self.permission_check(request, [ 'access.view_organization' ]):

        raise PermissionDenied('You are not part of this organization')

    return super().get(request, *args, **kwargs)
this example details manual usage of the permission_check() function for a get request.

Functions

get_parent_obj()

Get the Parent Model Object

Use in views where the the model has no organization and the organization should be fetched from the parent model.

Requires attribute parent_model within the view with the value of the parent's model class

Returns:

Name Type Description
parent_model Model

with PK from kwargs['pk']

object_organization()

is_member(organization)

Returns true if the current user is a member of the organization

iterates over the user_organizations list and returns true if the user is a member

Returns:

Name Type Description
bool bool

description

get_permission_required()

Override of 'PermissionRequiredMixin' method so that this mixin can obtain the required permission.

is_manager()

Returns true if the current user is a member of the organization

user_organizations()

Current Users organizations

Fetches the Organizations the user is apart of.

Get All groups the user is part of, fetch the associated team, iterate over the results adding the organization ID to a list to be returned.

Returns:

Name Type Description
_type_ list()

User Organizations.

has_organization_permission(organization=None, permissions_required=None)

Check if user has permission within organization.

Parameters:

Name Type Description Default
organization int

Organization to check. Defaults to None.

None
permissions_required list

if doing object level permissions, pass in required permission. Defaults to None.

None

Returns:

Name Type Description
bool bool

True for yes.

permission_check(request, permissions_required=None)

dispatch(request, *args, **kwargs)

About:

This page forms part of our Project Centurion ERP.

Page Metadata
Version: ToDo: place files short git commit here
Date Created: 2024-06-17
Date Edited: 2024-07-13

Contribution:

Would You like to contribute to our Centurion ERP project? You can assist in the following ways:

 

ToDo: Add the page list of contributors