src/cm/security.py
author raph
Thu, 03 Dec 2009 11:55:50 +0100
changeset 16 036705244cab
parent 0 40c8f766c9b8
child 81 720bafcca97d
permissions -rw-r--r--
FIX: comment visibility takes ownership into account
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
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    10
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:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    56
            return UserRole.objects.filter(user=user).filter(text=None).filter(Q(role__permissions__codename__exact=perm_name)).count() != 0            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    57
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    58
def has_own_perm(request, perm_name, text, comment):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    59
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    60
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    61
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    62
    if not user:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    63
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    64
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    65
    # bypass sec if NO_SECURITY
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    66
    if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    67
        return True
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    68
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    69
    # make sure perm exist
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    70
    assert Permission.objects.get(codename=perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    71
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    72
    # 2 special cases for comment own edition:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    73
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    74
    # 1
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    75
    # if perm = can_edit_own_comment and 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    76
    # text is a priori moderated and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    77
    # comment is approved and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    78
    # don't have moderation rights and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    79
    if comment and comment.state == 'approved' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    80
       perm_name == 'can_edit_comment_own' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    81
       text.last_text_version.mod_posteriori == False and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    82
       not has_perm(request, 'can_manage_text', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    83
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    84
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    85
    # 2       
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    86
    # if perm = can_edit_own_comment and and 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    87
    # text is a posteriori moderated and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    88
    # there is a reply
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    89
    # don't have moderation rights and
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    90
    if comment and comment.state == 'approved' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    91
       perm_name == 'can_edit_comment_own' and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    92
       text.last_text_version.mod_posteriori == True and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    93
       comment.comment_set.count() != 0 and \
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    94
       not has_perm(request, 'can_manage_text', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    95
        return False
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    96
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    97
    return (comment.user == request.user and has_perm(request, perm_name, text=text)) 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    98
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
    99
def is_authenticated(request):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   100
    # We customize this to be able to monkey patch it if needed
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   101
    return request.user.is_authenticated()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   102
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   103
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   104
## Content access functions
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   105
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   106
def get_texts_with_perm(request, perm_name):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   107
    assert Permission.objects.get(codename=perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   108
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   109
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   110
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   111
    if user and user.is_staff:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   112
        return Text.objects.all()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   113
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   114
    # local role only ADDS permissions:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   115
    ## global perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   116
    # 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
   117
    #    return Text.objects.all().distinct()
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   118
    ## only texts with role with perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   119
    #else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   120
    #    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
   121
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   122
    # local role OVERRIDES global role:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   123
    texts_with_local_role = Text.objects.filter(userrole__in=UserRole.objects.filter(user=user).filter(~Q(role=None)))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   124
    #Text.objects.filter(Q(userrole__user=user) & ~Q(userrole__role=None))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   125
    texts_without_local_role = Text.objects.exclude(id__in=texts_with_local_role)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   126
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   127
    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
   128
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   129
    # global perm?
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   130
    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
   131
        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
   132
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   133
        texts_without_local_role_with_perm = []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   134
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   135
    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
   136
    return Text.objects.filter(id__in=ids)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   137
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   138
def get_viewable_comments(request, comments, text, order_by=('created',)):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   139
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   140
    Get comments visibles by user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   141
    comments: queryset
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   142
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   143
    user = get_request_user(request)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   144
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   145
    if user and has_perm(request, 'can_view_unapproved_comment', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   146
        return list(comments.order_by(*order_by))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   147
    else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   148
        if has_perm(request, 'can_view_approved_comment', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   149
            visible_comments = comments.filter(state = 'approved').order_by(*order_by)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   150
            # 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
   151
            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
   152
            return comments_thread_viewable 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   153
        elif user and has_perm(request, 'can_view_comment_own', text=text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   154
            visible_comments = comments.filter(user=user).order_by(*order_by)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   155
            # 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
   156
            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
   157
            return comments_thread_viewable                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   158
        else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   159
            return []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   160
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   161
def get_viewable_activities(request=None, act_types={}, text=None):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   162
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   163
    Get activities user in request is allowed to see
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   164
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   165
    from cm.security import has_perm, get_texts_with_perm, get_viewable_comments
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   166
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   167
    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
   168
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   169
    activities = Activity.objects.filter(type__in=selected_activities)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   170
    if text:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   171
        activities = activities.filter(text=text)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   172
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   173
    if not has_perm(request, 'can_manage_workspace'):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   174
        texts = get_texts_with_perm(request, 'can_view_text')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   175
        activities = activities.filter(Q(text__in=texts))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   176
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   177
        comments = [] 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   178
        [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
   179
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   180
        activities = activities.filter(Q(comment__in=comments) | Q(comment=None))
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   181
    return activities.order_by('-created')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   182
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   183
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   184
# won't need to be overridden, should it be moved to another file ? 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   185
def list_viewable_comments(request, comments_list, text):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   186
    ret = []
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   187
    for comment in comments_list :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   188
        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
   189
    return ret
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   190
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   191
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   192
# decorators (simple wrappers around above functions)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   193
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
   194
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   195
        def _check_global_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   196
            if must_be_logged_in and not is_authenticated(request):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   197
                login_url = reverse('login')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   198
                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
   199
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   200
            if has_perm(request, perm_name, text=None): 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   201
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   202
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   203
            raise UnauthorizedException('No global perm %s' % perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   204
        _check_global_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   205
        _check_global_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   206
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   207
        return _check_global_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   208
    return _dec    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   209
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   210
def has_perm_on_text(perm_name, must_be_logged_in=False, redirect_field_name=REDIRECT_FIELD_NAME):    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   211
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   212
    decorator protection checking for perm for logged in user
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   213
    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
   214
    """    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   215
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   216
        def _check_local_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   217
            if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   218
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   219
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   220
            if must_be_logged_in and not is_authenticated(request):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   221
                login_url = reverse('login')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   222
                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
   223
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   224
            if 'key' in kwargs: 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   225
                text = get_object_or_404(Text, key=kwargs['key'])                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   226
            else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   227
                raise Exception('no security check possible')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   228
                                    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   229
            if has_perm(request, perm_name, text=text): 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   230
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   231
            #else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   232
                # 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
   233
                #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
   234
                #    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
   235
            # else : unauthorized
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   236
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   237
            raise UnauthorizedException('No perm %s' % perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   238
        _check_local_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   239
        _check_local_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   240
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   241
        return _check_local_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   242
    return _dec
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   243
        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   244
def has_perm_on_comment(perm_name):    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   245
    """
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   246
    decorator protection checking for perm for logged in user on to comment
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   247
    perm_name: 'virtual' permission name 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   248
    """    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   249
    def _dec(view_func):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   250
        def _check_local_perm(request, *args, **kwargs):
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   251
            if cm_settings.NO_SECURITY:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   252
                return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   253
            
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   254
            if 'key' in kwargs: 
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   255
                text = get_object_or_404(Text, key=kwargs['key'])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   256
                # first try permission on text                
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   257
                if has_perm(request, perm_name, text=text) :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   258
                    return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   259
                if 'comment_key' in kwargs:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   260
                    comment = get_object_or_404(Comment, key=kwargs['comment_key'])
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   261
                    if has_own_perm(request, perm_name + "_own", text, comment) :
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   262
                        return view_func(request, *args, **kwargs)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   263
                else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   264
                    raise Exception('no security check possible: no comment key')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   265
            else:
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   266
                raise Exception('no security check possible: no text key')
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   267
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   268
            raise UnauthorizedException('No perm %s on comment' % perm_name)
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   269
        _check_local_perm.__doc__ = view_func.__doc__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   270
        _check_local_perm.__dict__ = view_func.__dict__
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   271
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   272
        return _check_local_perm
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   273
    return _dec        
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   274
    
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   275
40c8f766c9b8 import from internal svn r 4007
raph
parents:
diff changeset
   276