# HG changeset patch # User cavaliet # Date 1365763562 -7200 # Node ID 4491284e73bbf213fab6c4f5c67afca6bbf2b4d0 # Parent 160b769463b68ff34e89e30dd9a12a4d98d8513e optimisation to open and save projects diff -r 160b769463b6 -r 4491284e73bb src/ldt/ldt/ldt_utils/views/lignesdetemps.py --- a/src/ldt/ldt/ldt_utils/views/lignesdetemps.py Thu Apr 11 10:15:51 2013 +0200 +++ b/src/ldt/ldt/ldt_utils/views/lignesdetemps.py Fri Apr 12 12:46:02 2013 +0200 @@ -7,6 +7,7 @@ from ldt.ldt_utils.models import Content, Project, Media from ldt.ldt_utils.utils import LdtUtils, clean_description from ldt.indexation import SimpleSearch +from ldt.security.permissionchecker import check_object_perm_for_user from ldt.security.utils import set_forbidden_stream from ldt.ldt_utils.stat import update_stat_project from ldt.ldt_utils.searchutils import search_generate_ldt @@ -14,6 +15,9 @@ from ldt.utils.web_url_management import get_web_url import base64 import lxml.etree + +import logging +logger = logging.getLogger(__name__) def search_index_get(request, field, query): @@ -180,28 +184,29 @@ @login_required def index_project(request, id, full=False): - + urlStr = absurl(request, "ldt.ldt_utils.views.lignesdetemps.init", args=['ldt_project', id]) posturl = absurl(request, "ldt.ldt_utils.views.lignesdetemps.save_ldt_project") language_code = request.LANGUAGE_CODE[:2] colorurl=absstatic(request, "ldt/swf/ldt/pkg/color.xml") i18nurl=absstatic(request, "ldt/swf/ldt/pkg/i18n") baseurl=absstatic(request, "ldt/swf/ldt/") + try: ldt = Project.safe_objects.get(ldt_id=id) except Project.DoesNotExist: return HttpResponseRedirect(reverse("ldt.ldt_utils.views.workspace.home")) - if ldt.state == 2 or not request.user.has_perm('change_project', ldt): #published + if ldt.state == 2 or not check_object_perm_for_user(ldt, 'change_project', request.user): readonly = 'true' else: readonly = 'false' - + if full: template_path = 'ldt/ldt_utils/init_ldt_full.html' else: template_path = 'ldt/ldt_utils/init_ldt.html' - + return render_to_response(template_path, {'colorurl': colorurl, 'i18nurl': i18nurl, 'language': language_code, 'baseurl': baseurl, 'url': urlStr, 'posturl': posturl, 'id': id, 'readonly': readonly}, context_instance=RequestContext(request)) @@ -211,7 +216,7 @@ doc = ldtgen.generate_init([url], 'ldt.ldt_utils.views.lignesdetemps.' + method, None) library = doc.xpath('/iri/files/library')[0] - for c in Content.safe_objects.all(): + for c in Content.safe_objects.all().select_related("media_obj"): elem = lxml.etree.SubElement(library, 'file') elem.set('src', c.iri_url()) if c.videopath : @@ -290,26 +295,26 @@ if c not in contents_id: content = Content.objects.get(iri_id=c) ldtproject.contents.add(content) - + update_stat_project(ldtproject) #remove html tags added by flash description = ldtproject.get_description(doc) new_desc = clean_description(description) - - if new_desc: + + if new_desc: desc_node = doc.xpath('/iri/project')[0] desc_node.set('abstract', new_desc) ldtproject.ldt = lxml.etree.tostring(doc, pretty_print=True) - + ldtproject.description = new_desc if new_desc else description - + #set a new icon for this project if check_icon_project: ldtproject.set_icon() - + ldtproject.save() - + else: ldt = '' new_contents = [] diff -r 160b769463b6 -r 4491284e73bb src/ldt/ldt/security/__init__.py --- a/src/ldt/ldt/security/__init__.py Thu Apr 11 10:15:51 2013 +0200 +++ b/src/ldt/ldt/security/__init__.py Fri Apr 12 12:46:02 2013 +0200 @@ -2,6 +2,7 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import User from django.core.signals import request_started +from ldt.security.permissionchecker import check_object_perm_for_user try: from threading import local @@ -94,9 +95,10 @@ if not user: user = get_anonymous_user() - if self.pk and not user.has_perm('change_%s' % cls_name, self): + # use our check_object_perm_for_user instead of not optimized guardian has_perm + if self.pk and not check_object_perm_for_user(self, 'change_%s' % cls_name, user): raise AttributeError('User %s is not allowed to change object %s' % (user, self)) - + return func(self, *args, **kwargs) return wrapped return wrapper diff -r 160b769463b6 -r 4491284e73bb src/ldt/ldt/security/permissionchecker.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/security/permissionchecker.py Fri Apr 12 12:46:02 2013 +0200 @@ -0,0 +1,47 @@ +from django.contrib.contenttypes.models import ContentType +from django.contrib.auth.models import Permission +from guardian.models import UserObjectPermission, GroupObjectPermission + +import logging +logger = logging.getLogger(__name__) + +def check_object_perm_for_user(obj, perm_name, user): + # Guardian has_perm request is REALLY long and not optimized. + # So we check manually the change_project permission for the user and the user's groups + # Get necessary datas + model_name = obj.__class__.__name__.lower() + content_type = ContentType.objects.get(model=model_name) + perm = Permission.objects.get(codename=perm_name) + can_change = False + # Check for the user + try: + logger.debug("COUCOU 5-2") + uop = UserObjectPermission.objects.get(user=user, content_type=content_type, permission=perm, object_pk=obj.pk) + logger.debug("COUCOU 5-3") + if uop: + logger.debug("COUCOU 5-4") + can_change = True + logger.debug("COUCOU 5-5") + except: + logger.debug("COUCOU 5-6") + can_change = False + logger.debug("COUCOU 5-7 can_change =") + logger.debug(can_change) + # Check for user's groups if necessary + if not can_change: + try: + logger.debug("COUCOU G-2") + gop = GroupObjectPermission.objects.filter(group__user=user, content_type=content_type, permission=perm, object_pk=obj.pk) + logger.debug("COUCOU G-3") + if gop and len(gop)>0: + logger.debug("COUCOU G-4") + can_change = True + logger.debug("COUCOU G-5") + except: + logger.debug("COUCOU G-6") + can_change = False + logger.debug("COUCOU G-7 can_change =") + logger.debug(can_change) + # End + return can_change + \ No newline at end of file diff -r 160b769463b6 -r 4491284e73bb src/ldt/ldt/security/utils.py --- a/src/ldt/ldt/security/utils.py Thu Apr 11 10:15:51 2013 +0200 +++ b/src/ldt/ldt/security/utils.py Fri Apr 12 12:46:02 2013 +0200 @@ -58,12 +58,15 @@ model_name = obj_list[0].__class__.__name__.lower() ctype = ContentType.objects.get(model=model_name) cls = ctype.model_class() - + + # We don't use obj.values_list('pk', flat=True) because the full queryset will be calculated and used after anyway. + pk_list = [item.pk for item in obj_list] if model_name in [cls_name.lower() for cls_name in settings.USE_GROUP_PERMISSIONS] or model_name == 'group': to_check = True - change_list = get_objects_for_user(user, '%s.change_%s' % (cls._meta.app_label, model_name)) + # Filter SUPER usefull : avoid to load ALL objects. We only check permissions on obj_list's objects + change_list = get_objects_for_user(user, '%s.change_%s' % (cls._meta.app_label, model_name)).filter(pk__in=pk_list) else: - to_check = False + to_check = False for obj in obj_list: if not to_check or obj in change_list: