From: Raphaël Barrois Date: Sat, 2 Feb 2013 20:32:57 +0000 (+0100) Subject: accounts: Add context_processor and middleware. X-Git-Url: http://git.polytechnique.org/?p=xnet;a=commitdiff_plain;h=97a0ca068cd0ed8d6465411e26a537e2e329d001 accounts: Add context_processor and middleware. Signed-off-by: Raphaël Barrois --- diff --git a/xnet/accounts/context_processors.py b/xnet/accounts/context_processors.py new file mode 100644 index 0000000..770b2a5 --- /dev/null +++ b/xnet/accounts/context_processors.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + + +def xnet(request): + """Returns context variables required by X.net sites.""" + return { + 'group': getattr(request, 'group', None), + 'membership': getattr(request, 'membership', None), + } diff --git a/xnet/accounts/decorators.py b/xnet/accounts/decorators.py index bc29091..ec2a8df 100644 --- a/xnet/accounts/decorators.py +++ b/xnet/accounts/decorators.py @@ -6,7 +6,41 @@ from django.shortcuts import get_object_or_404 from .models import XGroup, Membership +def with_group(view_func): + """Converts a group slug into a XGroup object. + + Example: + >>> @with_group + ... def my_view(request, group, *args, **kwargs): + ... # group is now a XGroup instance + """ + + @functools.wraps(view_func) + def wrapped_view_func(request, group_slug, *args, **kwargs): + group = get_object_or_404(XGroup, short=group_slug) + + request.group = group + + return view_func(request, group, *args, **kwargs) + + return wrapped_view_func + + class group_required(object): + """Force a minimum group membership level. + + Also combines with_group features: + - fetches the XGroup object, + - sets request.group + - sets request.membership + + Usage: + + >>> @group_required(level=Membership.LEVEL_MEMBER) + ... def my_view(request, group, *args, **kwargs): + ... pass + """ + def __init__(self, level=Membership.LEVEL_MEMBER): self.level = level @@ -14,13 +48,21 @@ class group_required(object): @functools.wraps(view_func) def wrapped_view_func(request, group_slug, *args, **kwargs): group = get_object_or_404(XGroup, short=group_slug) - membership = request.user.memberships.filter( - xgroup=group, - level__gte=self.level, - state='enabled', - ) - if membership.exists(): - return view_func(request, group, *args, membership=membership[0], **kwargs) + + try: + membership = request.user.memberships.get( + xgroup=group, + level__gte=self.level, + state='enabled', + ) + except Membership.DoesNotExist: + membership = None + + request.group = group + request.membership = membership + + if membership: + return view_func(request, group, *args, membership=membership, **kwargs) else: return HttpResponseForbidden() return wrapped_view_func diff --git a/xnet/accounts/middleware.py b/xnet/accounts/middleware.py new file mode 100644 index 0000000..5b3e57a --- /dev/null +++ b/xnet/accounts/middleware.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + + +class XnetAccountMiddleware(object): + """Ensures request.group and request.membership are defined.""" + + def process_request(self, request): + request.group = None + request.membership = None diff --git a/xnet/settings.py b/xnet/settings.py index 4260933..a23093c 100644 --- a/xnet/settings.py +++ b/xnet/settings.py @@ -49,6 +49,16 @@ OCALE_PATHS = ( os.path.join(ROOT_DIR, 'locale'), ) +TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.contrib.auth.context_processors.auth', + 'django.core.context_processors.debug', + 'django.core.context_processors.i18n', + 'django.core.context_processors.media', + 'django.core.context_processors.static', + 'django.core.context_processors.tz', + 'django.contrib.messages.context_processors.messages', + 'xnet.accounts.context_processors.xnet', +) SITE_ID = 1 @@ -99,7 +109,7 @@ STATICFILES_FINDERS = ( ) # Make this unique, and don't share it with anybody. -SECRET_KEY = 'iq9w_94mr$p$a3sr%*cnvt8z($-)zjk1o8wx45dw(6z3%(mwzo' +SECRET_KEY = 'FOR DEV ONLY!!' # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( @@ -113,6 +123,7 @@ MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'xnet.accounts.middleware.XnetAccountMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware',