permissions.py 4.45 KB
Newer Older
1
from django.core.exceptions import PermissionDenied
2
from django.db.models.base import ModelBase
3
from rest_framework.permissions import BasePermission
4

5

6
class LDPPermissions(BasePermission):
7 8 9 10
    """
        Default permissions
        Anon: None
        Auth: None but herit from Anon
11
        Ownr: None but herit from Auth
12
    """
13
    anonymous_perms = ['view']
14 15
    authenticated_perms = ['inherit']
    owner_perms = ['inherit']
16

17
    def user_permissions(self, user, obj_or_model, obj=None):
Thibaud's avatar
Thibaud committed
18
        """
19
            Filter user permissions for a model class
Thibaud's avatar
Thibaud committed
20
        """
21 22 23 24 25 26 27 28

        # sorted out param mess
        if isinstance(obj_or_model, ModelBase):
            model = obj_or_model
        else:
            obj = obj_or_model
            model = obj_or_model.__class__

29
        # Get Anonymous permissions from Model's Meta. If not found use default
30
        anonymous_perms = getattr(model._meta, 'anonymous_perms', self.anonymous_perms)
31

32
        # Get Auth permissions from Model's Meta. If not found use default
33
        authenticated_perms = getattr(model._meta, 'authenticated_perms', self.authenticated_perms)
34 35 36
        # Extend Auth if inherit is given
        if 'inherit' in authenticated_perms:
            authenticated_perms = authenticated_perms + list(set(anonymous_perms) - set(authenticated_perms))
Jean-Baptiste's avatar
Jean-Baptiste committed
37

38
        # Get Owner permissions from Model's Meta. If not found use default
39
        owner_perms = getattr(model._meta, 'owner_perms', self.owner_perms)
40 41 42
        # Extend Owner if inherit is given
        if 'inherit' in owner_perms:
            owner_perms = owner_perms + list(set(authenticated_perms) - set(owner_perms))
Thibaud's avatar
Thibaud committed
43

Alexandre's avatar
Alexandre committed
44
        if user.is_anonymous():
45 46
            return anonymous_perms

47
        else:
48 49 50
            if obj and hasattr(model._meta, 'owner_field') and (
                    getattr(obj, getattr(model._meta, 'owner_field')) == user or getattr(obj, getattr(model._meta,
                                                                                                      'owner_field')) == user.id):
51 52
                return owner_perms

53
            else:
54
                return authenticated_perms
55

56
    def filter_user_perms(self, user, obj_or_model, permissions):
57
        # Only used on Model.get_permissions to translate permissions to LDP
58
        return [perm for perm in permissions if perm in self.user_permissions(user, obj_or_model)]
Thibaud's avatar
Thibaud committed
59

60 61
    perms_map = {
        'GET': ['%(app_label)s.view_%(model_name)s'],
62
        'OPTIONS': [],
63
        'HEAD': ['%(app_label)s.view_%(model_name)s'],
64 65 66 67 68
        'POST': ['%(app_label)s.add_%(model_name)s'],
        'PUT': ['%(app_label)s.change_%(model_name)s'],
        'PATCH': ['%(app_label)s.change_%(model_name)s'],
        'DELETE': ['%(app_label)s.delete_%(model_name)s'],
    }
Thibaud's avatar
Thibaud committed
69

70 71 72 73 74 75 76 77
    def get_permissions(self, method, obj):
        """
            Translate perms_map to request
        """
        kwargs = {
            'app_label': obj._meta.app_label,
            'model_name': obj._meta.model_name
        }
78

79 80 81
        # Only allows methods that are on perms_map
        if method not in self.perms_map:
            raise PermissionDenied
82

83
        return [perm % kwargs for perm in self.perms_map[method]]
84

85 86 87 88
    def has_permission(self, request, view):
        """
            Access to containers
        """
89 90 91 92 93 94
        from djangoldp.models import Model

        if self.is_a_container(request._request.path):
            try:
                obj = Model.resolve_parent(request.path)
                model = view.parent_model
95
            except:
96 97 98 99 100
                obj = None
                model = view.model
        else:
            obj = Model.resolve_id(request._request.path)
            model = view.model
101

102
        perms = self.get_permissions(request.method, model)
103

104
        for perm in perms:
105
            if not perm.split('.')[1].split('_')[0] in self.user_permissions(request.user, model, obj):
106
                return False
107 108

        return True
109

110 111 112 113 114
    def is_a_container(self, path):
        from djangoldp.models import Model
        container, id = Model.resolve(path)
        return id is None

115
    def has_object_permission(self, request, view, obj):
116 117 118 119 120 121
        """
            Access to objects
            User have permission on request: Continue
            User does not have permission:   403
        """
        perms = self.get_permissions(request.method, obj)
122
        model = obj
123

124
        for perm in perms:
125
            if not perm.split('.')[1].split('_')[0] in self.user_permissions(request.user, model, obj):
126
                return False
127

128
        return True