# Path: tutelary/models.py
# class Policy(models.Model):
#     """An individual policy has a name and a JSON policy body.  Changes to
#     policies are audited.
# 
#     """
# 
#     name = models.CharField(max_length=200)
#     """Policy name field."""
# 
#     body = models.TextField()
#     """Policy JSON body."""
# 
#     audit_log = AuditLog()
# 
#     def __str__(self):
#         return self.name
# 
#     def variable_names(self):
#         pat = re.compile(r'\$(?:([_a-z][_a-z0-9]*)|{([_a-z][_a-z0-9]*)})')
#         return set([m[0] for m in re.findall(pat, self.body)])
# 
#     def save(self, *args, **kwargs):
#         super().save(*args, **kwargs)
#         self.refresh()
# 
#     def refresh(self):
#         for pset in _policy_psets([self]):
#             pset.refresh()
# 
# def assign_user_policies(user, *policies_roles):
#     """Assign a sequence of policies to a user (or the anonymous user is
#     ``user`` is ``None``).  (Also installed as ``assign_policies``
#     method on ``User`` model.
# 
#     """
#     clear_user_policies(user)
#     pset = PermissionSet.objects.by_policies_and_roles(policies_roles)
#     pset.refresh()
#     if user is None:
#         pset.anonymous_user = True
#     else:
#         pset.users.add(user)
#     pset.save()
#     cache.set(user_cache_key(user), None)


import json
import itertools
from django.contrib.auth.models import User
from tutelary.models import Policy, assign_user_policies
from exampleapp.models import (
    Organisation, Project, Party, Parcel, UserPolicyAssignment
)
         'action': ['parcel.list', 'parcel.create'],
         'object': ['project/$organisation/*']},

        {'effect': 'allow',
         'action': ['project.delete'],
         'object': ['project/$organisation/*']},
        {'effect': 'allow',
         'action': ['project.list', 'project.create'],
         'object': ['organisation/$organisation']}
    ]
}
org_p = Policy(name='org-default', body=json.dumps(org_p_body))
org_p.save()

proj_p_body = {
    'clause': [
        {'effect': 'deny',
         'action': ['party.edit'],
         'object': ['party/$organisation/$project/*']},
        {'effect': 'deny',
         'action': ['parcel.edit'],
         'object': ['parcel/$organisation/$project/*']},
        {'effect': 'deny',
         'action': ['project.edit', 'project.delete'],
         'object': ['project/$organisation/*']},
        {'effect': 'deny',
         'action': ['project.create'],
         'object': ['organisation/$organisation']}
    ]
}

# Path: tutelary/models.py
# class Policy(models.Model):
#     """An individual policy has a name and a JSON policy body.  Changes to
#     policies are audited.
# 
#     """
# 
#     name = models.CharField(max_length=200)
#     """Policy name field."""
# 
#     body = models.TextField()
#     """Policy JSON body."""
# 
#     audit_log = AuditLog()
# 
#     def __str__(self):
#         return self.name
# 
#     def variable_names(self):
#         pat = re.compile(r'\$(?:([_a-z][_a-z0-9]*)|{([_a-z][_a-z0-9]*)})')
#         return set([m[0] for m in re.findall(pat, self.body)])
# 
#     def save(self, *args, **kwargs):
#         super().save(*args, **kwargs)
#         self.refresh()
# 
#     def refresh(self):
#         for pset in _policy_psets([self]):
#             pset.refresh()
# 
# def assign_user_policies(user, *policies_roles):
#     """Assign a sequence of policies to a user (or the anonymous user is
#     ``user`` is ``None``).  (Also installed as ``assign_policies``
#     method on ``User`` model.
# 
#     """
#     clear_user_policies(user)
#     pset = PermissionSet.objects.by_policies_and_roles(policies_roles)
#     pset.refresh()
#     if user is None:
#         pset.anonymous_user = True
#     else:
#         pset.users.add(user)
#     pset.save()
#     cache.set(user_cache_key(user), None)


# Path: example/db-setup.py
import json
import itertools
from django.contrib.auth.models import User
from tutelary.models import Policy, assign_user_policies
from exampleapp.models import (
    Organisation, Project, Party, Parcel, UserPolicyAssignment
)

         'action': ['parcel.list', 'parcel.create'],
         'object': ['project/$organisation/*']},

        {'effect': 'allow',
         'action': ['project.delete'],
         'object': ['project/$organisation/*']},
        {'effect': 'allow',
         'action': ['project.list', 'project.create'],
         'object': ['organisation/$organisation']}
    ]
}
org_p = Policy(name='org-default', body=json.dumps(org_p_body))
org_p.save()

proj_p_body = {
    'clause': [
        {'effect': 'deny',
         'action': ['party.edit'],
         'object': ['party/$organisation/$project/*']},
        {'effect': 'deny',
         'action': ['parcel.edit'],
         'object': ['parcel/$organisation/$project/*']},
        {'effect': 'deny',
         'action': ['project.edit', 'project.delete'],
         'object': ['project/$organisation/*']},
        {'effect': 'deny',
         'action': ['project.create'],
         'object': ['organisation/$organisation']}
    ]
}

proj_p = Policy(name='project-default', body=json.dumps(proj_p_body))