models.py 2.34 KB
Newer Older
Lincoln Smith's avatar
Lincoln Smith committed
1
from django.db import models
2
from django.contrib.auth.models import Permission
Lincoln Smith's avatar
Lincoln Smith committed
3
from django.contrib.contenttypes.models import ContentType
4
from django.core.exceptions import ValidationError, ObjectDoesNotExist
Lincoln Smith's avatar
Lincoln Smith committed
5

6

7
8
9
class PFPContentType(models.Model):
    """ContentTypes to creat PerFieldPermissions for."""
    content_type = models.OneToOneField(ContentType, unique=True)
Lincoln Smith's avatar
Lincoln Smith committed
10
11

    def __str__(self):
12
        return str(self.content_type)
Lincoln Smith's avatar
Lincoln Smith committed
13
14


15
class PFPRoleType(models.Model):
Lincoln Smith's avatar
Lincoln Smith committed
16
17
    """Role types (e.g. User, Group) to allow users to filter available roles
    with."""
18
19
20
21
22
23
24
25
26
    role_ctype = models.OneToOneField(ContentType, unique=True)

    def __str__(self):
        return str(self.role_ctype)


class PFPFilterType(models.Model):
    """ContentTypes to make available when managing permissions."""
    filter_ctype = models.OneToOneField(ContentType, unique=True)
Lincoln Smith's avatar
Lincoln Smith committed
27
28

    def __str__(self):
29
        return str(self.role_ctype)
Lincoln Smith's avatar
Lincoln Smith committed
30

31
32
33
34
35
36
37
38
39
40

class PerFieldPermission(Permission):
    """Extends Permission to enable field level permissions."""
    field_name = models.CharField(max_length=100, blank=False, null=False)
    model_permission = models.ForeignKey(
            Permission,
            null=False,
            blank=False,
            on_delete=models.CASCADE,
            related_name='field_permissions',
Lincoln Smith's avatar
Lincoln Smith committed
41
42
43
            )

    class Meta:
44
        permissions = (('manage_permissions', 'Can manage permissions'),)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

    def clean(self):
        """Ensure a PFP has the same ContentType as its parent Permission."""
        if self.content_type_id != self.model_permission.content_type_id:
            raise ValidationError("""PerFieldPermission model_permission must
            be of the same ContentType as self.""")
        super().clean()

    def validate_unique(self, exclude=None):
        """
        Ensure only one PFP exists for a given Permission/field combination.
        """
        super().validate_unique(exclude)
        try:
            perm = PerFieldPermission.objects.get(
                    codename=self.codename,
                    model_permission=self.model_permission,
                    )
        except ObjectDoesNotExist:
            return

66
        if ((hasattr(self, 'id') and self.id != perm.id)
67
68
69
                or not hasattr(self, 'id')):
            raise ValidationError("""Only one PerFieldPermission allowed for
            each model permission/field combination.""")