# HG changeset patch # User verrierj # Date 1321357633 -3600 # Node ID a46cb257d8eedd2b2dc24481a619fa71628bb43b # Parent 352be36c9fd709493aa926f521209f594ecd3487 Models in ldt_utils derived from SafeModel instead of django.db.model diff -r 352be36c9fd7 -r a46cb257d8ee src/ldt/ldt/ldt_utils/models.py --- a/src/ldt/ldt/ldt_utils/models.py Tue Nov 15 12:01:16 2011 +0100 +++ b/src/ldt/ldt/ldt_utils/models.py Tue Nov 15 12:47:13 2011 +0100 @@ -6,6 +6,8 @@ from ldt.core.models import Document from guardian.shortcuts import assign, remove_perm import ldt.indexation +from ldt.security.models import SafeModel +from ldt.security.manager import SafeManager from utils import (create_ldt, copy_ldt, create_empty_iri, update_iri, generate_uuid) import lucene @@ -15,7 +17,7 @@ import tagging.fields import uuid -class Author(models.Model): +class Author(SafeModel): handle = models.CharField(max_length=512, unique=True, blank=True, null=True) email = models.EmailField(unique=False, blank=True, null=True) @@ -25,7 +27,7 @@ def __unicode__(self): return unicode(self.id) + " - " + self.handle + ", " + self.email + ", " + self.firstname + " " + self.lastname -class Media(models.Model): +class Media(SafeModel): external_id = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('media.external_id')) external_permalink = models.URLField(max_length=1024, verify_exists=False, null=True, blank=True, verbose_name=_('media.external_permalink')) external_publication_url = models.URLField(max_length=1024, verify_exists=True, null=True, blank=True, verbose_name=_('media.external_publication_url')) @@ -95,7 +97,7 @@ def get_by_natural_key(self, iri_id): return self.get(iri_id=iri_id) -class Content(models.Model): +class Content(SafeModel): objects = ContentManager() iri_id = models.CharField(max_length=1024, unique=True, default=generate_uuid, verbose_name=_('content.iri_id')) @@ -291,7 +293,7 @@ external_id = property(**external_id()) -class Project(Document): +class Project(Document, SafeModel): STATE_CHOICES = ( (1, 'edition'), (2, 'published'), @@ -309,7 +311,6 @@ changed_by = models.CharField(_("changed by"), max_length=70) state = models.IntegerField(choices=STATE_CHOICES, default=1) description = models.TextField(null=True, blank=True) - objects = models.Manager() class Meta: ordering = ["title"] @@ -406,7 +407,7 @@ return False -class Segment(models.Model): +class Segment(SafeModel): project_obj = models.ForeignKey(Project, null=True) content = models.ForeignKey(Content) diff -r 352be36c9fd7 -r a46cb257d8ee src/ldt/ldt/ldt_utils/security.py --- a/src/ldt/ldt/ldt_utils/security.py Tue Nov 15 12:01:16 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -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) \ No newline at end of file diff -r 352be36c9fd7 -r a46cb257d8ee src/ldt/ldt/ldt_utils/views.py --- a/src/ldt/ldt/ldt_utils/views.py Tue Nov 15 12:01:16 2011 +0100 +++ b/src/ldt/ldt/ldt_utils/views.py Tue Nov 15 12:47:13 2011 +0100 @@ -23,7 +23,7 @@ from guardian.core import ObjectPermissionChecker from ldt.ldt_utils.models import Content from ldt.ldt_utils.utils import boolean_convert, LdtUtils, LdtSearch -from ldt.ldt_utils.security import assign_project_to_groups +from ldt.security.utils import assign_project_to_groups from lxml.html import fragment_fromstring from models import Media, Project from projectserializer import ProjectSerializer diff -r 352be36c9fd7 -r a46cb257d8ee src/ldt/ldt/security/manager.py --- a/src/ldt/ldt/security/manager.py Tue Nov 15 12:01:16 2011 +0100 +++ b/src/ldt/ldt/security/manager.py Tue Nov 15 12:47:13 2011 +0100 @@ -4,15 +4,12 @@ class SafeManager(Manager): - def __init__(self, cls, user=None): - super(SafeManager, self).__init__() - self.model_name = cls.__name__.lower() - self.model = cls + def __init__(self, user=None): + super(SafeManager, self).__init__() if user: self.check_perm_for(user) else: - self.user = None - self.checker = None + self.user = None def check_perm_for(self, user): self.user = user @@ -20,12 +17,11 @@ def stop_checking(self): self.user = None - self.checker = None def has_user(self): - return self.user != None - - def get_query_set(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.") diff -r 352be36c9fd7 -r a46cb257d8ee src/ldt/ldt/security/middleware.py --- a/src/ldt/ldt/security/middleware.py Tue Nov 15 12:01:16 2011 +0100 +++ b/src/ldt/ldt/security/middleware.py Tue Nov 15 12:47:13 2011 +0100 @@ -2,13 +2,19 @@ from django.core.exceptions import MiddlewareNotUsed from ldt.security.utils import protect_models, unprotect_models +try: + from threading import local +except ImportError: + from django.utils._threading_local import local + +_thread_locals = local() + class SecurityMiddleware(object): def __init__(self): if not hasattr(settings, 'USE_GROUP_PERMISSIONS') or not settings.USE_GROUP_PERMISSIONS: raise MiddlewareNotUsed() - # !! Will not work with concurrent requests def process_request(self, request): protect_models(request.user) diff -r 352be36c9fd7 -r a46cb257d8ee src/ldt/ldt/security/models.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/security/models.py Tue Nov 15 12:47:13 2011 +0100 @@ -0,0 +1,9 @@ +from django.db import models +from manager import SafeManager + +class SafeModel(models.Model): + objects = models.Manager() + safe_objects = SafeManager() + + class Meta: + abstract = True \ No newline at end of file diff -r 352be36c9fd7 -r a46cb257d8ee src/ldt/ldt/security/utils.py --- a/src/ldt/ldt/security/utils.py Tue Nov 15 12:01:16 2011 +0100 +++ b/src/ldt/ldt/security/utils.py Tue Nov 15 12:47:13 2011 +0100 @@ -2,7 +2,6 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import Group from guardian.shortcuts import assign, remove_perm -from manager import SafeManager def protect_models(user): for cls in get_models_to_protect(): @@ -20,20 +19,21 @@ 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) - +def protect_model(cls, user): + cls.safe_objects.check_perm_for(user) + cls.base_save = cls.save - cls.save = change_security(user, cls.__name__.lower())(cls.save) - + cls.base_delete = cls.delete + class_name = cls.__name__.lower() + cls.save = change_security(user, class_name)(cls.save) + cls.delete = change_security(user, class_name)(cls.delete) 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 + if hasattr(cls, 'base_save'): + cls.save = cls.base_save + cls.delete = cls.base_delete + del cls.base_save + del cls.base_delete def change_security(user, cls_name): def wrapper(func):