--- 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 = []
--- 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
--- /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
--- 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: