Fixed a variable being clobbered in the auth_forms handler.

Adds some new test data and a regression test for this bug.

Fixes bug 953806.

Change-Id: I1873e7f2cf0ce4431a6f6fb0ad7b0ef0cbd34334
This commit is contained in:
Gabriel Hurley 2012-03-18 17:24:23 -07:00
parent 8ea84225c3
commit f59ecbef78
5 changed files with 55 additions and 16 deletions

View File

@ -86,7 +86,7 @@ class AuthViewTests(test.TestCase):
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.list())
aToken.id).AndReturn([self.tenants.first()])
api.token_create_scoped(IsA(http.HttpRequest),
self.tenant.id,
aToken.id).AndReturn(bToken)
@ -96,6 +96,40 @@ class AuthViewTests(test.TestCase):
res = self.client.post(reverse('horizon:auth_login'), form_data)
self.assertRedirectsNoFollow(res, DASH_INDEX_URL)
def test_login_first_tenant_invalid(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
disabled_tenant = self.tenants.get(name="disabled_tenant")
tenant = self.tenants.get(name="test_tenant")
tenants = [tenant, disabled_tenant]
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(tenants)
exc = keystone_exceptions.Unauthorized("Not authorized.")
api.token_create_scoped(IsA(http.HttpRequest),
disabled_tenant.id,
aToken.id).AndRaise(exc)
api.token_create_scoped(IsA(http.HttpRequest),
tenant.id,
aToken.id).AndReturn(bToken)
self.mox.ReplayAll()
res = self.client.post(reverse('horizon:auth_login'), form_data)
self.assertNoFormErrors(res)
self.assertNoMessages()
self.assertRedirectsNoFollow(res, DASH_INDEX_URL)
def test_login_invalid_credentials(self):
self.mox.StubOutWithMock(api, 'token_create')
unauthorized = keystone_exceptions.Unauthorized("Invalid")

View File

@ -58,6 +58,4 @@ class ContextProcessorTests(test.TestCase):
self.request.horizon['dashboard'] = ProjectDash
self.assertTrue(self.request.user.is_authenticated())
context = context_processors.horizon(self.request)
self.assertEqual(len(context['authorized_tenants']), 1)
tenant = context['authorized_tenants'].pop()
self.assertEqual(tenant.id, self.tenant.id)
self.assertItemsEqual(context['authorized_tenants'], tenant_list)

View File

@ -117,8 +117,13 @@ def data(TEST):
'name': 'test_tenant',
'description': "a test tenant.",
'enabled': True}
tenant_dict_2 = {'id': "2",
'name': 'disabled_tenant',
'description': "a disabled test tenant.",
'enabled': False}
tenant = tenants.Tenant(tenants.TenantManager, tenant_dict)
TEST.tenants.add(tenant)
disabled_tenant = tenants.Tenant(tenants.TenantManager, tenant_dict_2)
TEST.tenants.add(tenant, disabled_tenant)
TEST.tenant = tenant # Your "current" tenant
scoped_token = tokens.Token(tokens.TokenManager,

View File

@ -67,6 +67,7 @@ SITE_NAME = 'openstack'
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
NOSE_ARGS = ['--nocapture',
'--nologcapture',
'--cover-package=horizon',
'--cover-inclusive']
# For nose-selenium integration

View File

@ -94,8 +94,9 @@ class Login(forms.SelfHandlingForm):
data['password'])
tenants = api.tenant_list_for_token(request, token.id)
except:
msg = _('Unable to authenticate for that project.')
exceptions.handle(request,
message=_('Unable to authenticate tenant.'),
message=msg,
escalate=True)
_set_session_data(request, token)
user = users.get_user_from_request(request)
@ -104,10 +105,10 @@ class Login(forms.SelfHandlingForm):
elif data.get('username', None):
try:
token = api.token_create(request,
'',
data['username'],
data['password'])
unscoped_token = api.token_create(request,
'',
data['username'],
data['password'])
except keystone_exceptions.Unauthorized:
exceptions.handle(request,
_('Invalid user name or password.'))
@ -122,13 +123,13 @@ class Login(forms.SelfHandlingForm):
escalate=True)
# Unscoped token
request.session['unscoped_token'] = token.id
request.session['unscoped_token'] = unscoped_token.id
request.user.username = data['username']
# Get the tenant list, and log in using first tenant
# FIXME (anthony): add tenant chooser here?
try:
tenants = api.tenant_list_for_token(request, token.id)
tenants = api.tenant_list_for_token(request, unscoped_token.id)
except:
exceptions.handle(request)
tenants = []
@ -136,7 +137,7 @@ class Login(forms.SelfHandlingForm):
# Abort if there are no valid tenants for this user
if not tenants:
messages.error(request,
_('No tenants present for user: %(user)s') %
_('You are not authorized for any projects.') %
{"user": data['username']},
extra_tags="login")
return
@ -151,16 +152,16 @@ class Login(forms.SelfHandlingForm):
try:
token = api.token_create_scoped(request,
tenant.id,
token.id)
unscoped_token.id)
break
except:
# This will continue for recognized "unauthorized"
# This will continue for recognized Unauthorized
# exceptions from keystoneclient.
exceptions.handle(request, ignore=True)
token = None
if token is None:
raise exceptions.NotAuthorized(
_("You are not authorized for any available tenants."))
_("You are not authorized for any available projects."))
_set_session_data(request, token)
user = users.get_user_from_request(request)