Move xnet/accounts to xnet/groups
[xnet] / xnet / groups / decorators.py
diff --git a/xnet/groups/decorators.py b/xnet/groups/decorators.py
new file mode 100644 (file)
index 0000000..4e94ef2
--- /dev/null
@@ -0,0 +1,70 @@
+import functools
+
+from django.http import HttpResponseForbidden
+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
+
+    def __call__(self, view_func):
+        @functools.wraps(view_func)
+        def wrapped_view_func(request, group_slug, *args, **kwargs):
+            group = get_object_or_404(XGroup, short=group_slug)
+            if not request.user.is_authenticated():
+                return HttpResponseForbidden()
+
+            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