1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +00:00

per-object-permissions: Made some code-formatting changes

git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@4100 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-11-25 05:18:33 +00:00
parent 1b54fc3aba
commit 6fab0ffcad
7 changed files with 141 additions and 205 deletions

View File

@ -1,6 +1,5 @@
var row_level_permission = { var row_level_permission = {
copyToNew: function (id) copyToNew: function (id) {
{
var newForm = document.getElementById("addRLPForm"); var newForm = document.getElementById("addRLPForm");
var form = document.getElementById("editRLPForm-"+id); var form = document.getElementById("editRLPForm-"+id);
newForm.owner.selectedIndex = form.owner.selectedIndex; newForm.owner.selectedIndex = form.owner.selectedIndex;
@ -8,8 +7,7 @@ var row_level_permission = {
newForm.negative.checked = form.negative.checked; newForm.negative.checked = form.negative.checked;
}, },
apply_selected: function () apply_selected: function () {
{
var eleList = document.getElementsByName("apply_checkbox"); var eleList = document.getElementsByName("apply_checkbox");
var formList = []; var formList = [];
for (var i=0; eleList.length; i++) for (var i=0; eleList.length; i++)
@ -23,7 +21,6 @@ var row_level_permission = {
} }
return false; return false;
}, },
init: function() { init: function() {
} }

View File

@ -21,7 +21,6 @@ class ChangeRLPManipulator(forms.Manipulator):
) )
def save(self, new_data): def save(self, new_data):
rlp = RowLevelPermission.objects.get(pk=new_data['id']) rlp = RowLevelPermission.objects.get(pk=new_data['id'])
self.original_object = rlp self.original_object = rlp
@ -37,7 +36,6 @@ class ChangeRLPManipulator(forms.Manipulator):
perm = Permission.objects.get(pk=new_data['perm']) perm = Permission.objects.get(pk=new_data['perm'])
field_name_list = ('owner_ct', 'owner_id', 'model_ct', 'model_id', 'permission') field_name_list = ('owner_ct', 'owner_id', 'model_ct', 'model_id', 'permission')
field_data = owner_ct.id field_data = owner_ct.id
all_data = {'owner_id': owner.id, 'model_ct_id': model_ct.id, 'model_id': model_id, 'permission_id': perm.id} all_data = {'owner_id': owner.id, 'model_ct_id': model_ct.id, 'model_id': model_id, 'permission_id': perm.id}
@ -63,7 +61,6 @@ class AddRLPManipulator(ChangeRLPManipulator):
) )
def save(self, new_data): def save(self, new_data):
owner = MultipleObjSelectField.returnObject(new_data['owner']) owner = MultipleObjSelectField.returnObject(new_data['owner'])
self.manager = RowLevelPermission._default_manager self.manager = RowLevelPermission._default_manager
@ -74,7 +71,7 @@ class AddRLPManipulator(ChangeRLPManipulator):
for i in new_data.getlist('perm'): for i in new_data.getlist('perm'):
perm = Permission.objects.get(pk=i) perm = Permission.objects.get(pk=i)
#Check that the new row level perms are unique # Check that the new row level perms are unique.
field_name_list = ('owner_ct', 'owner_id', 'model_ct', 'model_id', 'permission') field_name_list = ('owner_ct', 'owner_id', 'model_ct', 'model_id', 'permission')
field_data = ct.id field_data = ct.id
model_id = self.obj_instance._get_pk_val() model_id = self.obj_instance._get_pk_val()
@ -106,9 +103,8 @@ class MultipleObjSelectField(forms.SelectField):
parameter for the content type (ct), if you have already determined the content type and want to save on parameter for the content type (ct), if you have already determined the content type and want to save on
db queries. db queries.
""" """
def __init__(self, field_name, obj_list=None, def __init__(self, field_name, obj_list=None, default_text=None, size=1,
default_text=None, size=1, is_required=False, validator_list=None, is_required=False, validator_list=None, member_name=None):
member_name=None):
choice_list = [] choice_list = []
self.default_text = default_text self.default_text = default_text
# Loop through the object list and create the list to be displayed # Loop through the object list and create the list to be displayed
@ -117,9 +113,8 @@ class MultipleObjSelectField(forms.SelectField):
object_choice = [(MultipleObjSelectField.returnKey(o, ct=ct), str(o)) for o in obj_choices] object_choice = [(MultipleObjSelectField.returnKey(o, ct=ct), str(o)) for o in obj_choices]
choice_list.extend([(ct.name.title(), object_choice)]) choice_list.extend([(ct.name.title(), object_choice)])
super(MultipleObjSelectField, self).__init__(field_name, choices=choice_list, super(MultipleObjSelectField, self).__init__(field_name, choices=choice_list,
size=size, is_required=is_required, size=size, is_required=is_required, validator_list=validator_list, member_name=member_name)
validator_list=validator_list,
member_name=member_name)
def render(self, data): def render(self, data):
from django.utils.html import escape from django.utils.html import escape
output = ['<select id="%s" class="v%s%s" name="%s" size="%s">' % \ output = ['<select id="%s" class="v%s%s" name="%s" size="%s">' % \
@ -157,6 +152,3 @@ class MultipleObjSelectField(forms.SelectField):
returnObject = staticmethod(returnObject) returnObject = staticmethod(returnObject)
returnKey = staticmethod(returnKey) returnKey = staticmethod(returnKey)

View File

@ -108,12 +108,9 @@ import sha
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
def verify_objref_hash( content_type_id, object_id, hash ): def verify_objref_hash(content_type_id, object_id, hash_):
hash_match = sha.new("%s/%s" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest() hash_match = sha.new("%s/%s" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest()
if hash == hash_match: return hash_ == hash_match
return True
else:
return False
def create_objref(object): def create_objref(object):
content_type_id = ContentType.objects.get_for_model(object).id content_type_id = ContentType.objects.get_for_model(object).id

View File

@ -51,15 +51,15 @@ class RowLevelPermissionManager(models.Manager):
def create_row_level_permission(self, model_instance, owner, permission, negative=False): def create_row_level_permission(self, model_instance, owner, permission, negative=False):
model_ct = ContentType.objects.get_for_model(model_instance) model_ct = ContentType.objects.get_for_model(model_instance)
if isinstance(permission, str): if isinstance(permission, str):
permission = Permission.objects.get(codename__exact=permission, content_type=model_ct.id) permission = Permission.objects.get(codename=permission, content_type=model_ct.id)
if model_ct != permission.content_type: if model_ct != permission.content_type:
raise TypeError, "Invalid value: Permission content type(%s) and object content type(%s) do not match" % (permission.content_type, type_ct) raise TypeError, "Permission content type (%s) and object content type (%s) do not match" % (permission.content_type, type_ct)
model_id = model_instance._get_pk_val() model_id = model_instance._get_pk_val()
rowLvlPerm = self.model(model_id=model_id, model_ct=model_ct, row_lvl_perm = self.model(model_id=model_id, model_ct=model_ct, owner_id=owner.id,
owner_id=owner.id, owner_ct=ContentType.objects.get_for_model(owner), owner_ct=ContentType.objects.get_for_model(owner),
permission=permission, negative=negative) permission=permission, negative=negative)
rowLvlPerm.save() row_lvl_perm.save()
return rowLvlPerm return row_lvl_perm
def create_default_row_permissions(self, model_instance, owner, change=True, delete=True, negChange=False, negDel=False): def create_default_row_permissions(self, model_instance, owner, change=True, delete=True, negChange=False, negDel=False):
ret_dict = {} ret_dict = {}
@ -77,17 +77,12 @@ class RowLevelPermissionManager(models.Manager):
if isinstance(perm, str): if isinstance(perm, str):
perm = Permission.objects.get(codename__exact=perm, content_type=model_ct.id) perm = Permission.objects.get(codename__exact=perm, content_type=model_ct.id)
user_model_ids = RowLevelPermission.objects.filter(owner_ct=ContentType.objects.get_for_model(User), user_model_ids = RowLevelPermission.objects.filter(owner_ct=ContentType.objects.get_for_model(User),
owner_id=user.id, permission=perm.id, owner_id=user.id, permission=perm.id, model_ct=model_ct).values('model_id')
model_ct=model_ct
).values('model_id')
id_list = [o['model_id'] for o in user_model_ids] id_list = [o['model_id'] for o in user_model_ids]
user_group_list = [g['id'] for g in user.groups.select_related().values('id')] user_group_list = [g['id'] for g in user.groups.select_related().values('id')]
if user_group_list: if user_group_list:
group_model_ids = RowLevelPermission.objects.filter(owner_ct=ContentType.objects.get_for_model(Group).id, group_model_ids = RowLevelPermission.objects.filter(owner_ct=ContentType.objects.get_for_model(Group).id,
owner_id__in=user_group_list, owner_id__in=user_group_list, model_ct = model_ct).values('model_id')
model_ct = model_ct
).values('model_id')
id_list = id_list + [o['model_id'] for o in group_model_ids] id_list = id_list + [o['model_id'] for o in group_model_ids]
return id_list return id_list
@ -96,7 +91,6 @@ class RowLevelPermission(models.Model):
Similiar to permissions but works on instances of objects instead of types. Similiar to permissions but works on instances of objects instead of types.
This uses generic relations to minimize the number of tables, and connects to the This uses generic relations to minimize the number of tables, and connects to the
permissions table using a many to one relation. permissions table using a many to one relation.
""" """
model_id = models.PositiveIntegerField("'Model' ID") model_id = models.PositiveIntegerField("'Model' ID")
model_ct = models.ForeignKey(ContentType, verbose_name="'Model' content type", related_name="model_ct") model_ct = models.ForeignKey(ContentType, verbose_name="'Model' content type", related_name="model_ct")
@ -104,10 +98,8 @@ class RowLevelPermission(models.Model):
owner_ct = models.ForeignKey(ContentType, verbose_name="'Owner' content type", related_name="owner_ct") owner_ct = models.ForeignKey(ContentType, verbose_name="'Owner' content type", related_name="owner_ct")
negative = models.BooleanField() negative = models.BooleanField()
permission = models.ForeignKey(Permission) permission = models.ForeignKey(Permission)
model = models.GenericForeignKey(fk_field='model_id', ct_field='model_ct') model = models.GenericForeignKey(fk_field='model_id', ct_field='model_ct')
owner = models.GenericForeignKey(fk_field='owner_id', ct_field='owner_ct') owner = models.GenericForeignKey(fk_field='owner_id', ct_field='owner_ct')
objects = RowLevelPermissionManager() objects = RowLevelPermissionManager()
class Meta: class Meta:
@ -124,7 +116,6 @@ class RowLevelPermission(models.Model):
def __repr__(self): def __repr__(self):
return "%s | %s:%s | %s:%s" % (self.permission, self.owner_ct, self.owner, self.model_ct, self.model) return "%s | %s:%s | %s:%s" % (self.permission, self.owner_ct, self.owner, self.model_ct, self.model)
class Group(models.Model): class Group(models.Model):
"""Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups. """Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
@ -286,27 +277,18 @@ class User(models.Model):
object_ct = ContentType.objects.get_for_model(object) object_ct = ContentType.objects.get_for_model(object)
if isinstance(permission, str): if isinstance(permission, str):
try: try:
permission = Permission.objects.get(codename__exact=permission, content_type=object_ct.id) permission = Permission.objects.get(codename=permission, content_type=object_ct.id)
except Permission.DoesNotExist: except Permission.DoesNotExist:
return False return False
try: try:
model_id = object._get_pk_val() model_id = object._get_pk_val()
row_level_perm = self.row_level_permissions_owned.get(model_id=model_id, row_level_perm = self.row_level_permissions_owned.get(model_id=model_id,
model_ct=object_ct.id, model_ct=object_ct.id, permission=permission.id)
permission=permission.id)
except RowLevelPermission.DoesNotExist: except RowLevelPermission.DoesNotExist:
return self.check_group_row_level_permissions(permission, object) return self.check_group_row_level_permissions(permission, object)
return not row_level_perm.negative return not row_level_perm.negative
def check_group_row_level_permissions(self, permission, object): def check_group_row_level_permissions(self, permission, object):
#SELECT rlp."negative"
#FROM "auth_user_groups" ug, "auth_rowlevelpermission" rlp
#WHERE rlp."owner_id"=ug."group_id"
#AND ug."user_id"=%s
#AND rlp."owner_ct_id"=%s
#AND rlp."model_id"=%s
#AND rlp."model_ct_id"=%s
#AND rlp."permission_id"=%s;
model_id = object._get_pk_val() model_id = object._get_pk_val()
cursor = connection.cursor() cursor = connection.cursor()
sql = """ sql = """
@ -331,12 +313,10 @@ class User(models.Model):
ContentType.objects.get_for_model(object).id, ContentType.objects.get_for_model(object).id,
permission.id,]) permission.id,])
row = cursor.fetchone() row = cursor.fetchone()
if row is None: if row is None:
return None return None
return not row[0] return not row[0]
def has_perm(self, perm, object=None): def has_perm(self, perm, object=None):
"Returns True if the user has the specified permission." "Returns True if the user has the specified permission."
if not self.is_active: if not self.is_active:
@ -344,7 +324,7 @@ class User(models.Model):
if self.is_superuser: if self.is_superuser:
return True return True
if object and object._meta.row_level_permissions: if object and object._meta.row_level_permissions:
#Since we use the content type for row level perms, we don't need the application name # Since we use the content type for row level perms, we don't need the application name.
permission_str = perm[perm.index('.')+1:] permission_str = perm[perm.index('.')+1:]
row_level_permission = self.check_row_level_permission(permission_str, object) row_level_permission = self.check_row_level_permission(permission_str, object)
if row_level_permission is not None: if row_level_permission is not None:
@ -377,20 +357,11 @@ class User(models.Model):
else: else:
permission = perm permission = perm
count = self.row_level_permissions_owned.filter(model_ct=model_ct.id, permission=permission.id).count() count = self.row_level_permissions_owned.filter(model_ct=model_ct.id, permission=permission.id).count()
if count > 0: if count > 0:
return True return True
return self.contains_group_row_level_perms(permission, model_ct) return self.contains_group_row_level_perms(permission, model_ct)
def contains_group_row_level_perms(self, perm, ct): def contains_group_row_level_perms(self, perm, ct):
#SELECT COUNT(*)
#FROM "auth_user_groups" ug, "auth_rowlevelpermission" rlp, "django_content_type" ct
#WHERE rlp."owner_id" = ug."group_id"
#AND ug."user_id"=%s
#AND rlp."negative" = False
#AND rlp."owner_ct_id" = %s
#AND rlp."model_ct_id" = %s
cursor = connection.cursor() cursor = connection.cursor()
sql = """ sql = """
SELECT COUNT(*) SELECT COUNT(*)
@ -408,7 +379,7 @@ class User(models.Model):
backend.quote_name('model_ct_id'), backend.quote_name('permission_id')) backend.quote_name('model_ct_id'), backend.quote_name('permission_id'))
cursor.execute(sql, [self.id, False, ContentType.objects.get_for_model(Group).id, ct.id, perm.id]) cursor.execute(sql, [self.id, False, ContentType.objects.get_for_model(Group).id, ct.id, perm.id])
count = int(cursor.fetchone()[0]) count = int(cursor.fetchone()[0])
return (count>0) return count > 0
def has_module_perms(self, app_label): def has_module_perms(self, app_label):
"Returns True if the user has any permissions in the given app label." "Returns True if the user has any permissions in the given app label."
@ -416,18 +387,11 @@ class User(models.Model):
return False return False
if self.is_superuser: if self.is_superuser:
return True return True
if bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label])): if [p for p in self.get_all_permissions() if p[:p.index('.')] == app_label]:
return True return True
return self.has_module_row_level_perms(app_label) return self.has_module_row_level_perms(app_label)
def has_module_row_level_perms(self, app_label): def has_module_row_level_perms(self, app_label):
#SELECT COUNT(*)
#FROM "django_content_type" ct, "auth_rowlevelpermission" rlp
#WHERE rlp."model_ct_id" = ct."id"
#AND ct."app_label"=%s
#AND rlp."negative" = False
#AND rlp."owner_ct_id" = %s
#AND rlp."owner_id" = %s
cursor = connection.cursor() cursor = connection.cursor()
sql = """ sql = """
SELECT COUNT(*) SELECT COUNT(*)
@ -443,8 +407,6 @@ class User(models.Model):
backend.quote_name('app_label'), backend.quote_name('app_label'),
backend.quote_name('owner_ct_id'), backend.quote_name('owner_ct_id'),
backend.quote_name('owner_id'),backend.quote_name('negative'), ) backend.quote_name('owner_id'),backend.quote_name('negative'), )
#import pdb
#pdb.set_trace()
cursor.execute(sql, [app_label, ContentType.objects.get_for_model(User).id, self.id, False]) cursor.execute(sql, [app_label, ContentType.objects.get_for_model(User).id, self.id, False])
count = int(cursor.fetchone()[0]) count = int(cursor.fetchone()[0])
if count > 0: if count > 0:
@ -452,14 +414,6 @@ class User(models.Model):
return self.has_module_group_row_level_perms(app_label) return self.has_module_group_row_level_perms(app_label)
def has_module_group_row_level_perms(self, app_label): def has_module_group_row_level_perms(self, app_label):
#SELECT COUNT(*)
#FROM "auth_user_groups" ug, "auth_rowlevelpermission" rlp, "django_content_type" ct
#WHERE rlp."owner_id" = ug."group_id"
#AND ug."user_id"=%s
#AND rlp."model_ct_id" = ct."id"
#AND ct."app_label"=%s
#AND rlp."negative" = False
#AND rlp."owner_ct_id" = %s
cursor = connection.cursor() cursor = connection.cursor()
sql = """ sql = """
SELECT COUNT(*) SELECT COUNT(*)
@ -480,7 +434,6 @@ class User(models.Model):
count = int(cursor.fetchone()[0]) count = int(cursor.fetchone()[0])
return (count>0) return (count>0)
def get_and_delete_messages(self): def get_and_delete_messages(self):
messages = [] messages = []
for m in self.message_set.all(): for m in self.message_set.all():

View File

@ -6,18 +6,16 @@ register = template.Library()
def if_has_perm(parser, token): def if_has_perm(parser, token):
""" """
TODO: Update document TODO: Update document
Checks permission on the given user. Will check Checks permission on the given user. Checks row-level permissions if an
row level permissions if an object is given. object is given.
Note: Perm name should be in the format of [app_label].[perm codename]
Perm name should be in the format [app_label].[perm codename].
""" """
tokens = token.split_contents() tokens = token.split_contents()
if len(tokens) < 2: if len(tokens) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least 1 arguments" % tokens[0] raise template.TemplateSyntaxError, "%r tag requires at least 1 argument" % tokens[0]
if len(tokens) > 4: if len(tokens) > 4:
raise template.TemplateSyntaxError, "%r tag should have no more then 3 arguments" % tokens[0] raise template.TemplateSyntaxError, "%r tag should have no more then 3 arguments" % tokens[0]
@ -31,7 +29,7 @@ def if_has_perm(parser, token):
object_var = None object_var = None
not_flag = False not_flag = False
if tokens[1] is "not": if tokens[1] == "not":
not_flag = True not_flag = True
permission = tokens[2] permission = tokens[2]
if len(tokens) > 3: if len(tokens) > 3:

View File

@ -233,7 +233,6 @@ class AutomaticManipulator(forms.Manipulator):
new_rel_obj.delete() new_rel_obj.delete()
self.fields_deleted.append('%s "%s"' % (related.opts.verbose_name, old_rel_obj)) self.fields_deleted.append('%s "%s"' % (related.opts.verbose_name, old_rel_obj))
# Save the order, if applicable. # Save the order, if applicable.
if self.change and self.opts.get_ordered_objects(): if self.change and self.opts.get_ordered_objects():
order = new_data['order_'] and map(int, new_data['order_'].split(',')) or [] order = new_data['order_'] and map(int, new_data['order_'].split(',')) or []