From 474c50356cebccb03aca336015b26cf86f83ec8a Mon Sep 17 00:00:00 2001 From: Mohammed Naser Date: Thu, 7 Jan 2016 18:34:21 -0500 Subject: [PATCH] Fix WebSSO when Keystone server hostname contains 'auth' When using WebSSO, if the Keystone server has "auth" in the hostname, the existing regular expression below is problematic which causes a failed replacement. Change-Id: I564d9af4be837f83f5ef1f8b00b794befafeeb7b Closes-Bug: #1532032 --- openstack_auth/tests/tests.py | 19 +++++++++++++++++++ openstack_auth/utils.py | 11 +++++++++++ openstack_auth/views.py | 3 +-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/openstack_auth/tests/tests.py b/openstack_auth/tests/tests.py index 842acaf..3eeff59 100644 --- a/openstack_auth/tests/tests.py +++ b/openstack_auth/tests/tests.py @@ -918,6 +918,25 @@ class OpenStackAuthTestsWebSSO(OpenStackAuthTestsMixin, test.TestCase): response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) + def test_websso_login_with_auth_in_url(self): + settings.OPENSTACK_KEYSTONE_URL = 'http://auth.openstack.org:5000/v3' + + projects = [self.data.project_one, self.data.project_two] + unscoped = self.data.federated_unscoped_access_info + token = unscoped.auth_token + + form_data = {'token': token} + self._mock_unscoped_client_list_projects(unscoped, projects) + self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id) + + self.mox.ReplayAll() + + url = reverse('websso') + + # POST to the page to log in. + response = self.client.post(url, form_data) + self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) + load_tests = load_tests_apply_scenarios diff --git a/openstack_auth/utils.py b/openstack_auth/utils.py index c961d1c..599e338 100644 --- a/openstack_auth/utils.py +++ b/openstack_auth/utils.py @@ -13,6 +13,7 @@ import datetime import logging +import re from django.conf import settings from django.contrib import auth @@ -280,6 +281,16 @@ def fix_auth_url_version(auth_url): return auth_url +def clean_up_auth_url(auth_url): + """Clean up the auth url to extract the exact Keystone URL""" + + # NOTE(mnaser): This drops the query and fragment because we're only + # trying to extract the Keystone URL. + scheme, netloc, path, query, fragment = urlparse.urlsplit(auth_url) + return urlparse.urlunsplit(( + scheme, netloc, re.sub(r'/auth.*', '', path), '', '')) + + def get_token_auth_plugin(auth_url, token, project_id=None, domain_name=None): if get_keystone_version() >= 3: if domain_name: diff --git a/openstack_auth/views.py b/openstack_auth/views.py index 3b84319..9e060a0 100644 --- a/openstack_auth/views.py +++ b/openstack_auth/views.py @@ -11,7 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging -import re import django from django.conf import settings @@ -135,7 +134,7 @@ def login(request, template_name=None, extra_context=None, **kwargs): def websso(request): """Logs a user in using a token from Keystone's POST.""" referer = request.META.get('HTTP_REFERER', settings.OPENSTACK_KEYSTONE_URL) - auth_url = re.sub(r'/auth.*', '', referer) + auth_url = utils.clean_up_auth_url(referer) token = request.POST.get('token') try: request.user = auth.authenticate(request=request, auth_url=auth_url,