Projects can be shared with users and groups. Does not work with contents yet, still some bugs in templates
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from guardian.core import ObjectPermissionChecker
from guardian.shortcuts import assign, remove_perm, get_users_with_perms, get_groups_with_perms
try:
from threading import local
except ImportError:
from django.utils._threading_local import local
_thread_locals = local()
def get_current_user():
return getattr(_thread_locals, 'user', None)
def protect_models():
cls_list = ToProtect.get_models()
if cls_list:
user = get_current_user()
for cls in ToProtect.get_models():
protect_model(cls, user)
def unprotect_models():
for cls in ToProtect.get_models():
unprotect_model(cls)
class ToProtect(object):
@staticmethod
def get_models():
if hasattr(ToProtect, 'cls_list'):
return ToProtect.cls_list
cls_list = []
for cls_name in settings.USE_GROUP_PERMISSIONS:
cls_type = ContentType.objects.get(model=cls_name.lower())
cls_list.append(cls_type.model_class())
ToProtect.cls_list = cls_list
return cls_list
def protect_model(cls, user):
cls.safe_objects.user = user
cls.safe_objects.check_perm = True
cls.old_save = cls.save
cls.old_delete = cls.delete
class_name = cls.__name__.lower()
cls.save = change_security(class_name)(cls.save)
cls.delete = change_security(class_name)(cls.delete)
def unprotect_model(cls):
if hasattr(cls, 'old_save'):
cls.save = cls.old_save
cls.delete = cls.old_delete
del cls.old_save
del cls.old_delete
cls.safe_objects.user = None
def change_security(cls_name):
def wrapper(func):
def wrapped(self, *args, **kwargs):
if self.pk and not get_current_user().has_perm('change_%s' % cls_name, self):
raise AttributeError('User %s is not allowed to change object %s' % (get_current_user(), self))
return func(self, *args, **kwargs)
return wrapped
return wrapper
def set_forbidden_stream(xml, user):
cls = ContentType.objects.get(model='content')
cls = cls.model_class()
old_user = cls.safe_objects.user
obj_list = cls.safe_objects.all()
for elem in xml.xpath('/iri/medias/media'):
if not obj_list.filter(iri_id=elem.get('id')):
elem.set('video', settings.FORBIDDEN_STREAM_URL)
cls.safe_objects.user = old_user
return xml
def add_change_attr(user, obj_list):
if len(obj_list) == 0:
return []
model_name = obj_list[0].__class__.__name__.lower()
ctype = ContentType.objects.get(model=model_name)
cls = ctype.model_class()
checker = ObjectPermissionChecker(user)
perm_name = "%s.change_%s" % (cls._meta.app_label, model_name)
for obj in obj_list:
if checker.has_perm(perm_name, obj):
obj.change = True
else:
obj.change = False
return obj_list
def assign_object_to_groups(object, read_list, write_list, owner):
name = object.__class__.__name__.lower()
old_users = get_users_with_perms(object).exclude(id=owner.id)
old_groups = get_groups_with_perms(object)
for elem in read_list:
assign('view_%s' % name, elem, object)
if elem in write_list:
assign('change_%s' % name, elem, object)
else:
remove_perm('change_%s' % name, elem, object)
def remove_perms(new_list, old_list, obj, name):
for e in old_list:
if e not in new_list:
remove_perm('view_%s' % name, e, obj)
remove_perm('change_%s' % name, e, obj)
remove_perms(read_list, old_users, object, name)
remove_perms(read_list, old_groups, object, name)
def get_perm_form(groups, formset):
perm_list = []
for group in groups:
perm_list.append({'share': False, 'perms': 'read', 'group': group.id })
permission = formset(initial=perm_list)
management_form = permission.management_form
group_form = zip(permission, groups)
return (management_form, group_form)