src/cm/security.py
author gibus
Thu, 11 Jul 2013 14:44:02 +0200
changeset 522 c9c2148f09c9
parent 470 077be006891e
child 523 cc1cd48289e0
permissions -rw-r--r--
improves performence of text_view_comments by memoizing permission computations.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     1
from django.conf import settings
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     2
from django.contrib.auth import REDIRECT_FIELD_NAME
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     3
from django.contrib.auth.models import Permission
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     4
from django.contrib.contenttypes.models import ContentType
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     5
from django.shortcuts import get_object_or_404
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     6
from django.core.urlresolvers import reverse
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     7
from django.http import HttpResponseRedirect
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     8
from django.utils.http import urlquote
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
     9
from django.db.models import Q
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
    10
from piston.utils import rc
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    11
import logging
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    12
from django.core.cache import cache
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    13
from hashlib import sha1
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    14
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    15
from cm.models import *
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    16
from cm import cm_settings
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    17
from cm.exception import UnauthorizedException
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
    18
from cm.cm_settings import DECORATED_CREATORS
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    19
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    20
def get_request_user(request):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    21
    if request and request.user and not request.user.is_anonymous():
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    22
        user = request.user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    23
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    24
        user = None
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    25
    return user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    26
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    27
## Permission functions
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    28
class FakeRequest(object):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    29
    def __init__(self, user):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    30
        self.user = user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    31
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    32
def user_has_perm(user, perm_name, text=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    33
    return has_perm(FakeRequest(user),perm_name, text)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    34
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    35
def has_perm(request, perm_name, text=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    36
    # bypass sec if NO_SECURITY
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    37
    if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    38
        return True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    39
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    40
    # make sure perm exist
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    41
    assert Permission.objects.get(codename=perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    42
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    43
    user = get_request_user(request)
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    44
    myself = request.GET.get('name', None)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    45
    key = sha1(str((settings.SITE_URL, 'has_perm', (user, myself, text, perm_name)))).hexdigest()
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    46
    val = cache.get(key)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    47
    if val != None:
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    48
      return val
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    49
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    50
    if user and user.is_staff:
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    51
        cache.set(key, True)
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    52
        return True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    53
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    54
    if not text:
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    55
        ret = UserRole.objects.filter(user=user, text=None).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    56
        cache.set(key, ret)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    57
        return ret
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    58
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    59
        # local role only ADDS permissions:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    60
        # either a global or a local role with appropriate permissions
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    61
        #return UserRole.objects.filter(user=user).filter(Q(text=text) | Q(text=None)).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    62
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    63
        # local role OVERRIDES global role:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    64
        if UserRole.objects.filter(Q(user=user),Q(text=text),~Q(role=None)): # if non void local role
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    65
            ret = UserRole.objects.filter(user=user).filter(text=text).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    66
            cache.set(key, ret)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    67
            return ret
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    68
        else:
210
e4715ab65e2d fix security pb (too restrictive): logged users should inherit anon roles (if no text role is defined)
raph
parents: 102
diff changeset
    69
            # local role for anon users
e4715ab65e2d fix security pb (too restrictive): logged users should inherit anon roles (if no text role is defined)
raph
parents: 102
diff changeset
    70
            # OR global role for anon users
e4715ab65e2d fix security pb (too restrictive): logged users should inherit anon roles (if no text role is defined)
raph
parents: 102
diff changeset
    71
            # OR global role for this user
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    72
            ret = UserRole.objects.filter(Q(user=user) | Q(user=None)).filter(Q(text=None) | Q(text=text)).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0            
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    73
            cache.set(key, ret)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    74
            return ret
210
e4715ab65e2d fix security pb (too restrictive): logged users should inherit anon roles (if no text role is defined)
raph
parents: 102
diff changeset
    75
            #return UserRole.objects.filter(user=user).filter(text=None).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    76
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    77
def has_own_perm(request, perm_name, text, comment):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    78
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    79
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    80
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    81
    if not user:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    82
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    83
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    84
    # bypass sec if NO_SECURITY
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    85
    if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    86
        return True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    87
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    88
    # make sure perm exist
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    89
    assert Permission.objects.get(codename=perm_name)
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    90
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    91
    myself = request.GET.get('name', None)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    92
    key = sha1(str((settings.SITE_URL, 'has_own_perm', (user, myself, text, comment, perm_name)))).hexdigest()
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    93
    val = cache.get(key)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    94
    if val != None:
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
    95
      return val
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    96
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    97
    # 2 special cases for comment own edition:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    98
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    99
    # 1
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   100
    # if perm = can_edit_own_comment and 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   101
    # text is a priori moderated and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   102
    # comment is approved and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   103
    # don't have moderation rights and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   104
    if comment and comment.state == 'approved' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   105
       perm_name == 'can_edit_comment_own' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   106
       text.last_text_version.mod_posteriori == False and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   107
       not has_perm(request, 'can_manage_text', text=text):
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   108
        cache.set(key, False)
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   109
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   110
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   111
    # 2       
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   112
    # if perm = can_edit_own_comment and and 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   113
    # text is a posteriori moderated and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   114
    # there is a reply
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   115
    # don't have moderation rights and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   116
    if comment and comment.state == 'approved' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   117
       perm_name == 'can_edit_comment_own' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   118
       text.last_text_version.mod_posteriori == True and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   119
       comment.comment_set.count() != 0 and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   120
       not has_perm(request, 'can_manage_text', text=text):
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   121
        cache.set(key, False)
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   122
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   123
    
355
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   124
    actual_own_user = False
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   125
    if comment.user == request.user:
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   126
      if DECORATED_CREATORS:
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   127
        if request.GET.get('name', None) == comment.get_name():
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   128
          actual_own_user = True
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   129
      else:
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   130
        actual_own_user = True
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   131
    ret = (actual_own_user and has_perm(request, perm_name, text=text)) 
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   132
    cache.set(key, ret)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   133
    return ret
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   134
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   135
def is_authenticated(request):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   136
    # We customize this to be able to monkey patch it if needed
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   137
    return request.user.is_authenticated()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   138
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   139
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   140
## Content access functions
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   141
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   142
def get_texts_with_perm(request, perm_name):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   143
    assert Permission.objects.get(codename=perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   144
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   145
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   146
    
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   147
    key = sha1(str((settings.SITE_URL, 'get_texts_with_perm', (user, perm_name)))).hexdigest()
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   148
    val = cache.get(key)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   149
    if val != None:
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   150
      return val
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   151
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   152
    if user and user.is_staff:
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   153
        ret = Text.objects.all()
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   154
        cache.set(key, ret)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   155
        return ret
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   156
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   157
    # local role only ADDS permissions:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   158
    ## global perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   159
    # if UserRole.objects.filter(text=None).filter(role__permissions__codename__exact=perm_name).filter(Q(user=user) | Q(user=None) ).count() != 0:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   160
    #    return Text.objects.all().distinct()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   161
    ## only texts with role with perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   162
    #else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   163
    #    return Text.objects.filter(Q(userrole__role__permissions__codename__exact=perm_name), Q(userrole__user=user) | Q(userrole__user=None)).distinct()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   164
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   165
    # local role OVERRIDES global role:
102
f5d3ea4bd03c fix permissions in get_text_with_perms
raph
parents: 81
diff changeset
   166
    texts_with_local_role = Text.objects.filter(userrole__in=UserRole.objects.filter(Q(user=user) | Q(user=None)).filter(~Q(role=None)))
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   167
    #Text.objects.filter(Q(userrole__user=user) & ~Q(userrole__role=None))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   168
    texts_without_local_role = Text.objects.exclude(id__in=texts_with_local_role)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   169
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   170
    texts_with_local_role_with_perm = Text.objects.filter(id__in=texts_with_local_role).filter(Q(userrole__role__permissions__codename__exact=perm_name), Q(userrole__user=user) | Q(userrole__user=None)).distinct()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   171
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   172
    # global perm?
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   173
    if UserRole.objects.filter(text=None).filter(role__permissions__codename__exact=perm_name).filter(Q(user=user) | Q(user=None) ).count() != 0:    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   174
        texts_without_local_role_with_perm = Text.objects.filter(id__in=texts_without_local_role)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   175
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   176
        texts_without_local_role_with_perm = []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   177
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   178
    ids = set([t.id for t in texts_with_local_role_with_perm]).union(set([t.id for t in texts_without_local_role_with_perm]))
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   179
    ret = Text.objects.filter(id__in=ids)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   180
    cache.set(key, ret)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   181
    return ret
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   182
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   183
def get_viewable_comments(request, comments, text, order_by=('created',)):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   184
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   185
    Get comments visibles by user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   186
    comments: queryset
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   187
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   188
    user = get_request_user(request)
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   189
    myself = request.GET.get('name', None)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   190
    key = sha1(str((settings.SITE_URL, 'get_viewable_comments', (user, myself, text, comments)))).hexdigest()
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   191
    val = cache.get(key)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   192
    if val != None:
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   193
      return val
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   194
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   195
    if user and has_perm(request, 'can_view_unapproved_comment', text=text):
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   196
        ret = list(comments.order_by(*order_by))
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   197
        cache.set(key, ret)
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   198
        return ret
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   199
    else:
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   200
        # Fetch role_model to process specific behaviour for role_teacher model
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   201
        from cm.models import ApplicationConfiguration
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   202
        role_model = ApplicationConfiguration.get_key('workspace_role_model')
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   203
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   204
        if has_perm(request, 'can_view_approved_comment', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   205
            visible_comments = comments.filter(state = 'approved').order_by(*order_by)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   206
            # filter comments with a non visible (i.e. moderated) comment in the above thread 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   207
            comments_thread_viewable = [c for c in visible_comments if c.is_thread_full_visible()]
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   208
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   209
            # for role_teacher role model, do not show 'individual student' comments
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   210
            if (role_model == 'teacher'):
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   211
              unfiltered_comments = list(comments_thread_viewable)
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   212
              for c in unfiltered_comments:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   213
                if c.user_id and c.user_id != 1:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   214
                  try:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   215
                    userrole = UserRole.objects.get(user=c.user, text=text)
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   216
                  except:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   217
                    userrole = UserRole.objects.get(user=None, text=None)
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   218
                  if userrole.role_id == None:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   219
                    role = c.user.get_profile().global_userrole().role
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   220
                  else:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   221
                    role = userrole.role
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   222
                  if role.name == 'Individual student':
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   223
                    comments_thread_viewable.remove(c)
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   224
            cache.set(key, comments_thread_viewable)
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   225
            return comments_thread_viewable 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   226
        elif user and has_perm(request, 'can_view_comment_own', text=text):
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   227
            if DECORATED_CREATORS:
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   228
              visible_comments = comments.filter(name=myself).order_by(*order_by)
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   229
            else:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   230
              visible_comments = comments.filter(user=user).order_by(*order_by)
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   231
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   232
            # for role_teacher role model, add 'teacher' comments
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   233
            if (role_model == 'teacher'):
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   234
              with_teachers = []
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   235
              for u in list(User.objects.filter(userrole__role__name = 'Teacher')):
470
077be006891e Fix filtering of teachers' comments for individual students in role_teacher role model when using DECORATED_CREATORS.
gibus
parents: 449
diff changeset
   236
                with_teachers.append(u.id)
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   237
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   238
              # add admin and current user
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   239
              admin =  User.objects.get(id=1)
470
077be006891e Fix filtering of teachers' comments for individual students in role_teacher role model when using DECORATED_CREATORS.
gibus
parents: 449
diff changeset
   240
              with_teachers.append(admin.id)
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   241
              if DECORATED_CREATORS:
470
077be006891e Fix filtering of teachers' comments for individual students in role_teacher role model when using DECORATED_CREATORS.
gibus
parents: 449
diff changeset
   242
                visible_comments = comments.filter(Q(user__id__in=with_teachers) | Q(name=myself)).order_by(*order_by)
449
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   243
              else:
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   244
                with_teachers.append(user.id)
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   245
                visible_comments = comments.filter(user__id__in=with_teachers).order_by(*order_by)
5387c032df35 In role_teacher model, individual students can see their own comments but also teacher's ones, whereas individual students' comments cannot be seen by students.
gibus
parents: 355
diff changeset
   246
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   247
            # filter comments with a non visible (i.e. moderated) comment in the above thread 
16
036705244cab FIX: comment visibility takes ownership into account
raph
parents: 0
diff changeset
   248
            comments_thread_viewable = [c for c in visible_comments if c.is_thread_full_visible(own_user=user)]
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   249
            cache.set(key, comments_thread_viewable)
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   250
            return comments_thread_viewable                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   251
        else:
522
c9c2148f09c9 improves performence of text_view_comments by memoizing permission computations.
gibus
parents: 470
diff changeset
   252
            cache.set(key, [])
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   253
            return []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   254
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   255
def get_viewable_activities(request=None, act_types={}, text=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   256
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   257
    Get activities user in request is allowed to see
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   258
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   259
    from cm.security import has_perm, get_texts_with_perm, get_viewable_comments
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   260
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   261
    selected_activities = reduce(list.__add__,[Activity.VIEWABLE_ACTIVITIES[k] for k in act_types.keys() if act_types[k]], [])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   262
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   263
    activities = Activity.objects.filter(type__in=selected_activities)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   264
    if text:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   265
        activities = activities.filter(text=text)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   266
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   267
    if not has_perm(request, 'can_manage_workspace'):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   268
        texts = get_texts_with_perm(request, 'can_view_text')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   269
        activities = activities.filter(Q(text__in=texts))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   270
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   271
        comments = [] 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   272
        [comments.extend(get_viewable_comments(request, t.last_text_version.comment_set.all(), t)) for t in texts]
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   273
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   274
        activities = activities.filter(Q(comment__in=comments) | Q(comment=None))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   275
    return activities.order_by('-created')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   276
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   277
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   278
# won't need to be overridden, should it be moved to another file ? 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   279
def list_viewable_comments(request, comments_list, text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   280
    ret = []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   281
    for comment in comments_list :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   282
        ret += [comment] + list_viewable_comments(request, get_viewable_comments(request, comment.comment_set, text), text)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   283
    return ret
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   284
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   285
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   286
# decorators (simple wrappers around above functions)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   287
def has_global_perm(perm_name, must_be_logged_in=False, redirect_field_name=REDIRECT_FIELD_NAME):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   288
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   289
        def _check_global_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   290
            if must_be_logged_in and not is_authenticated(request):
284
730dd9fb2c77 simplification of security check: all unauthorized exceptions are dealt with by context processors
raph
parents: 210
diff changeset
   291
                raise UnauthorizedException('Should be logged in')
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   292
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   293
            if has_perm(request, perm_name, text=None): 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   294
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   295
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   296
            raise UnauthorizedException('No global perm %s' % perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   297
        _check_global_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   298
        _check_global_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   299
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   300
        return _check_global_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   301
    return _dec    
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   302
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   303
def has_perm_on_text_api(perm_name, must_be_logged_in=False, redirect_field_name=REDIRECT_FIELD_NAME):    
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   304
    return _has_perm_on_text(perm_name, must_be_logged_in, redirect_field_name, api=True)
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   305
    
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   306
def has_perm_on_text(perm_name, must_be_logged_in=False, redirect_field_name=REDIRECT_FIELD_NAME, api=False):
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   307
    return _has_perm_on_text(perm_name, must_be_logged_in, redirect_field_name, api)
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   308
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   309
def _has_perm_on_text(perm_name, must_be_logged_in=False, redirect_field_name=REDIRECT_FIELD_NAME, api=False):    
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   310
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   311
    decorator protection checking for perm for logged in user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   312
    force logged in (i.e. redirect to connection screen if not if must_be_logged_in 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   313
    """    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   314
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   315
        def _check_local_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   316
            if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   317
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   318
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   319
            if must_be_logged_in and not is_authenticated(request):
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   320
                if not api:
295
7c40b98f627f Merge with b8672f57ba3cd4e876277a13c69621446b940052
raph
parents: 287 284
diff changeset
   321
                    raise UnauthorizedException('Should be logged in')
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   322
                else:
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   323
                    return rc.FORBIDDEN
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   324
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   325
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   326
            if 'key' in kwargs: 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   327
                text = get_object_or_404(Text, key=kwargs['key'])                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   328
            else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   329
                raise Exception('no security check possible')
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   330
                
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   331
            # in api, the view has an object as first parameter, request is args[0]
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   332
            if not api:                
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   333
                req = request
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   334
            else:                    
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   335
                req = args[0]     
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   336
            if has_perm(req, perm_name, text=text): 
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   337
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   338
            #else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   339
                # TODO: (? useful ?) if some user have the perm and not logged-in : redirect to login
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   340
                #if not request.user.is_authenticated() and number_has_perm_on_text(permission, text_id) > 0:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   341
                #    return HttpResponseRedirect('%s?%s=%s' % (login_url, redirect_field_name, urlquote(request.get_full_path())))                    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   342
            # else : unauthorized
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   343
            
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   344
            if not api:
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   345
                raise UnauthorizedException('No perm %s' % perm_name)
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   346
            else:
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   347
                return rc.FORBIDDEN
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   348
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   349
        _check_local_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   350
        _check_local_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   351
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   352
        return _check_local_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   353
    return _dec
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   354
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   355
def has_perm_on_comment(perm_name):    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   356
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   357
    decorator protection checking for perm for logged in user on to comment
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   358
    perm_name: 'virtual' permission name 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   359
    """    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   360
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   361
        def _check_local_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   362
            if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   363
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   364
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   365
            if 'key' in kwargs: 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   366
                text = get_object_or_404(Text, key=kwargs['key'])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   367
                # first try permission on text                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   368
                if has_perm(request, perm_name, text=text) :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   369
                    return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   370
                if 'comment_key' in kwargs:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   371
                    comment = get_object_or_404(Comment, key=kwargs['comment_key'])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   372
                    if has_own_perm(request, perm_name + "_own", text, comment) :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   373
                        return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   374
                else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   375
                    raise Exception('no security check possible: no comment key')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   376
            else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   377
                raise Exception('no security check possible: no text key')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   378
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   379
            raise UnauthorizedException('No perm %s on comment' % perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   380
        _check_local_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   381
        _check_local_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   382
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   383
        return _check_local_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   384
    return _dec        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   385
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   386
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   387