forked from maraujop/django-rules
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmodels.py
More file actions
54 lines (45 loc) · 2.38 KB
/
models.py
File metadata and controls
54 lines (45 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# -*- coding: utf-8 -*-
import inspect
from django.core.exceptions import ValidationError
from django.db import models
from django.contrib.contenttypes.models import ContentType
from exceptions import NonexistentFieldName
from exceptions import RulesError
class RulePermission(models.Model):
class Meta:
app_label = 'django_rules'
"""
This model holds the rules for the authorization system
"""
codename = models.CharField(primary_key=True, max_length=30)
field_name = models.CharField(max_length=30)
content_type = models.ForeignKey(ContentType)
view_param_pk = models.CharField(max_length=30)
description = models.CharField(max_length=140, null=True)
def save(self, *args, **kwargs):
"""
Validates that the field_name exists in the content_type model
raises ValidationError if it doesn't. We need to restrict security rules creation
"""
# If not set use codename as field_name as default
if self.field_name == '':
self.field_name = self.codename
# If not set use primary key attribute name as default
if self.view_param_pk == '':
self.view_param_pk = self.content_type.model_class()._meta.pk.get_attname()
# First search for a method or property defined in the model class
# Then we look in the meta field_names
# If field_name does not exist a ValidationError is raised
if not hasattr(self.content_type.model_class(), self.field_name):
# Search within attributes field names
if not (self.field_name in self.content_type.model_class()._meta.get_fields()):
raise NonexistentFieldName("Could not create rule: field_name %s of rule %s does not exist in model %s" %
(self.field_name, self.codename, self.content_type.model))
else:
# Check if the method parameters are less than 2 including self in the count
bound_field = getattr(self.content_type.model_class(), self.field_name)
if callable(bound_field):
if len(inspect.getargspec(bound_field)[0]) > 2:
raise RulesError("method %s from rule %s in model %s has too many parameters." %
(self.field_name, self.codename, self.content_type.model))
super(RulePermission, self).save(*args, **kwargs)