src/cm/security.py
author gibus
Mon, 14 May 2012 16:01:30 +0200
changeset 429 fc7477d34489
parent 355 c926868cf7e6
child 449 5387c032df35
permissions -rw-r--r--
Fixed author when there is none.
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
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    12
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    13
from cm.models import *
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    14
from cm import cm_settings
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    15
from cm.exception import UnauthorizedException
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    16
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    17
def get_request_user(request):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    18
    if request and request.user and not request.user.is_anonymous():
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    19
        user = request.user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    20
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    21
        user = None
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    22
    return user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    23
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    24
## Permission functions
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    25
class FakeRequest(object):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    26
    def __init__(self, user):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    27
        self.user = user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    28
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    29
def user_has_perm(user, perm_name, text=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    30
    return has_perm(FakeRequest(user),perm_name, text)
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 has_perm(request, perm_name, text=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    33
    # bypass sec if NO_SECURITY
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    34
    if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    35
        return True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    36
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    37
    # make sure perm exist
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    38
    assert Permission.objects.get(codename=perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    39
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    40
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    41
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    42
    if user and user.is_staff:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    43
        return True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    44
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    45
    if not text:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    46
        return UserRole.objects.filter(user=user, text=None).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    47
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    48
        # local role only ADDS permissions:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    49
        # either a global or a local role with appropriate permissions
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    50
        #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
    51
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    52
        # local role OVERRIDES global role:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    53
        if UserRole.objects.filter(Q(user=user),Q(text=text),~Q(role=None)): # if non void local role
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    54
            return UserRole.objects.filter(user=user).filter(text=text).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    55
        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
    56
            # 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
    57
            # 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
    58
            # OR global role for this user
e4715ab65e2d fix security pb (too restrictive): logged users should inherit anon roles (if no text role is defined)
raph
parents: 102
diff changeset
    59
            return 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            
e4715ab65e2d fix security pb (too restrictive): logged users should inherit anon roles (if no text role is defined)
raph
parents: 102
diff changeset
    60
            #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
    61
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    62
def has_own_perm(request, perm_name, text, comment):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    63
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    64
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    65
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    66
    if not user:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    67
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    68
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    69
    # bypass sec if NO_SECURITY
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    70
    if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    71
        return True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    72
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    73
    # make sure perm exist
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    74
    assert Permission.objects.get(codename=perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    75
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    76
    # 2 special cases for comment own edition:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    77
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    78
    # 1
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    79
    # if perm = can_edit_own_comment and 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    80
    # text is a priori moderated and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    81
    # comment is approved and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    82
    # don't have moderation rights and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    83
    if comment and comment.state == 'approved' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    84
       perm_name == 'can_edit_comment_own' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    85
       text.last_text_version.mod_posteriori == False and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    86
       not has_perm(request, 'can_manage_text', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    87
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    88
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    89
    # 2       
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    90
    # if perm = can_edit_own_comment and and 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    91
    # text is a posteriori moderated and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    92
    # there is a reply
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    93
    # don't have moderation rights and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    94
    if comment and comment.state == 'approved' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    95
       perm_name == 'can_edit_comment_own' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    96
       text.last_text_version.mod_posteriori == True and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    97
       comment.comment_set.count() != 0 and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    98
       not has_perm(request, 'can_manage_text', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    99
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   100
    
355
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   101
    actual_own_user = False
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   102
    from cm.cm_settings import DECORATED_CREATORS
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   103
    if comment.user == request.user:
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   104
      if DECORATED_CREATORS:
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   105
        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
   106
          actual_own_user = True
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   107
      else:
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   108
        actual_own_user = True
c926868cf7e6 if DECORATED_CREATORS take into account the "fake" username if has_own_perm()
gibus
parents: 295
diff changeset
   109
    return (actual_own_user and has_perm(request, perm_name, text=text)) 
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   110
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   111
def is_authenticated(request):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   112
    # We customize this to be able to monkey patch it if needed
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   113
    return request.user.is_authenticated()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   114
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   115
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   116
## Content access functions
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   117
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   118
def get_texts_with_perm(request, perm_name):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   119
    assert Permission.objects.get(codename=perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   120
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   121
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   122
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   123
    if user and user.is_staff:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   124
        return Text.objects.all()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   125
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   126
    # local role only ADDS permissions:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   127
    ## global perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   128
    # 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
   129
    #    return Text.objects.all().distinct()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   130
    ## only texts with role with perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   131
    #else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   132
    #    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
   133
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   134
    # local role OVERRIDES global role:
102
f5d3ea4bd03c fix permissions in get_text_with_perms
raph
parents: 81
diff changeset
   135
    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
   136
    #Text.objects.filter(Q(userrole__user=user) & ~Q(userrole__role=None))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   137
    texts_without_local_role = Text.objects.exclude(id__in=texts_with_local_role)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   138
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   139
    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
   140
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   141
    # global perm?
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   142
    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
   143
        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
   144
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   145
        texts_without_local_role_with_perm = []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   146
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   147
    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]))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   148
    return Text.objects.filter(id__in=ids)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   149
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   150
def get_viewable_comments(request, comments, text, order_by=('created',)):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   151
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   152
    Get comments visibles by user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   153
    comments: queryset
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   154
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   155
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   156
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   157
    if user and has_perm(request, 'can_view_unapproved_comment', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   158
        return list(comments.order_by(*order_by))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   159
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   160
        if has_perm(request, 'can_view_approved_comment', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   161
            visible_comments = comments.filter(state = 'approved').order_by(*order_by)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   162
            # 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
   163
            comments_thread_viewable = [c for c in visible_comments if c.is_thread_full_visible()]
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   164
            return comments_thread_viewable 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   165
        elif user and has_perm(request, 'can_view_comment_own', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   166
            visible_comments = comments.filter(user=user).order_by(*order_by)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   167
            # 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
   168
            comments_thread_viewable = [c for c in visible_comments if c.is_thread_full_visible(own_user=user)]
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   169
            return comments_thread_viewable                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   170
        else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   171
            return []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   172
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   173
def get_viewable_activities(request=None, act_types={}, text=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   174
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   175
    Get activities user in request is allowed to see
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   176
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   177
    from cm.security import has_perm, get_texts_with_perm, get_viewable_comments
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   178
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   179
    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
   180
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   181
    activities = Activity.objects.filter(type__in=selected_activities)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   182
    if text:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   183
        activities = activities.filter(text=text)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   184
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   185
    if not has_perm(request, 'can_manage_workspace'):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   186
        texts = get_texts_with_perm(request, 'can_view_text')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   187
        activities = activities.filter(Q(text__in=texts))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   188
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   189
        comments = [] 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   190
        [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
   191
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   192
        activities = activities.filter(Q(comment__in=comments) | Q(comment=None))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   193
    return activities.order_by('-created')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   194
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   195
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   196
# won't need to be overridden, should it be moved to another file ? 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   197
def list_viewable_comments(request, comments_list, text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   198
    ret = []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   199
    for comment in comments_list :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   200
        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
   201
    return ret
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   202
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   203
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   204
# decorators (simple wrappers around above functions)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   205
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
   206
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   207
        def _check_global_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   208
            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
   209
                raise UnauthorizedException('Should be logged in')
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   210
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   211
            if has_perm(request, perm_name, text=None): 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   212
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   213
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   214
            raise UnauthorizedException('No global perm %s' % perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   215
        _check_global_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   216
        _check_global_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   217
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   218
        return _check_global_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   219
    return _dec    
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   220
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   221
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
   222
    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
   223
    
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   224
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
   225
    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
   226
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   227
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
   228
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   229
    decorator protection checking for perm for logged in user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   230
    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
   231
    """    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   232
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   233
        def _check_local_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   234
            if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   235
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   236
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   237
            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
   238
                if not api:
295
7c40b98f627f Merge with b8672f57ba3cd4e876277a13c69621446b940052
raph
parents: 287 284
diff changeset
   239
                    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
   240
                else:
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   241
                    return rc.FORBIDDEN
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   242
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   243
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   244
            if 'key' in kwargs: 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   245
                text = get_object_or_404(Text, key=kwargs['key'])                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   246
            else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   247
                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
   248
                
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   249
            # 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
   250
            if not api:                
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   251
                req = request
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   252
            else:                    
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   253
                req = args[0]     
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   254
            if has_perm(req, perm_name, text=text): 
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   255
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   256
            #else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   257
                # 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
   258
                #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
   259
                #    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
   260
            # else : unauthorized
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   261
            
287
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   262
            if not api:
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   263
                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
   264
            else:
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   265
                return rc.FORBIDDEN
fc5ed157ebfe add api: basic auth / unit tests / online doc (based on django-piston)
raph
parents: 210
diff changeset
   266
0
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   267
        _check_local_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   268
        _check_local_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   269
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   270
        return _check_local_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   271
    return _dec
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   272
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   273
def has_perm_on_comment(perm_name):    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   274
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   275
    decorator protection checking for perm for logged in user on to comment
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   276
    perm_name: 'virtual' permission name 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   277
    """    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   278
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   279
        def _check_local_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   280
            if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   281
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   282
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   283
            if 'key' in kwargs: 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   284
                text = get_object_or_404(Text, key=kwargs['key'])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   285
                # first try permission on text                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   286
                if has_perm(request, perm_name, text=text) :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   287
                    return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   288
                if 'comment_key' in kwargs:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   289
                    comment = get_object_or_404(Comment, key=kwargs['comment_key'])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   290
                    if has_own_perm(request, perm_name + "_own", text, comment) :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   291
                        return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   292
                else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   293
                    raise Exception('no security check possible: no comment key')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   294
            else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   295
                raise Exception('no security check possible: no text key')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   296
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   297
            raise UnauthorizedException('No perm %s on comment' % perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   298
        _check_local_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   299
        _check_local_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   300
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   301
        return _check_local_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   302
    return _dec        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   303
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   304
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   305