From 1b579a7e4518303cb3a98563b44e66367d7f667f Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 12 Sep 2014 21:51:50 +0200 Subject: [PATCH] Basic permission logic --- src/tixl/settings.py | 2 +- src/tixlcontrol/context.py | 4 +- src/tixlcontrol/middleware.py | 55 ++++++++++++------- .../templates/tixlcontrol/events/index.html | 2 +- src/tixlcontrol/urls.py | 1 + src/tixlcontrol/views/event.py | 5 ++ 6 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 src/tixlcontrol/views/event.py diff --git a/src/tixl/settings.py b/src/tixl/settings.py index 4926aa5a6..56647f277 100644 --- a/src/tixl/settings.py +++ b/src/tixl/settings.py @@ -52,7 +52,7 @@ MIDDLEWARE_CLASSES = ( 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'tixlcontrol.middleware.LoginRequiredMiddleware', + 'tixlcontrol.middleware.PermissionMiddleware', ) TEMPLATE_CONTEXT_PROCESSORS = ( diff --git a/src/tixlcontrol/context.py b/src/tixlcontrol/context.py index ef43dd429..3970ac98d 100644 --- a/src/tixlcontrol/context.py +++ b/src/tixlcontrol/context.py @@ -3,7 +3,9 @@ from django.core.urlresolvers import resolve def contextprocessor(request): - return { + ctx = { 'url_name': resolve(request.path_info).url_name, 'settings': settings, } + + return ctx diff --git a/src/tixlcontrol/middleware.py b/src/tixlcontrol/middleware.py index 63a97f89e..d7e73751c 100644 --- a/src/tixlcontrol/middleware.py +++ b/src/tixlcontrol/middleware.py @@ -4,13 +4,18 @@ from django.utils.encoding import force_str from django.utils.six.moves.urllib.parse import urlparse from django.shortcuts import resolve_url from django.contrib.auth import REDIRECT_FIELD_NAME +from django.http import HttpResponseNotFound + +from tixlbase.models import Event -class LoginRequiredMiddleware: +class PermissionMiddleware: """ This middleware enforces all requests to the control app to require login. + Additionally, it enforces all requests to "control:event." URLs + to be for an event the user has basic access to. """ EXCEPTIONS = ( @@ -18,22 +23,34 @@ class LoginRequiredMiddleware: ) def process_request(self, request): + url = resolve(request.path_info) + url_namespace = url.namespace + url_name = url.url_name + if url_namespace != 'control' or url_name in self.EXCEPTIONS: + return if not request.user.is_authenticated(): - url_namespace = resolve(request.path_info).namespace - url_name = resolve(request.path_info).url_name - if url_namespace == 'control' and url_name not in self.EXCEPTIONS: - # Taken from django/contrib/auth/decorators.py - path = request.build_absolute_uri() - # urlparse chokes on lazy objects in Python 3, force to str - resolved_login_url = force_str( - resolve_url(settings.LOGIN_URL_CONTROL)) - # If the login url is the same scheme and net location then just - # use the path as the "next" url. - login_scheme, login_netloc = urlparse(resolved_login_url)[:2] - current_scheme, current_netloc = urlparse(path)[:2] - if ((not login_scheme or login_scheme == current_scheme) and - (not login_netloc or login_netloc == current_netloc)): - path = request.get_full_path() - from django.contrib.auth.views import redirect_to_login - return redirect_to_login( - path, resolved_login_url, REDIRECT_FIELD_NAME) + # Taken from django/contrib/auth/decorators.py + path = request.build_absolute_uri() + # urlparse chokes on lazy objects in Python 3, force to str + resolved_login_url = force_str( + resolve_url(settings.LOGIN_URL_CONTROL)) + # If the login url is the same scheme and net location then just + # use the path as the "next" url. + login_scheme, login_netloc = urlparse(resolved_login_url)[:2] + current_scheme, current_netloc = urlparse(path)[:2] + if ((not login_scheme or login_scheme == current_scheme) and + (not login_netloc or login_netloc == current_netloc)): + path = request.get_full_path() + from django.contrib.auth.views import redirect_to_login + return redirect_to_login( + path, resolved_login_url, REDIRECT_FIELD_NAME) + + if 'event.' in url_name and 'event' in url.kwargs: + try: + request.event = Event.objects.get( + slug=url.kwargs['event'], + permitted__id__exact=request.user.id + ) + except: + return HttpResponseNotFound(_("The selected event was not found or you have no permission to administrate it.")) + diff --git a/src/tixlcontrol/templates/tixlcontrol/events/index.html b/src/tixlcontrol/templates/tixlcontrol/events/index.html index 6444def95..1785f164b 100644 --- a/src/tixlcontrol/templates/tixlcontrol/events/index.html +++ b/src/tixlcontrol/templates/tixlcontrol/events/index.html @@ -16,7 +16,7 @@ {% for e in events %} - {{ e.name }} + {{ e.name }} {{ e.organizer }} {{ e.get_date_from_display }} {{ e.get_date_to_display }} diff --git a/src/tixlcontrol/urls.py b/src/tixlcontrol/urls.py index 9a7809908..d0bf690f0 100644 --- a/src/tixlcontrol/urls.py +++ b/src/tixlcontrol/urls.py @@ -3,6 +3,7 @@ from tixlcontrol.views import main urlpatterns = patterns('', url(r'^$', 'tixlcontrol.views.main.index', name='index'), + url(r'^event/(?P\w+)/$', 'tixlcontrol.views.event.index', name='event.index'), url(r'^events/$', main.EventList.as_view(), name='events'), url(r'^logout$', 'tixlcontrol.views.auth.logout', name='auth.logout'), url(r'^login$', 'tixlcontrol.views.auth.login', name='auth.login'), diff --git a/src/tixlcontrol/views/event.py b/src/tixlcontrol/views/event.py new file mode 100644 index 000000000..a2b104e5e --- /dev/null +++ b/src/tixlcontrol/views/event.py @@ -0,0 +1,5 @@ +from django.shortcuts import render + + +def index(request, event): + pass