Commits

Chris Beaven committed 284a923

Provide a way to "log out" of the admin preview

Comments (0)

Files changed (4)

     def secret_page(request):
         # ...
 
-The decorator accepts three arguments:
+The decorator accepts four arguments:
 
 ``form``
   The form to use for providing an admin preview, rather than the form
   referenced by ``settings.LOCKDOWN_FORM``. Note that this must be an actual
   form class, not a module reference like the setting. 
 
+``logout_key``
+  A preview logout key to use, rather than the one provided by
+  ``settings.LOCKDOWN_LOGOUT_KEY``.
+
 ``session_key``
   The session key to use, rather than the one provided by
   ``settings.LOCKDOWN_SESSION_KEY``.
 LOCKDOWN_URL_EXCEPTIONS
 -----------------------
 
-Optional: a list/tuple of regular expressions to be matched against
-incoming URLs. If a URL matches a regular expression in this list, it
-will not be locked. For example::
+An optional list/tuple of regular expressions to be matched against incoming
+URLs. If a URL matches a regular expression in this list, it will not be
+locked. For example::
 
     LOCKDOWN_URL_EXCEPTIONS = (
         r'^/about/$',   # unlock /about/
         r'\.json$',   # unlock JSON API
     )
 
+LOCKDOWN_LOGOUT_KEY
+-------------------
+
+A key which, if provided in the querystring of a locked URL, will log out the
+user from the preview. 
+
 LOCKDOWN_FORM
 -------------
 
 
 * Once Django 1.2 ships with signed cookies (hopefully), replace
   contrib.sessions dependency with a signed cookie.
-
-* Provide a way to "log out" of the admin preview.

lockdown/middleware.py

 
 
 class LockdownMiddleware(object):
-    def __init__(self, form=None, session_key=None, url_exceptions=None,
-                 **form_kwargs):
+    def __init__(self, form=None, logout_key=None, session_key=None,
+                 url_exceptions=None, **form_kwargs):
         if form is None:
             form = _default_form
+        if logout_key is None:
+            logout_key = settings.LOGOUT_KEY
         if session_key is None:
             session_key = settings.SESSION_KEY
         if url_exceptions is None:
             url_exceptions = _default_url_exceptions
         self.form = form
         self.form_kwargs = form_kwargs
+        self.logout_key = logout_key
         self.session_key = session_key
         self.url_exceptions = url_exceptions
 
         form_data = request.method == 'POST' and request.POST or None
         form = self.form(data=form_data, **self.form_kwargs)
 
-        # Don't lock down if the user is already authorized for previewing.
+        authorized = False
         token = session.get(self.session_key)
         if hasattr(form, 'authenticate'):
             if form.authenticate(token):
-                return None
+                authorized = True
         elif token is True:
+            authorized = True
+
+        if authorized and self.logout_key and self.logout_key in request.GET:
+            if self.session_key in session:
+                del session[self.session_key]
+            url = request.path
+            querystring = request.GET.copy()
+            del querystring[self.logout_key]
+            if querystring:
+                url = '%s?%s' % (url, querystring.urlencode())
+            return self.redirect(request)
+
+        # Don't lock down if the user is already authorized for previewing.
+        if authorized:
             return None
 
         if form.is_valid():
             else:
                 token = True
             session[self.session_key] = token
-            return HttpResponseRedirect(request.path)
+            return self.redirect(request)
 
         page_data = {}
         if not hasattr(form, 'show_form') or form.show_form():
 
         return render_to_response('lockdown/form.html', page_data,
                                   context_instance=RequestContext(request))
+
+    def redirect(self, request):
+        url = request.path
+        querystring = request.GET.copy()
+        if self.logout_key and self.logout_key in request.GET:
+            del querystring[self.logout_key]
+        if querystring:
+            url = '%s?%s' % (url, querystring.urlencode())
+        return HttpResponseRedirect(url)

lockdown/settings.py

 PASSWORDS = getattr(settings, 'LOCKDOWN_PASSWORDS', ())
 FORM = getattr(settings, 'LOCKDOWN_FORM', 'lockdown.forms.LockdownForm')
 SESSION_KEY = getattr(settings, 'LOCKDOWN_SESSION_KEY', 'lockdown-allow')
+LOGOUT_KEY = getattr(settings, 'LOCKDOWN_LOGOUT_KEY', 'preview-logout')
 
 if not isinstance(PASSWORDS, (tuple, list)):
     PASSWORDS = PASSWORDS and (PASSWORDS,) or ()