def process_exception(self, request, exception): from curia.authentication import AccessDeniedException, WrongCommunityException from curia.shortcuts import render_to_response if isinstance(exception, AccessDeniedException): if request.user.is_anonymous(): return HttpResponseRedirect('%s?next=%s' % (self.require_login_path, request.path)) from django.http import HttpResponseForbidden from django.template import loader from django.template import RequestContext return HttpResponseForbidden(loader.render_to_string(context_instance=RequestContext(request), dictionary={'comment': exception.comment}, template_name='403.html'), status=403) elif isinstance(exception, WrongCommunityException): from curia import get_community_of obj = exception.obj obj_community = get_community_of(obj) from django.conf import settings domain = 'http://%s' % obj_community.meta.domain port_marker = request.META['HTTP_HOST'].rfind(':', 5) if port_marker != -1: domain += request.META['HTTP_HOST'][port_marker:] if request.META['QUERY_STRING'] == None: path = '%s%s' % (domain, request.path) else: path = '%s%s?%s' % (domain, request.path, request.META['QUERY_STRING']) return HttpResponseRedirect(path) return None
def get_object_or_404_and_check_access(request, klass, **kwargs): from django.shortcuts import get_object_or_404 command = None if 'command' in kwargs: command = kwargs['command'] del kwargs['command'] obj = get_object_or_404(klass, **kwargs) from curia import get_community_of if get_community_of(obj) != request.community: from curia.authentication import WrongCommunityException raise WrongCommunityException(obj) check_access(request.user, obj, level=2, command=command) return obj
def has_perm(user, obj, command): owner = get_owner(obj) if owner == user: return PermissionResponse(True, 'user always has access on owned objects') from curia.authentication.models import GroupPermission from django.contrib.auth.models import User, Group if get_community_of(obj).meta.created_by == user: return PermissionResponse(True, 'user is creator of current community') if command == 'add': if hasattr(obj, 'deleted') and obj.deleted: return PermissionResponse( True, 'add access is always denied on deleted objects') # translate from function naming convention to django permission naming convention if command == 'edit': command = 'change' if obj == None: obj = user if obj == user and command == 'view': return PermissionResponse(True, u'user can always view himself') if user.is_anonymous(): return has_perm(get_public_user(), obj, command) if user != get_public_user(): p = has_perm(user=get_public_user(), obj=obj, command=command) if p: return p response = has_django_perm(user, obj, command) if response is not None: return response content_type = get_content_type(obj) if user != get_public_user(): response = has_admin_access(user, obj, content_type, command) if response is not None: return response response = has_access_on_object(user, obj, content_type, command) if response is not None: return response response = has_group_access_on_object(user, obj, content_type, command) if response is not None: return response # check content type level access everyone_permissions = get_objects_from(GroupPermission, group=get_everyone_group(), command=command, content_type=content_type, object_id=obj.id) if len(everyone_permissions) != 0: if everyone_permissions[0].deny: return PermissionResponse(False, u'everyone is denied access') else: return PermissionResponse(True, u'everyone is granted access') response = has_access_on_content_type(user, content_type, command) if response is not None: return response response = has_group_access_on_content_type(user, content_type, command) if response is not None: return response if owner != None: # check global access on the owner response = has_perm(user=user, obj=owner, command=command) # ignore access denied here, because we will check defaults and then return access denied later if need be if response: return response # default access levels if obj == user: return PermissionResponse( True, u'user has full access on self unless specifically denied') if command == 'view' or command == 'add': if isinstance(obj, Group): if user in obj.user_set.all(): return PermissionResponse( True, 'everyone has view and add access by default in groups they are part of' ) community = get_current_community() if obj != community and get_community_of(obj) != community: raise WrongCommunityException(obj) if command == 'view' and isinstance(obj, User): if obj in community.user_set.all() and user in community.user_set.all( ): return PermissionResponse( True, u'everyone has view access on a user if they are in a community that the user in question is a member of' ) #if (command == 'change' or command == 'add') and isinstance(obj, Group): # if obj.id in [group.id for group in user.groups.all()]: # return PermissionResponse(True, 'members have change access by default on groups they are a member of') if hasattr(obj, 'has_default_permission'): response = obj.has_default_permission(user, command) if response is not None: return response if ' ' in command: return has_perm(user=user, obj=obj, command=command.split()[0]) return PermissionResponse( False, u'%s has no %s permissions on %s' % (user, command, obj))
def has_perm(user, obj, command): owner = get_owner(obj) if owner == user: return PermissionResponse(True, 'user always has access on owned objects') from curia.authentication.models import GroupPermission from django.contrib.auth.models import User, Group if get_community_of(obj).meta.created_by == user: return PermissionResponse(True, 'user is creator of current community') if command == 'add': if hasattr(obj, 'deleted') and obj.deleted: return PermissionResponse(True, 'add access is always denied on deleted objects') # translate from function naming convention to django permission naming convention if command == 'edit': command = 'change' if obj == None: obj = user if obj == user and command == 'view': return PermissionResponse(True, u'user can always view himself') if user.is_anonymous(): return has_perm(get_public_user(), obj, command) if user != get_public_user(): p = has_perm(user=get_public_user(), obj=obj, command=command) if p: return p response = has_django_perm(user, obj, command) if response is not None: return response content_type = get_content_type(obj) if user != get_public_user(): response = has_admin_access(user, obj, content_type, command) if response is not None: return response response = has_access_on_object(user, obj, content_type, command) if response is not None: return response response = has_group_access_on_object(user, obj, content_type, command) if response is not None: return response # check content type level access everyone_permissions = get_objects_from(GroupPermission, group=get_everyone_group(), command=command, content_type=content_type, object_id=obj.id) if len(everyone_permissions) != 0: if everyone_permissions[0].deny: return PermissionResponse(False, u'everyone is denied access') else: return PermissionResponse(True, u'everyone is granted access') response = has_access_on_content_type(user, content_type, command) if response is not None: return response response = has_group_access_on_content_type(user, content_type, command) if response is not None: return response if owner != None: # check global access on the owner response = has_perm(user=user, obj=owner, command=command) # ignore access denied here, because we will check defaults and then return access denied later if need be if response: return response # default access levels if obj == user: return PermissionResponse(True, u'user has full access on self unless specifically denied') if command == 'view' or command == 'add': if isinstance(obj, Group): if user in obj.user_set.all(): return PermissionResponse(True, 'everyone has view and add access by default in groups they are part of') community = get_current_community() if obj != community and get_community_of(obj) != community: raise WrongCommunityException(obj) if command == 'view' and isinstance(obj, User): if obj in community.user_set.all() and user in community.user_set.all(): return PermissionResponse(True, u'everyone has view access on a user if they are in a community that the user in question is a member of') #if (command == 'change' or command == 'add') and isinstance(obj, Group): # if obj.id in [group.id for group in user.groups.all()]: # return PermissionResponse(True, 'members have change access by default on groups they are a member of') if hasattr(obj, 'has_default_permission'): response = obj.has_default_permission(user, command) if response is not None: return response if ' ' in command: return has_perm(user=user, obj=obj, command=command.split()[0]) return PermissionResponse(False, u'%s has no %s permissions on %s' % (user, command, obj))