Browse Source

Shared admin error pages logic #342

Rafał Pitoń 11 years ago
parent
commit
a8d5e36800

+ 1 - 0
misago/admin/auth.py

@@ -4,6 +4,7 @@ from django.conf import settings
 from django.contrib import auth as dj_auth, messages
 from django.utils.translation import ugettext as _
 
+
 KEY_TOKEN = 'misago_admin_session_token'
 KEY_UPDATED = 'misago_admin_session_updated'
 

+ 2 - 3
misago/admin/middleware.py

@@ -1,13 +1,12 @@
 from django.conf import settings
 from misago.admin.auth import is_admin_session, update_admin_session
-from misago.admin.views import get_admin_namespace
+from misago.admin.views import get_protected_namespace
 from misago.admin.views.auth import login
 
 
 class AdminAuthMiddleware(object):
     def process_view(self, request, view_func, view_args, view_kwargs):
-        request.admin_namespace = get_admin_namespace(
-            request.resolver_match.namespace)
+        request.admin_namespace = get_protected_namespace(request)
 
         if request.admin_namespace:
             if not is_admin_session(request):

+ 23 - 2
misago/admin/views/__init__.py

@@ -1,11 +1,15 @@
 from django.conf import settings
+from django.core.urlresolvers import reverse
 from django.shortcuts import render as dj_render
 from misago.admin import site
+from misago.admin.auth import is_admin_session, update_admin_session
+from misago.admin.views.auth import login
 
 
-def get_admin_namespace(requested_namespace):
+def get_protected_namespace(request):
     for namespace in settings.MISAGO_ADMIN_NAMESPACES:
-        if requested_namespace.startswith(namespace):
+        admin_path = reverse('%s:index' % namespace)
+        if request.path.startswith(admin_path):
             return namespace
     else:
         return None
@@ -34,3 +38,20 @@ def render(request, template, context=None):
         })
 
     return dj_render(request, template, context)
+
+
+# Decorator for views
+def protected_admin_view(f):
+    def decorator(request, *args, **kwargs):
+        protected_view = get_protected_namespace(request)
+        if protected_view:
+            if is_admin_session(request):
+                update_admin_session(request)
+                return f(request, *args, **kwargs)
+            else:
+                request.admin_namespace = protected_view
+                return login(request)
+        else:
+            return f(request, *args, **kwargs)
+
+    return decorator

+ 47 - 0
misago/admin/views/errorpages.py

@@ -0,0 +1,47 @@
+from django.shortcuts import render
+from misago.admin.auth import is_admin_session, update_admin_session
+from misago.admin.views import get_protected_namespace, protected_admin_view
+
+
+# Magic error page used by admin
+@protected_admin_view
+def _error_page(request, code, message=None):
+    template_pattern = 'misago/admin/errorpages/%s.html' % code
+
+    response = render(request,
+                      template_pattern,
+                      {'message': message})
+    response.status_code = code
+    return response
+
+
+def admin_error_page(f):
+    def decorator(request, *args, **kwargs):
+        if get_protected_namespace(request):
+            update_admin_session(request)
+            return _error_page(request, *args, **kwargs)
+        else:
+            return f(request, *args, **kwargs)
+    return decorator
+
+
+# Magic CSRF fail page for Admin
+def _csrf_failure(request, reason=""):
+    if is_admin_session(request):
+        update_admin_session(request)
+        response = render(
+            request, 'misago/admin/errorpages/csrf_failure_authenticated.html')
+    else:
+        response = render(request, 'misago/admin/errorpages/csrf_failure.html')
+
+    response.status_code = 403
+    return response
+
+
+def admin_csrf_failure(f):
+    def decorator(request, *args, **kwargs):
+        if get_protected_namespace(request):
+            return _csrf_failure(request, *args, **kwargs)
+        else:
+            return f(request, *args, **kwargs)
+    return decorator

+ 3 - 0
misago/core/errorpages.py

@@ -1,7 +1,9 @@
 from django.shortcuts import render
 from misago.core.utils import is_request_to_misago
+from misago.admin.views.errorpages import admin_error_page, admin_csrf_failure
 
 
+@admin_error_page
 def _error_page(request, code, message=None):
     response = render(request,
                       'misago/errorpages/%s.html' % code,
@@ -18,6 +20,7 @@ def page_not_found(request):
     return _error_page(request, 404)
 
 
+@admin_csrf_failure
 def csrf_failure(request, reason=""):
     response = render(request, 'misago/errorpages/csrf_failure.html')
     response.status_code = 403

+ 1 - 0
misago/templates/misago/admin/errorpages/404.html

@@ -0,0 +1 @@
+Admin 404 placeholder