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_no_tenants(self): TOKEN_ID = 1 form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.PASSWORD, 'username': self.TEST_USER} self.mox.StubOutWithMock(api, 'token_create') class FakeToken(object): id = TOKEN_ID, user = {'roles': [{'name': 'fake'}]}, serviceCatalog = {} aToken = api.Token(FakeToken()) api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndReturn(aToken) self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id).\ AndReturn([]) self.mox.StubOutWithMock(messages, 'error') messages.error(IsA(http.HttpRequest), IsA(unicode), extra_tags=IsA(str)) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'horizon/auth/login.html')
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) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL)
def test_login(self): form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.user.password, 'username': self.user.name} 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), aToken.id).AndReturn([self.tenants.first()]) api.token_create_scoped(IsA(http.HttpRequest), self.tenant.id, aToken.id).AndReturn(bToken) self.mox.ReplayAll() 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(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.list()) api.token_create_scoped(IsA(http.HttpRequest), self.tenant.id, aToken.id).AndReturn(bToken) self.mox.ReplayAll() 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.") exc.silence_logging = True 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(self): form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.PASSWORD, 'username': self.TEST_USER} self.mox.StubOutWithMock(api, 'token_create') self.mox.StubOutWithMock(api, 'tenant_list_for_token') self.mox.StubOutWithMock(api, 'token_create_scoped') class FakeToken(object): id = 1, user = {"id": "1", "roles": [{"id": "1", "name": "fake"}], "name": "user"} serviceCatalog = {} tenant = None aToken = api.Token(FakeToken()) bToken = aToken bToken.tenant = {'id': self.tenant.id, 'name': self.tenant.name} api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndReturn(aToken) api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id).AndReturn(self.tenants) api.token_create_scoped(IsA(http.HttpRequest), self.tenant.id, aToken.id).AndReturn(bToken) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL)
def handle(self, request, data): try: if data.get("tenant", None): token = api.token_create(request, data.get("tenant"), data["username"], data["password"]) tenants = api.tenant_list_for_token(request, token.id) tenant = None for t in tenants: if t.id == data.get("tenant"): tenant = t _set_session_data(request, token) user = users.get_user_from_request(request) return shortcuts.redirect(base.Horizon.get_user_home(user)) elif data.get("username", None): token = api.token_create(request, "", data["username"], data["password"]) # Unscoped token request.session["unscoped_token"] = token.id request.user.username = data["username"] # Get the tenant list, and log in using first tenant # FIXME (anthony): add tenant chooser here? tenants = api.tenant_list_for_token(request, token.id) # Abort if there are no valid tenants for this user if not tenants: messages.error(request, _("No tenants present for user: %(user)s") % {"user": data["username"]}) return # Create a token. # NOTE(gabriel): Keystone can return tenants that you're # authorized to administer but not to log into as a user, so in # the case of an Unauthorized error we should iterate through # the tenants until one succeeds or we've failed them all. while tenants: tenant = tenants.pop() try: token = api.token_create_scoped(request, tenant.id, token.id) break except api_exceptions.Unauthorized as e: token = None if token is None: raise exceptions.NotAuthorized(_("You are not authorized for any available tenants.")) _set_session_data(request, token) user = users.get_user_from_request(request) return shortcuts.redirect(base.Horizon.get_user_home(user)) except api_exceptions.Unauthorized as e: msg = _("Error authenticating: %s") % e.message LOG.exception(msg) messages.error(request, msg) except api_exceptions.ApiException as e: messages.error(request, _("Error authenticating with keystone: %s") % e.message)
def test_switch_tenants(self): NEW_TENANT_ID = '6' NEW_TENANT_NAME = 'FAKENAME' TOKEN_ID = 1 tenants = self.TEST_CONTEXT['authorized_tenants'] aTenant = self.mox.CreateMock(api.Token) aTenant.id = NEW_TENANT_ID aTenant.name = NEW_TENANT_NAME aToken = self.mox.CreateMock(api.Token) aToken.id = TOKEN_ID aToken.user = { 'id': self.TEST_USER_ID, 'name': self.TEST_USER, 'roles': [{ 'name': 'fake' }] } aToken.serviceCatalog = {} aToken.tenant = {'id': aTenant.id, 'name': aTenant.name} self.setActiveUser(id=self.TEST_USER_ID, token=self.TEST_TOKEN, username=self.TEST_USER, tenant_id=self.TEST_TENANT, service_catalog=self.TEST_SERVICE_CATALOG, authorized_tenants=tenants) self.mox.StubOutWithMock(api, 'token_create') self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.token_create(IsA(http.HttpRequest), NEW_TENANT_ID, self.TEST_USER, self.PASSWORD).AndReturn(aToken) api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id) \ .AndReturn([aTenant]) self.mox.ReplayAll() form_data = { 'method': 'LoginWithTenant', 'region': 'http://localhost:5000/v2.0,local', 'password': self.PASSWORD, 'tenant': NEW_TENANT_ID, 'username': self.TEST_USER } res = self.client.post( reverse('horizon:auth_switch', args=[NEW_TENANT_ID]), form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL) self.assertEqual(self.client.session['tenant'], NEW_TENANT_NAME)
def test_login(self): NEW_TENANT_ID = '6' NEW_TENANT_NAME = 'FAKENAME' TOKEN_ID = 1 form_data = { 'method': 'Login', 'password': self.PASSWORD, 'username': self.TEST_USER } self.mox.StubOutWithMock(api, 'token_create') class FakeToken(object): id = TOKEN_ID, user = { "id": "1", "roles": [{ "id": "1", "name": "fake" }], "name": "user" } serviceCatalog = {} tenant = None aToken = api.Token(FakeToken()) bToken = aToken api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndReturn(aToken) aTenant = self.mox.CreateMock(api.Token) aTenant.id = NEW_TENANT_ID aTenant.name = NEW_TENANT_NAME bToken.tenant = {'id': aTenant.id, 'name': aTenant.name} self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id).\ AndReturn([aTenant]) self.mox.StubOutWithMock(api, 'token_create_scoped') api.token_create_scoped(IsA(http.HttpRequest), aTenant.id, aToken.id).AndReturn(bToken) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL)
def test_session_fixation(self): session_ids = [] 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), aToken.id).AndReturn([self.tenants.first()]) api.token_create_scoped(IsA(http.HttpRequest), self.tenant.id, aToken.id).AndReturn(bToken) self.mox.ReplayAll() res = self.client.get(reverse('horizon:auth_login')) self.assertEqual(res.cookies.get('sessionid'), None) res = self.client.post(reverse('horizon:auth_login'), form_data) session_ids.append(res.cookies['sessionid'].value) self.assertEquals(self.client.session['user_name'], self.user.name) self.client.session['foobar'] = 'MY TEST VALUE' res = self.client.get(reverse('horizon:auth_logout')) session_ids.append(res.cookies['sessionid'].value) self.assertEqual(len(self.client.session.items()), 0) # Sleep for 1 second so the session values are different if # using the signed_cookies backend. time.sleep(1) res = self.client.post(reverse('horizon:auth_login'), form_data) session_ids.append(res.cookies['sessionid'].value) # Make sure all 3 session id values are different self.assertEqual(len(session_ids), len(set(session_ids)))
def test_login_invalid_credentials(self): form_data = {'method': 'Login', 'password': self.PASSWORD, 'username': self.TEST_USER} self.mox.StubOutWithMock(api, 'token_create') unauthorized = api_exceptions.Unauthorized('unauth', message='unauth') api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndRaise(unauthorized) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'splash.html')
def test_session_fixation(self): session_ids = [] 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), aToken.id).AndReturn([self.tenants.first()]) api.token_create_scoped(IsA(http.HttpRequest), self.tenant.id, aToken.id).AndReturn(bToken) self.mox.ReplayAll() res = self.client.get(reverse('horizon:auth_login')) self.assertEqual(res.cookies.get('sessionid'), None) res = self.client.post(reverse('horizon:auth_login'), form_data) session_ids.append(res.cookies['sessionid'].value) self.assertEquals(self.client.session['user_name'], self.user.name) self.client.session['foobar'] = 'MY TEST VALUE' res = self.client.get(reverse('horizon:auth_logout')) session_ids.append(res.cookies['sessionid'].value) self.assertEqual(len(self.client.session.items()), 0) # Sleep for 1 second so the session values are different if # using the signed_cookies backend. time.sleep(1) res = self.client.post(reverse('horizon:auth_login'), form_data) session_ids.append(res.cookies['sessionid'].value) # Make sure all 3 session id values are different self.assertEqual(len(session_ids), len(set(session_ids)))
def test_login_exception(self): self.mox.StubOutWithMock(api, 'token_create') api.token_create(IsA(http.HttpRequest), "", self.user.name, self.user.password).AndRaise(self.exceptions.keystone) self.mox.ReplayAll() form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.user.password, 'username': self.user.name} res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'horizon/auth/login.html')
def test_login_exception(self): self.mox.StubOutWithMock(api, 'token_create') api.token_create(IsA(http.HttpRequest), "", self.user.name, self.user.password).AndRaise(self.exceptions.keystone) self.mox.ReplayAll() form_data = { 'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.user.password, 'username': self.user.name } res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'horizon/auth/login.html')
def test_login_exception(self): self.mox.StubOutWithMock(api, 'token_create') ex = keystone_exceptions.BadRequest('Cannot talk to keystone') api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndRaise(ex) self.mox.ReplayAll() form_data = { 'method': 'Login', 'region': 'http://localhost:5000/v2.0,local', 'password': self.PASSWORD, 'username': self.TEST_USER } res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'splash.html')
def test_login_invalid_credentials(self): self.mox.StubOutWithMock(api, 'token_create') unauthorized = keystone_exceptions.Unauthorized("Invalid") api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndRaise(unauthorized) self.mox.ReplayAll() form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.PASSWORD, 'username': self.TEST_USER} res = self.client.post(reverse('horizon:auth_login'), form_data, follow=True) self.assertTemplateUsed(res, 'horizon/auth/login.html')
def test_login_exception(self): self.mox.StubOutWithMock(api, 'token_create') ex = keystone_exceptions.BadRequest('Cannot talk to keystone') api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndRaise(ex) self.mox.ReplayAll() form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.PASSWORD, 'username': self.TEST_USER} res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'horizon/auth/login.html')
def test_switch_tenants(self): NEW_TENANT_ID = '6' NEW_TENANT_NAME = 'FAKENAME' TOKEN_ID = 1 tenants = self.TEST_CONTEXT['authorized_tenants'] aTenant = self.mox.CreateMock(api.Token) aTenant.id = NEW_TENANT_ID aTenant.name = NEW_TENANT_NAME aToken = self.mox.CreateMock(api.Token) aToken.id = TOKEN_ID aToken.user = {'id': self.TEST_USER_ID, 'name': self.TEST_USER, 'roles': [{'name': 'fake'}]} aToken.serviceCatalog = {} aToken.tenant = {'id': aTenant.id, 'name': aTenant.name} self.setActiveUser(id=self.TEST_USER_ID, token=self.TEST_TOKEN, username=self.TEST_USER, tenant_id=self.TEST_TENANT, service_catalog=self.TEST_SERVICE_CATALOG, authorized_tenants=tenants) self.mox.StubOutWithMock(api, 'token_create') self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.token_create(IsA(http.HttpRequest), NEW_TENANT_ID, self.TEST_USER, self.PASSWORD).AndReturn(aToken) api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id) \ .AndReturn([aTenant]) self.mox.ReplayAll() form_data = {'method': 'LoginWithTenant', 'region': 'http://localhost:5000/v2.0', 'password': self.PASSWORD, 'tenant': NEW_TENANT_ID, 'username': self.TEST_USER} res = self.client.post(reverse('horizon:auth_switch', args=[NEW_TENANT_ID]), form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL) self.assertEqual(self.client.session['tenant'], NEW_TENANT_NAME)
def test_login_invalid_credentials(self): self.mox.StubOutWithMock(api, 'token_create') unauthorized = keystone_exceptions.Unauthorized("Invalid") api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndRaise(unauthorized) self.mox.ReplayAll() form_data = { 'method': 'Login', 'region': 'http://localhost:5000/v2.0,local', 'password': self.PASSWORD, 'username': self.TEST_USER } res = self.client.post(reverse('horizon:auth_login'), form_data, follow=True) self.assertTemplateUsed(res, 'splash.html')
def test_login(self): NEW_TENANT_ID = '6' NEW_TENANT_NAME = 'FAKENAME' TOKEN_ID = 1 form_data = {'method': 'Login', 'password': self.PASSWORD, 'username': self.TEST_USER} self.mox.StubOutWithMock(api, 'token_create') class FakeToken(object): id = TOKEN_ID, user = {"id": "1", "roles": [{"id": "1", "name": "fake"}], "name": "user"} serviceCatalog = {} tenant = None aToken = api.Token(FakeToken()) bToken = aToken api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndReturn(aToken) aTenant = self.mox.CreateMock(api.Token) aTenant.id = NEW_TENANT_ID aTenant.name = NEW_TENANT_NAME bToken.tenant = {'id': aTenant.id, 'name': aTenant.name} self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id).\ AndReturn([aTenant]) self.mox.StubOutWithMock(api, 'token_create_scoped') api.token_create_scoped(IsA(http.HttpRequest), aTenant.id, aToken.id).AndReturn(bToken) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL) self.mox.VerifyAll()
def test_login_no_tenants(self): aToken = self.tokens.first() self.mox.StubOutWithMock(api, 'token_create') self.mox.StubOutWithMock(api, 'tenant_list_for_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.mox.ReplayAll() form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.user.password, 'username': self.user.name} res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'horizon/auth/login.html')
def test_login_no_tenants(self): NEW_TENANT_ID = '6' NEW_TENANT_NAME = 'FAKENAME' TOKEN_ID = 1 form_data = { 'method': 'Login', 'region': 'http://localhost:5000/v2.0,local', 'password': self.PASSWORD, 'username': self.TEST_USER } self.mox.StubOutWithMock(api, 'token_create') class FakeToken(object): id = TOKEN_ID, user = {'roles': [{'name': 'fake'}]}, serviceCatalog = {} aToken = api.Token(FakeToken()) api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndReturn(aToken) aTenant = self.mox.CreateMock(api.Token) aTenant.id = NEW_TENANT_ID aTenant.name = NEW_TENANT_NAME self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id).\ AndReturn([]) self.mox.StubOutWithMock(messages, 'error') messages.error(IsA(http.HttpRequest), IsA(unicode), extra_tags=IsA(str)) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'splash.html')
def test_login_invalid_credentials(self): self.mox.StubOutWithMock(api, 'token_create') unauthorized = keystone_exceptions.Unauthorized("Invalid") unauthorized.silence_logging = True api.token_create(IsA(http.HttpRequest), "", self.user.name, self.user.password).AndRaise(unauthorized) self.mox.ReplayAll() form_data = {'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.user.password, 'username': self.user.name} res = self.client.post(reverse('horizon:auth_login'), form_data, follow=True) self.assertTemplateUsed(res, 'horizon/auth/login.html') # Verify that API error messages are rendered, but not using the # messages framework. self.assertContains(res, "Invalid user name or password.") self.assertNotContains(res, 'class="messages"')
def test_login_no_tenants(self): aToken = self.tokens.first() self.mox.StubOutWithMock(api, 'token_create') self.mox.StubOutWithMock(api, 'tenant_list_for_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.mox.ReplayAll() form_data = { 'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.user.password, 'username': self.user.name } res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'horizon/auth/login.html')
def test_login_no_tenants(self): NEW_TENANT_ID = '6' NEW_TENANT_NAME = 'FAKENAME' TOKEN_ID = 1 form_data = {'method': 'Login', 'password': self.PASSWORD, 'username': self.TEST_USER} self.mox.StubOutWithMock(api, 'token_create') class FakeToken(object): id = TOKEN_ID, user = {'roles': [{'name': 'fake'}]}, serviceCatalog = {} aToken = api.Token(FakeToken()) api.token_create(IsA(http.HttpRequest), "", self.TEST_USER, self.PASSWORD).AndReturn(aToken) aTenant = self.mox.CreateMock(api.Token) aTenant.id = NEW_TENANT_ID aTenant.name = NEW_TENANT_NAME self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id).\ AndReturn([]) self.mox.StubOutWithMock(messages, 'error') messages.error(IsA(http.HttpRequest), IsA(unicode)) self.mox.ReplayAll() res = self.client.post(reverse('horizon:auth_login'), form_data) self.assertTemplateUsed(res, 'splash.html') self.mox.VerifyAll()
def test_login_invalid_credentials(self): self.mox.StubOutWithMock(api, 'token_create') unauthorized = keystone_exceptions.Unauthorized("Invalid") unauthorized.silence_logging = True api.token_create(IsA(http.HttpRequest), "", self.user.name, self.user.password).AndRaise(unauthorized) self.mox.ReplayAll() form_data = { 'method': 'Login', 'region': 'http://localhost:5000/v2.0', 'password': self.user.password, 'username': self.user.name } res = self.client.post(reverse('horizon:auth_login'), form_data, follow=True) self.assertTemplateUsed(res, 'horizon/auth/login.html') # Verify that API error messages are rendered, but not using the # messages framework. self.assertContains(res, "Invalid user name or password.") self.assertNotContains(res, 'class="messages"')
def test_switch_tenants(self): tenants = self.tenants.list() tenant = self.tenants.first() token = self.tokens.unscoped_token scoped_token = self.tokens.scoped_token switch_to = scoped_token.tenant['id'] user = self.users.first() self.setActiveUser(id=user.id, token=token.id, username=user.name, tenant_id=tenant.id, service_catalog=self.service_catalog, authorized_tenants=tenants) self.mox.StubOutWithMock(api, 'token_create') self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.token_create(IsA(http.HttpRequest), switch_to, user.name, user.password).AndReturn(scoped_token) api.tenant_list_for_token(IsA(http.HttpRequest), token.id).AndReturn(tenants) self.mox.ReplayAll() form_data = {'method': 'LoginWithTenant', 'region': 'http://localhost:5000/v2.0', 'username': user.name, 'password': user.password, 'tenant': switch_to} switch_url = reverse('horizon:auth_switch', args=[switch_to]) res = self.client.post(switch_url, form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL) self.assertEqual(self.client.session['tenant'], scoped_token.tenant['name'])
def test_switch_tenants(self): tenants = self.tenants.list() tenant = self.tenants.first() token = self.tokens.unscoped_token scoped_token = self.tokens.scoped_token switch_to = scoped_token.tenant['id'] user = self.users.first() self.setActiveUser(id=user.id, token=token.id, username=user.name, tenant_id=tenant.id, service_catalog=self.service_catalog, authorized_tenants=tenants) self.mox.StubOutWithMock(api, 'token_create') self.mox.StubOutWithMock(api, 'tenant_list_for_token') api.token_create(IsA(http.HttpRequest), switch_to, user.name, user.password).AndReturn(scoped_token) api.tenant_list_for_token(IsA(http.HttpRequest), token.id).AndReturn(tenants) self.mox.ReplayAll() form_data = { 'method': 'LoginWithTenant', 'region': 'http://localhost:5000/v2.0', 'username': user.name, 'password': user.password, 'tenant': switch_to } switch_url = reverse('horizon:auth_switch', args=[switch_to]) res = self.client.post(switch_url, form_data) self.assertRedirectsNoFollow(res, DASH_INDEX_URL) self.assertEqual(self.client.session['tenant'], scoped_token.tenant['name'])
def test_token_create(self): token = self.tokens.scoped_token keystoneclient = self.stub_keystoneclient() keystoneclient.tokens = self.mox.CreateMockAnything() keystoneclient.tokens.authenticate(username=self.user.name, password=self.user.password, tenant_id=token.tenant['id'])\ .AndReturn(token) self.mox.ReplayAll() ret_val = api.token_create(self.request, token.tenant['id'], self.user.name, self.user.password) self.assertEqual(token.tenant['id'], ret_val.tenant['id'])
def test_token_create(self): test_token = Token(TEST_TOKEN_ID, TEST_USERNAME, TEST_TENANT_ID, TEST_TENANT_NAME) keystoneclient = self.stub_keystoneclient() keystoneclient.tokens = self.mox.CreateMockAnything() keystoneclient.tokens.authenticate(username=TEST_USERNAME, password=TEST_PASSWORD, tenant_id=TEST_TENANT_ID)\ .AndReturn(test_token) self.mox.ReplayAll() ret_val = api.token_create(self.request, TEST_TENANT_ID, TEST_USERNAME, TEST_PASSWORD) self.assertEqual(test_token.tenant['id'], ret_val.tenant['id'])
def handle(self, request, data): # For now we'll allow fallback to OPENSTACK_KEYSTONE_URL if the # form post doesn't include a region. endpoint = data.get('region', None) or settings.OPENSTACK_KEYSTONE_URL region_name = dict(self.fields['region'].choices)[endpoint] request.session['region_endpoint'] = endpoint request.session['region_name'] = region_name redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, "") if data.get('tenant', None): try: token = api.token_create(request, data.get('tenant'), data['username'], data['password']) tenants = api.tenant_list_for_token(request, token.id) except: msg = _('Unable to authenticate for that project.') exceptions.handle(request, message=msg, escalate=True) _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect) elif data.get('username', None): try: unscoped_token = api.token_create(request, '', data['username'], data['password']) except keystone_exceptions.Unauthorized: exceptions.handle(request, _('Invalid user name or password.')) except: # If we get here we don't want to show a stack trace to the # user. However, if we fail here, there may be bad session # data that's been cached already. request.session.clear() exceptions.handle(request, message=_("An error occurred authenticating." " Please try again later."), escalate=True) # Unscoped token 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, unscoped_token.id) except: exceptions.handle(request) tenants = [] # Abort if there are no valid tenants for this user if not tenants: messages.error(request, _('You are not authorized for any projects.') % {"user": data['username']}, extra_tags="login") return # Create a token. # NOTE(gabriel): Keystone can return tenants that you're # authorized to administer but not to log into as a user, so in # the case of an Unauthorized error we should iterate through # the tenants until one succeeds or we've failed them all. while tenants: tenant = tenants.pop() try: token = api.token_create_scoped(request, tenant.id, unscoped_token.id) break except: # 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 projects.")) _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect)
def handle(self, request, data): region = data.get('region', '').split(',') if len(region) > 1: request.session['region_endpoint'] = region[0] request.session['region_name'] = region[1] if data.get('tenant', None): try: token = api.token_create(request, data.get('tenant'), data['username'], data['password']) tenants = api.tenant_list_for_token(request, token.id) except: exceptions.handle(request, message=_('Unable to authenticate tenant.'), escalate=True) tenant = None for t in tenants: if t.id == data.get('tenant'): tenant = t _set_session_data(request, token) user = users.get_user_from_request(request) return shortcuts.redirect(base.Horizon.get_user_home(user)) elif data.get('username', None): try: token = api.token_create(request, '', data['username'], data['password']) except keystone_exceptions.Unauthorized: exceptions.handle(request, _('Invalid user name or password.')) except: exceptions.handle(request, escalate=True) # Unscoped token request.session['unscoped_token'] = 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) except: exceptions.handle(request) tenants = [] # Abort if there are no valid tenants for this user if not tenants: messages.error(request, _('No tenants present for user: %(user)s') % {"user": data['username']}, extra_tags="login") return # Create a token. # NOTE(gabriel): Keystone can return tenants that you're # authorized to administer but not to log into as a user, so in # the case of an Unauthorized error we should iterate through # the tenants until one succeeds or we've failed them all. while tenants: tenant = tenants.pop() try: token = api.token_create_scoped(request, tenant.id, token.id) break except: # 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.")) _set_session_data(request, token) user = users.get_user_from_request(request) return shortcuts.redirect(base.Horizon.get_user_home(user))
def handle(self, request, data): # For now we'll allow fallback to OPENSTACK_KEYSTONE_URL if the # form post doesn't include a region. endpoint = data.get("region", None) or settings.OPENSTACK_KEYSTONE_URL region_name = dict(self.fields["region"].choices)[endpoint] request.session["region_endpoint"] = endpoint request.session["region_name"] = region_name redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, "") if data.get("tenant", None): try: token = api.token_create(request, data.get("tenant"), data["username"], data["password"]) tenants = api.tenant_list_for_token(request, token.id) except: exceptions.handle(request, message=_("Unable to authenticate tenant."), escalate=True) tenant = None for t in tenants: if t.id == data.get("tenant"): tenant = t _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect) elif data.get("username", None): try: token = api.token_create(request, "", data["username"], data["password"]) except keystone_exceptions.Unauthorized: exceptions.handle(request, _("Invalid user name or password.")) except: exceptions.handle(request, escalate=True) # Unscoped token request.session["unscoped_token"] = 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) except: exceptions.handle(request) tenants = [] # Abort if there are no valid tenants for this user if not tenants: messages.error( request, _("No tenants present for user: %(user)s") % {"user": data["username"]}, extra_tags="login" ) return # Create a token. # NOTE(gabriel): Keystone can return tenants that you're # authorized to administer but not to log into as a user, so in # the case of an Unauthorized error we should iterate through # the tenants until one succeeds or we've failed them all. while tenants: tenant = tenants.pop() try: token = api.token_create_scoped(request, tenant.id, token.id) break except: # 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.")) _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect)
def handle(self, request, data): """ Process the user's login via Keystone. Note: We don't use the messages framework here (including messages created by ``exceptions.handle`` beause they will not be displayed on the login page (intentionally). Instead we add all error messages to the form's ``non_field_errors``, causing them to appear as errors on the form itself. """ if 'user_name' in request.session: if request.session['user_name'] != data['username']: # To avoid reusing another user's session, create a # new, empty session if the existing session # corresponds to a different authenticated user. request.session.flush() # Always cycle the session key when viewing the login form to # prevent session fixation request.session.cycle_key() # For now we'll allow fallback to OPENSTACK_KEYSTONE_URL if the # form post doesn't include a region. endpoint = data.get('region', None) or settings.OPENSTACK_KEYSTONE_URL if endpoint != request.session.get('region_endpoint', None): region_name = dict(self.fields['region'].choices)[endpoint] request.session['region_endpoint'] = endpoint request.session['region_name'] = region_name request.user.service_catalog = None redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, "") if data.get('tenant', None): try: token = api.token_create(request, data.get('tenant'), data['username'], data['password']) tenants = api.tenant_list_for_token(request, token.id) except: msg = _('Unable to authenticate for that project.') exceptions.handle(request, ignore=True) return self.api_error(msg) _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect) elif data.get('username', None): try: unscoped_token = api.token_create(request, '', data['username'], data['password']) except keystone_exceptions.Unauthorized: msg = _('Invalid user name or password.') exceptions.handle(request, ignore=True) return self.api_error(msg) except: # If we get here we don't want to show a stack trace to the # user. However, if we fail here, there may be bad session # data that's been cached already. request.user_logout() msg = _("An error occurred authenticating. " "Please try again later.") exceptions.handle(request, ignore=True) return self.api_error(msg) # Unscoped token 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, unscoped_token.id) except: exceptions.handle(request, ignore=True) tenants = [] # Abort if there are no valid tenants for this user if not tenants: msg = _('You are not authorized for any projects.') return self.api_error(msg) # Create a token. # NOTE(gabriel): Keystone can return tenants that you're # authorized to administer but not to log into as a user, so in # the case of an Unauthorized error we should iterate through # the tenants until one succeeds or we've failed them all. while tenants: tenant = tenants.pop() try: token = api.token_create_scoped(request, tenant.id, unscoped_token.id) break except: # This will continue for recognized Unauthorized # exceptions from keystoneclient. exceptions.handle(request, ignore=True) token = None if token is None: msg = _("You are not authorized for any available projects.") return self.api_error(msg) _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect)
def handle(self, request, data): try: if data.get('tenant', None): token = api.token_create(request, data.get('tenant'), data['username'], data['password']) tenants = api.tenant_list_for_token(request, token.id) tenant = None for t in tenants: if t.id == data.get('tenant'): tenant = t _set_session_data(request, token) user = users.get_user_from_request(request) return shortcuts.redirect(base.Horizon.get_user_home(user)) elif data.get('username', None): try: token = api.token_create(request, '', data['username'], data['password']) except keystone_exceptions.Unauthorized: messages.error(request, _('Bad user name or password.'), extra_tags="login") return # Unscoped token request.session['unscoped_token'] = token.id request.user.username = data['username'] # Get the tenant list, and log in using first tenant # FIXME (anthony): add tenant chooser here? tenants = api.tenant_list_for_token(request, token.id) # Abort if there are no valid tenants for this user if not tenants: messages.error(request, _('No tenants present for user: %(user)s') % {"user": data['username']}, extra_tags="login") return # Create a token. # NOTE(gabriel): Keystone can return tenants that you're # authorized to administer but not to log into as a user, so in # the case of an Unauthorized error we should iterate through # the tenants until one succeeds or we've failed them all. while tenants: tenant = tenants.pop() try: token = api.token_create_scoped(request, tenant.id, token.id) break except api_exceptions.Unauthorized as e: token = None if token is None: raise exceptions.NotAuthorized( _("You are not authorized for any available tenants.")) _set_session_data(request, token) user = users.get_user_from_request(request) return shortcuts.redirect(base.Horizon.get_user_home(user)) except api_exceptions.Unauthorized as e: msg = _('Error authenticating: %s') % e.message LOG.exception(msg) messages.error(request, msg, extra_tags="login") except api_exceptions.ApiException as e: messages.error(request, _('Error authenticating with keystone: %s') % e.message, extra_tags="login")
def handle(self, request, data): if 'user_name' in request.session: if request.session['user_name'] != data['username']: # To avoid reusing another user's session, create a # new, empty session if the existing session # corresponds to a different authenticated user. request.session.flush() # Always cycle the session key when viewing the login form to # prevent session fixation request.session.cycle_key() # For now we'll allow fallback to OPENSTACK_KEYSTONE_URL if the # form post doesn't include a region. # jt default_region = (settings.OPENSTACK_KEYSTONE_URL, "Default Region") regions = getattr(settings, 'AVAILABLE_REGIONS', [default_region]) #endpoint = data.get('region', None) or settings.OPENSTACK_KEYSTONE_URL #region_name = dict(self.fields['region'].choices)[endpoint] region_name = data.get('region', None) or "Default Region" endpoint = [r[0] for r in regions if r[1] == region_name][0] request.session['region_endpoint'] = endpoint request.session['region_name'] = region_name redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, None) # Make sure the requested redirect matches the protocol, # domain, and port of this request if redirect_to and not same_origin( request.build_absolute_uri(redirect_to), request.build_absolute_uri()): redirect_to = None if data.get('tenant', None): try: token = api.token_create(request, data.get('tenant'), data['username'], data['password']) tenants = api.tenant_list_for_token(request, token.id) except: msg = _('Unable to authenticate for that project.') exceptions.handle(request, message=msg, escalate=True) _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect) elif data.get('username', None): try: unscoped_token = api.token_create(request, '', data['username'], data['password']) except keystone_exceptions.Unauthorized: exceptions.handle(request, _('Invalid user name or password.')) except: # If we get here we don't want to show a stack trace to the # user. However, if we fail here, there may be bad session # data that's been cached already. request.user_logout() exceptions.handle(request, message=_("An error occurred authenticating." " Please try again later."), escalate=True) # Unscoped token 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, unscoped_token.id) except: exceptions.handle(request) tenants = [] # Abort if there are no valid tenants for this user if not tenants: messages.error(request, _('You are not authorized for any projects.') % {"user": data['username']}, extra_tags="login") return # Create a token. # NOTE(gabriel): Keystone can return tenants that you're # authorized to administer but not to log into as a user, so in # the case of an Unauthorized error we should iterate through # the tenants until one succeeds or we've failed them all. while tenants: tenant = tenants.pop() try: token = api.token_create_scoped(request, tenant.id, unscoped_token.id) break except: # 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 projects.")) _set_session_data(request, token) user = users.get_user_from_request(request) redirect = redirect_to or base.Horizon.get_user_home(user) return shortcuts.redirect(redirect)