Login/Logout redirects with Django variables

The login/logout url patterns now use
the Django LOGIN_URL and LOGOUT_URL

The default redirect url after a successful login
now uses as default the Django LOGIN_REDIRECT_URL
with possible override using HORIZON_CONFIG.user_home
in settings file. There are 3 cases:

* no user_home in settings.HORIZON_CONFIG - uses
Django LOGIN_REDIRECT_URL
* user_home = None in settings.HORIZON_CONFIG -
will default to the primary dashboard(the current
fall-back behavior)
* user_home = 'something' - it will be used to
determine the actual redirect url

Fixes bug 980434

Patch Set 2:
Restored the previous behavior - splash page('/')
redirects to /nova or /syspanel, depending on the user,
while /home/ will redirect to the 'user_home' setting
(or LOGIN_REDIRECT_URL if user_home is not set).
The same logic will be applied after user logs in.

Change-Id: I28e25566199393382639da9ca2022d1850f25a94
This commit is contained in:
Tihomir Trifonov 2012-06-20 00:05:08 +03:00
parent 6174eae5ae
commit f0fe2029f3
5 changed files with 37 additions and 9 deletions

View File

@ -52,7 +52,8 @@ HORIZON_CONFIG = {
'dashboards': None,
# Name of a default dashboard; defaults to first alphabetically if None
'default_dashboard': None,
'user_home': None,
# Default redirect url for users' home
'user_home': settings.LOGIN_REDIRECT_URL,
'exceptions': {'unauthorized': [],
'not_found': [],
'recoverable': []}
@ -700,9 +701,11 @@ class Site(Registry, HorizonComponent):
{"user_home": "/home",} # A URL
{"user_home": "my_module.get_user_home",} # Path to a function
{"user_home": lambda user: "/" + user.name,} # A function
{"user_home": None,} # Will always return the default dashboard
This can be useful if the default dashboard may not be accessible
to all users.
to all users. When user_home is missing from HORIZON_CONFIG,
it will default to the settings.LOGIN_REDIRECT_URL value.
"""
user_home = self._conf['user_home']
if user_home:

View File

@ -19,14 +19,17 @@
# under the License.
from django.conf.urls.defaults import patterns, url, include
from django.conf import settings
from horizon.views.auth import LoginView
urlpatterns = patterns('horizon.views.auth',
url(r'home/$', 'user_home', name='user_home'),
url(r'auth/login/$', LoginView.as_view(), name='auth_login'),
url(r'auth/logout/$', 'logout', name='auth_logout'),
url(r"^%s$" % settings.LOGIN_URL.lstrip('/'), LoginView.as_view(),
name='auth_login'),
url(r"^%s$" % settings.LOGOUT_URL.lstrip('/'), 'logout',
name='auth_logout'),
url(r'auth/switch/(?P<tenant_id>[^/]+)/$', 'switch_tenants',
name='auth_switch'))

View File

@ -21,6 +21,7 @@
import time
from django import http
from django.conf import settings
from django.core.urlresolvers import reverse
from keystoneclient import exceptions as keystone_exceptions
from mox import IsA
@ -72,19 +73,25 @@ class AuthViewTests(test.TestCase):
self.assertTemplateUsed(res, 'horizon/auth/login.html')
@test.create_stubs({api: ('token_create', 'tenant_list_for_token',
'token_create_scoped')})
def test_login(self):
form_data = {'method': 'Login',
'region': 'http://localhost:5000/v2.0',
'password': self.user.password,
'username': self.user.name}
self.mox.StubOutWithMock(api, 'token_create')
self.mox.StubOutWithMock(api, 'tenant_list_for_token')
self.mox.StubOutWithMock(api, 'token_create_scoped')
aToken = self.tokens.unscoped_token
bToken = self.tokens.scoped_token
api.token_create(IsA(http.HttpRequest), "", self.user.name,
self.user.password).AndReturn(aToken)
api.tenant_list_for_token(IsA(http.HttpRequest),
aToken.id).AndReturn([self.tenants.first()])
api.token_create_scoped(IsA(http.HttpRequest),
self.tenant.id,
aToken.id).AndReturn(bToken)
api.token_create(IsA(http.HttpRequest), "", self.user.name,
self.user.password).AndReturn(aToken)
api.tenant_list_for_token(IsA(http.HttpRequest),
@ -98,6 +105,12 @@ class AuthViewTests(test.TestCase):
res = self.client.post(reverse('horizon:auth_login'), form_data)
self.assertRedirectsNoFollow(res, DASH_INDEX_URL)
# Test default Django LOGIN_REDIRECT_URL
user_home = settings.HORIZON_CONFIG.pop('user_home')
res = self.client.post(reverse('horizon:auth_login'), form_data)
self.assertRedirectsNoFollow(res, settings.LOGIN_REDIRECT_URL)
settings.HORIZON_CONFIG['user_home'] = user_home
def test_login_first_tenant_invalid(self):
form_data = {'method': 'Login',
'region': 'http://localhost:5000/v2.0',

View File

@ -25,6 +25,10 @@ from django.utils.translation import ugettext_lazy as _
socket.setdefaulttimeout(1)
LOGIN_URL = '/auth/login/'
LOGOUT_URL = '/auth/logout/'
LOGIN_REDIRECT_URL = '/'
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
DEBUG = True
TESTSERVER = 'http://testserver'
@ -101,6 +105,7 @@ HORIZON_CONFIG = {
"regex": '^.{8,18}$',
"help_text": _("Password must be between 8 and 18 characters.")
},
'user_home': None
}
AVAILABLE_REGIONS = [

View File

@ -34,7 +34,11 @@ TEMPLATE_DEBUG = DEBUG
SITE_ID = 1
SITE_BRANDING = 'OpenStack'
LOGIN_URL = '/auth/login'
LOGIN_URL = '/auth/login/'
LOGOUT_URL = '/auth/logout/'
# LOGIN_REDIRECT_URL can be used as an alternative for
# HORIZON_CONFIG.user_home, if user_home is not set.
# Do not set it to '/home/', as this will cause circular redirect loop
LOGIN_REDIRECT_URL = '/'
MEDIA_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '..', 'media'))