A quick example¶
Models¶
Suppose that we have a Django model called Organization we want to
manage with django-tutelary. We mark up the basic model definition
using a decorator (permissioned_model) and a metadata class
(TutelaryMeta):
from django.db import models
from tutelary.decorators import permissioned_model
@permissioned_model
class Organization(models.Model):
name = models.CharField(max_length=100)
class TutelaryMeta:
perm_type = 'organization'
path_fields = ('name',)
actions = [('org.list', {'permissions_object': None}),
('org.create', {'permissions_object': None}),
'org.delete']
Here, the TutelaryMeta class carries metadata describing the
actions that can be performed on an Organization object, and how
to represent instances of Organization as django-tutelary objects.
Here, an Organization with name = "Cadasta" would be
represented by the django-tutelary object organization/Cadasta,
based on the perm_type and path_fields values.
Views¶
The link between the view used to perform particular operations on Django objects and the django-tutelary permissions required to perform those operations is made in the following way:
from django.core.urlresolvers import reverse_lazy
import django.views.generic.edit as edit
from tutelary.mixins import PermissionRequiredMixin
from .models import Organization
class OrganizationDelete(PermissionRequiredMixin,
edit.DeleteView):
model = Organization
success_url = reverse_lazy('organization-list')
permission_required = 'org.delete'
Here, we use a normal Django class-based view and mix in
django-tutelary’s PermissionRequiredMixin. This mixin uses the
permission_required attribute on the OrganizationDelete view
to determine which django-tutelary action this view corresponds to.
If a user attempts to delete an organization, the user’s associated
permission set (generated from the policies assigned to the user) is
used to determine whether the org.delete action is allowed on the
organization in question. If the action is allowed, view processing
proceeds as normal. If the action is denied, a PermissionDenied
exception is raised.
Policies¶
Policies can be read from JSON files or stored in a database. Here’s a simple example of reading a couple of policy documents from files, creating a role from them and assigning the role to a user:
from django.contrib.auth.models import User
from tutelary.models import Policy
default_p = Policy(name='default',
body=open('default-policy.json').read())
default_p.save()
sysadmin_p = Policy(name='sys-admin-policy',
body=open('sys-admin-policy.json').read())
sysadmin_p.save()
sysadmin_role = Roles.objects.create(
name='sys-admin', policies=[default_p, sysadmin_p]
)
sysadmin = User.objects.get(username='admin')
sysadmin.assign_policies(sysadmin_role)
After the call to User.assign_policies, any subsequent permissions
queries against the admin user will be answered according to the
contents of the policies in the default-policy.json and
sys-admin-policy.json files.