Honour LOGIN_URL when redirecting to login page

Currently the redirect is always made to the url of the 'login' view.
This change makes redirects go to LOGIN_URL, so the default login view
can be replaced with a view at another url/name.

Fixes bug 1079444.

Change-Id: Ib56200679668dd053d3c6ac24807d2a2affc0df8
This commit is contained in:
Kieran Spear 2012-11-16 17:20:51 +11:00
parent 0e328995ec
commit 3fbe68f690
3 changed files with 48 additions and 10 deletions

View File

@ -26,8 +26,10 @@ import logging
from django import http
from django import shortcuts
from django.conf import settings
from django.contrib import messages as django_messages
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.views import redirect_to_login
from django.core.urlresolvers import reverse
from django.utils import timezone
from django.utils.encoding import iri_to_uri
@ -59,20 +61,23 @@ class HorizonMiddleware(object):
"""
if isinstance(exception, (exceptions.NotAuthorized,
exceptions.NotAuthenticated)):
auth_url = reverse("login")
auth_url = settings.LOGIN_URL
next_url = iri_to_uri(request.get_full_path())
if next_url != auth_url:
param = "?%s=%s" % (REDIRECT_FIELD_NAME, next_url)
redirect_to = "".join((auth_url, param))
field_name = REDIRECT_FIELD_NAME
else:
redirect_to = auth_url
field_name = None
login_url = request.build_absolute_uri(auth_url)
response = redirect_to_login(next_url, login_url=login_url,
redirect_field_name=field_name)
# TODO(gabriel): Find a way to display an appropriate message to
# the user *on* the login form...
if request.is_ajax():
response_401 = http.HttpResponse(status=401)
response_401['X-Horizon-Location'] = redirect_to
response_401['X-Horizon-Location'] = response['location']
return response_401
return shortcuts.redirect(redirect_to)
return response
# If an internal "NotFound" error gets this far, return a real 404.
if isinstance(exception, exceptions.NotFound):

View File

@ -226,7 +226,7 @@ class HorizonTests(BaseHorizonTests):
self.client.logout()
resp = self.client.get(url)
redirect_url = "?".join([urlresolvers.reverse("login"),
redirect_url = "?".join(['http://testserver' + settings.LOGIN_URL,
"next=%s" % url])
self.assertRedirects(resp, redirect_url)
@ -235,8 +235,7 @@ class HorizonTests(BaseHorizonTests):
# Response should be HTTP 401 with redirect header
self.assertEquals(resp.status_code, 401)
self.assertEquals(resp["X-Horizon-Location"],
"?".join([urlresolvers.reverse("login"),
"next=%s" % url]))
redirect_url)
def test_required_permissions(self):
dash = horizon.get_dashboard("cats")
@ -275,7 +274,7 @@ class HorizonTests(BaseHorizonTests):
dogs = horizon.get_dashboard("dogs")
puppies = dogs.get_panel("puppies")
url = puppies.get_absolute_url()
redirect_url = "?".join([urlresolvers.reverse("login"),
redirect_url = "?".join([settings.LOGIN_URL,
"next=%s" % url])
self.client.logout()

View File

@ -0,0 +1,34 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 OpenStack LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from django.conf import settings
from horizon import exceptions
from horizon import middleware
from horizon.test import helpers as test
class MiddlewareTests(test.TestCase):
def test_redirect_login_fail_to_login(self):
url = settings.LOGIN_URL
request = self.factory.post(url)
mw = middleware.HorizonMiddleware()
resp = mw.process_exception(request, exceptions.NotAuthorized())
resp.client = self.client
self.assertRedirects(resp, url)