from django.conf import settings
from django.db.models import Manager
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType
from guardian.shortcuts import assign, remove_perm, get_objects_for_user
from guardian.core import ObjectPermissionChecker
def protect_models(user):
for cls in get_models_to_protect():
protect_model(cls, user)
def unprotect_models():
for cls in get_models_to_protect():
unprotect_model(cls)
def get_models_to_protect():
to_protect = []
for cls_name in settings.USE_GROUP_PERMISSIONS:
cls_type = ContentType.objects.get(app_label="ldt_utils", model=cls_name.lower())
to_protect.append(cls_type.model_class())
return to_protect
def protect_model(cls, user):
cls.base_objects = cls.objects
cls.objects = SafeManager(cls, user)
cls.base_save = cls.save
cls.save = save_security(user, cls.__name__.lower())(cls.save)
def unprotect_model(cls):
if hasattr(cls, 'base_objects'):
cls.objects = cls.base_objects
cls.save = cls.base_save
del cls.base_objects
del cls.base_save
class SafeManager(Manager):
def __init__(self, cls, user=None):
super(SafeManager, self).__init__()
self.model_name = cls.__name__.lower()
self.model = cls
if user:
self.check_perm_for(user)
else:
self.user = None
self.checker = None
def check_perm_for(self, user):
self.user = user
self.checker = ObjectPermissionChecker(self.user)
def stop_checking(self):
self.user = None
self.checker = None
def has_user(self):
return self.user != None
def get_query_set(self):
if not self.has_user():
raise AttributeError("A user has to be chosen to check permissions.")
user_objects = get_objects_for_user(self.user, 'ldt_utils.view_%s' % self.model_name)
return user_objects
def save_security(user, cls_name):
def wrapper(func):
def wrapped(self, *args, **kwargs):
if self.pk and not user.has_perm('change_%s' % cls_name, self):
raise AttributeError('User %s is not allowed to change object %s' % (user, self))
return func(self, *args, **kwargs)
return wrapped
return wrapper
def assign_project_to_groups(project, permissions):
for elem in permissions:
group = Group.objects.get(id=elem['group'])
if elem['share']:
assign('view_project', group, project)
if elem['perms'] == 'write':
assign('change_project', group, project)
else:
remove_perm('view_project', group, project)
remove_perm('change_project', group, project)