Use keystone auth plugins
Convert the existing DOA to using authentication plugins keeping as close to the current code structure as possible. This will allow us to add additional authentication plugins later and to start changing horizon to use these plugins when talking to other services rather than hacking tokens into the clients. Change-Id: Idd9ad5044e998a6c514f6161f5159b44391a0849
This commit is contained in:
parent
5aeeaa09b0
commit
01e0abc17d
@ -69,35 +69,22 @@ class KeystoneBackend(object):
|
|||||||
"""Authenticates a user via the Keystone Identity API."""
|
"""Authenticates a user via the Keystone Identity API."""
|
||||||
LOG.debug('Beginning user authentication for user "%s".' % username)
|
LOG.debug('Beginning user authentication for user "%s".' % username)
|
||||||
|
|
||||||
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
|
interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'public')
|
||||||
ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
|
|
||||||
endpoint_type = getattr(
|
|
||||||
settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
|
|
||||||
|
|
||||||
if auth_url is None:
|
if auth_url is None:
|
||||||
auth_url = settings.OPENSTACK_KEYSTONE_URL
|
auth_url = settings.OPENSTACK_KEYSTONE_URL
|
||||||
|
|
||||||
# keystone client v3 does not support logging in on the v2 url any more
|
session = utils.get_session()
|
||||||
if utils.get_keystone_version() >= 3:
|
keystone_client_class = utils.get_keystone_client().Client
|
||||||
if utils.has_in_url_path(auth_url, "/v2.0"):
|
|
||||||
LOG.warning("The settings.py file points to a v2.0 keystone "
|
auth_url = utils.fix_auth_url_version(auth_url)
|
||||||
"endpoint, but v3 is specified as the API version "
|
unscoped_auth = utils.get_password_auth_plugin(auth_url,
|
||||||
"to use. Using v3 endpoint for authentication.")
|
username,
|
||||||
auth_url = utils.url_path_replace(auth_url, "/v2.0", "/v3", 1)
|
password,
|
||||||
|
user_domain_name)
|
||||||
|
|
||||||
keystone_client = utils.get_keystone_client()
|
|
||||||
try:
|
try:
|
||||||
client = keystone_client.Client(
|
unscoped_auth_ref = unscoped_auth.get_access(session)
|
||||||
user_domain_name=user_domain_name,
|
|
||||||
username=username,
|
|
||||||
password=password,
|
|
||||||
auth_url=auth_url,
|
|
||||||
insecure=insecure,
|
|
||||||
cacert=ca_cert,
|
|
||||||
debug=settings.DEBUG)
|
|
||||||
|
|
||||||
unscoped_auth_ref = client.auth_ref
|
|
||||||
unscoped_token = auth_user.Token(auth_ref=unscoped_auth_ref)
|
|
||||||
except (keystone_exceptions.Unauthorized,
|
except (keystone_exceptions.Unauthorized,
|
||||||
keystone_exceptions.Forbidden,
|
keystone_exceptions.Forbidden,
|
||||||
keystone_exceptions.NotFound) as exc:
|
keystone_exceptions.NotFound) as exc:
|
||||||
@ -114,22 +101,16 @@ class KeystoneBackend(object):
|
|||||||
# Check expiry for our unscoped auth ref.
|
# Check expiry for our unscoped auth ref.
|
||||||
self.check_auth_expiry(unscoped_auth_ref)
|
self.check_auth_expiry(unscoped_auth_ref)
|
||||||
|
|
||||||
# Check if token is automatically scoped to default_project
|
unscoped_client = keystone_client_class(session=session,
|
||||||
# grab the project from this token, to use as a default
|
auth=unscoped_auth)
|
||||||
# if no recent_project is found in the cookie
|
|
||||||
token_proj_id = None
|
|
||||||
if unscoped_auth_ref.project_scoped:
|
|
||||||
token_proj_id = unscoped_auth_ref.get('project',
|
|
||||||
{}).get('id')
|
|
||||||
|
|
||||||
# We list all the user's projects
|
# We list all the user's projects
|
||||||
try:
|
try:
|
||||||
if utils.get_keystone_version() < 3:
|
if utils.get_keystone_version() >= 3:
|
||||||
projects = client.tenants.list()
|
projects = unscoped_client.projects.list(
|
||||||
else:
|
|
||||||
client.management_url = auth_url
|
|
||||||
projects = client.projects.list(
|
|
||||||
user=unscoped_auth_ref.user_id)
|
user=unscoped_auth_ref.user_id)
|
||||||
|
else:
|
||||||
|
projects = unscoped_client.tenants.list()
|
||||||
except (keystone_exceptions.ClientException,
|
except (keystone_exceptions.ClientException,
|
||||||
keystone_exceptions.AuthorizationFailure) as exc:
|
keystone_exceptions.AuthorizationFailure) as exc:
|
||||||
msg = _('Unable to retrieve authorized projects.')
|
msg = _('Unable to retrieve authorized projects.')
|
||||||
@ -143,51 +124,55 @@ class KeystoneBackend(object):
|
|||||||
# the recent project id a user might have set in a cookie
|
# the recent project id a user might have set in a cookie
|
||||||
recent_project = None
|
recent_project = None
|
||||||
if request:
|
if request:
|
||||||
|
# Check if token is automatically scoped to default_project
|
||||||
|
# grab the project from this token, to use as a default
|
||||||
|
# if no recent_project is found in the cookie
|
||||||
recent_project = request.COOKIES.get('recent_project',
|
recent_project = request.COOKIES.get('recent_project',
|
||||||
token_proj_id)
|
unscoped_auth_ref.project_id)
|
||||||
|
|
||||||
# if a most recent project was found, try using it first
|
# if a most recent project was found, try using it first
|
||||||
for pos, project in enumerate(projects):
|
if recent_project:
|
||||||
if project.id == recent_project:
|
for pos, project in enumerate(projects):
|
||||||
# move recent project to the beginning
|
if project.id == recent_project:
|
||||||
projects.pop(pos)
|
# move recent project to the beginning
|
||||||
projects.insert(0, project)
|
projects.pop(pos)
|
||||||
break
|
projects.insert(0, project)
|
||||||
|
break
|
||||||
|
|
||||||
for project in projects:
|
for project in projects:
|
||||||
|
token = unscoped_auth_ref.auth_token
|
||||||
|
scoped_auth = utils.get_token_auth_plugin(auth_url,
|
||||||
|
token=token,
|
||||||
|
project_id=project.id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client = keystone_client.Client(
|
scoped_auth_ref = scoped_auth.get_access(session)
|
||||||
tenant_id=project.id,
|
|
||||||
token=unscoped_auth_ref.auth_token,
|
|
||||||
auth_url=auth_url,
|
|
||||||
insecure=insecure,
|
|
||||||
cacert=ca_cert,
|
|
||||||
debug=settings.DEBUG)
|
|
||||||
auth_ref = client.auth_ref
|
|
||||||
break
|
|
||||||
except (keystone_exceptions.ClientException,
|
except (keystone_exceptions.ClientException,
|
||||||
keystone_exceptions.AuthorizationFailure):
|
keystone_exceptions.AuthorizationFailure):
|
||||||
auth_ref = None
|
pass
|
||||||
|
else:
|
||||||
if auth_ref is None:
|
break
|
||||||
|
else:
|
||||||
msg = _("Unable to authenticate to any available projects.")
|
msg = _("Unable to authenticate to any available projects.")
|
||||||
raise exceptions.KeystoneAuthException(msg)
|
raise exceptions.KeystoneAuthException(msg)
|
||||||
|
|
||||||
# Check expiry for our new scoped token.
|
# Check expiry for our new scoped token.
|
||||||
self.check_auth_expiry(auth_ref)
|
self.check_auth_expiry(scoped_auth_ref)
|
||||||
|
|
||||||
# If we made it here we succeeded. Create our User!
|
# If we made it here we succeeded. Create our User!
|
||||||
user = auth_user.create_user_from_token(
|
user = auth_user.create_user_from_token(
|
||||||
request,
|
request,
|
||||||
auth_user.Token(auth_ref),
|
auth_user.Token(scoped_auth_ref),
|
||||||
client.service_catalog.url_for(endpoint_type=endpoint_type))
|
scoped_auth_ref.service_catalog.url_for(endpoint_type=interface))
|
||||||
|
|
||||||
if request is not None:
|
if request is not None:
|
||||||
request.session['unscoped_token'] = unscoped_token.id
|
request.session['unscoped_token'] = unscoped_auth_ref.auth_token
|
||||||
request.user = user
|
request.user = user
|
||||||
|
scoped_client = keystone_client_class(session=session,
|
||||||
|
auth=scoped_auth)
|
||||||
|
|
||||||
# Support client caching to save on auth calls.
|
# Support client caching to save on auth calls.
|
||||||
setattr(request, KEYSTONE_CLIENT_ATTR, client)
|
setattr(request, KEYSTONE_CLIENT_ATTR, scoped_client)
|
||||||
|
|
||||||
LOG.debug('Authentication completed for user "%s".' % username)
|
LOG.debug('Authentication completed for user "%s".' % username)
|
||||||
return user
|
return user
|
||||||
|
@ -15,7 +15,11 @@ from django.conf import settings
|
|||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django import test
|
from django import test
|
||||||
|
from keystoneclient.auth.identity import v2 as auth_v2
|
||||||
|
from keystoneclient.auth.identity import v3 as auth_v3
|
||||||
|
from keystoneclient.auth import token_endpoint
|
||||||
from keystoneclient import exceptions as keystone_exceptions
|
from keystoneclient import exceptions as keystone_exceptions
|
||||||
|
from keystoneclient import session
|
||||||
from keystoneclient.v2_0 import client as client_v2
|
from keystoneclient.v2_0 import client as client_v2
|
||||||
from keystoneclient.v3 import client as client_v3
|
from keystoneclient.v3 import client as client_v3
|
||||||
from mox3 import mox
|
from mox3 import mox
|
||||||
@ -39,64 +43,44 @@ class OpenStackAuthTestsMixin(object):
|
|||||||
('admin', {'interface': 'adminURL'})
|
('admin', {'interface': 'adminURL'})
|
||||||
]
|
]
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.mox.UnsetStubs()
|
|
||||||
self.mox.VerifyAll()
|
|
||||||
|
|
||||||
def _mock_unscoped_client(self, user):
|
def _mock_unscoped_client(self, user):
|
||||||
self.mox.StubOutWithMock(self.ks_client_module, "Client")
|
plugin = self._create_password_auth()
|
||||||
self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
plugin.get_access(mox.IsA(session.Session)). \
|
||||||
password=user.password,
|
AndReturn(self.data.unscoped_access_info)
|
||||||
username=user.name,
|
return self.ks_client_module.Client(session=mox.IsA(session.Session),
|
||||||
user_domain_name=DEFAULT_DOMAIN,
|
auth=plugin)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)\
|
|
||||||
.AndReturn(self.keystone_client_unscoped)
|
|
||||||
|
|
||||||
def _mock_unscoped_client_with_token(self, user, unscoped):
|
def _mock_unscoped_client_with_token(self, user, unscoped):
|
||||||
self.mox.StubOutWithMock(self.ks_client_module, "Client")
|
plugin = token_endpoint.Token(settings.OPENSTACK_KEYSTONE_URL,
|
||||||
url = settings.OPENSTACK_KEYSTONE_URL
|
unscoped.auth_token)
|
||||||
self.ks_client_module.Client(user_id=user.id,
|
return self.ks_client_module.Client(session=mox.IsA(session.Session),
|
||||||
auth_url=url,
|
auth=plugin)
|
||||||
token=unscoped.auth_token,
|
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)\
|
|
||||||
.AndReturn(self.keystone_client_unscoped)
|
|
||||||
|
|
||||||
def _mock_client_token_auth_failure(self, unscoped, tenant_id):
|
def _mock_client_token_auth_failure(self, unscoped, tenant_id):
|
||||||
exc = keystone_exceptions.AuthorizationFailure
|
plugin = self._create_token_auth(tenant_id, unscoped.auth_token)
|
||||||
self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
plugin.get_access(mox.IsA(session.Session)). \
|
||||||
tenant_id=tenant_id,
|
AndRaise(keystone_exceptions.AuthorizationFailure)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
token=unscoped.auth_token,
|
|
||||||
debug=False) \
|
|
||||||
.AndRaise(exc)
|
|
||||||
|
|
||||||
def _mock_client_password_auth_failure(self, username, password, exc):
|
def _mock_client_password_auth_failure(self, username, password, exc):
|
||||||
self.mox.StubOutWithMock(self.ks_client_module, "Client")
|
plugin = self._create_password_auth(username=username,
|
||||||
self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
password=password)
|
||||||
password=password,
|
plugin.get_access(mox.IsA(session.Session)).AndRaise(exc)
|
||||||
username=username,
|
|
||||||
user_domain_name=DEFAULT_DOMAIN,
|
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False).AndRaise(exc)
|
|
||||||
|
|
||||||
def _mock_scoped_client_for_tenant(self, auth_ref, tenant_id, url=None):
|
def _mock_scoped_client_for_tenant(self, auth_ref, tenant_id, url=None,
|
||||||
|
client=True):
|
||||||
if url is None:
|
if url is None:
|
||||||
auth_url = settings.OPENSTACK_KEYSTONE_URL
|
url = settings.OPENSTACK_KEYSTONE_URL
|
||||||
else:
|
|
||||||
auth_url = url
|
plugin = self._create_token_auth(
|
||||||
self.ks_client_module.Client(auth_url=auth_url,
|
tenant_id,
|
||||||
tenant_id=tenant_id,
|
token=self.data.unscoped_access_info.auth_token,
|
||||||
insecure=False,
|
url=url)
|
||||||
cacert=None,
|
|
||||||
token=auth_ref.auth_token,
|
plugin.get_access(mox.IsA(session.Session)).AndReturn(auth_ref)
|
||||||
debug=False) \
|
if client:
|
||||||
.AndReturn(self.keystone_client_scoped)
|
return self.ks_client_module.Client(
|
||||||
|
session=mox.IsA(session.Session),
|
||||||
|
auth=plugin)
|
||||||
|
|
||||||
def get_form_data(self, user):
|
def get_form_data(self, user):
|
||||||
return {'region': settings.OPENSTACK_KEYSTONE_URL,
|
return {'region': settings.OPENSTACK_KEYSTONE_URL,
|
||||||
@ -116,25 +100,67 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
self.addCleanup(override.disable)
|
self.addCleanup(override.disable)
|
||||||
|
|
||||||
self.mox = mox.Mox()
|
self.mox = mox.Mox()
|
||||||
|
self.addCleanup(self.mox.VerifyAll)
|
||||||
|
self.addCleanup(self.mox.UnsetStubs)
|
||||||
|
|
||||||
self.data = data_v2.generate_test_data()
|
self.data = data_v2.generate_test_data()
|
||||||
self.ks_client_module = client_v2
|
self.ks_client_module = client_v2
|
||||||
endpoint = settings.OPENSTACK_KEYSTONE_URL
|
|
||||||
self.keystone_client_unscoped = self.ks_client_module.Client(
|
|
||||||
endpoint=endpoint,
|
|
||||||
auth_ref=self.data.unscoped_access_info)
|
|
||||||
self.keystone_client_scoped = self.ks_client_module.Client(
|
|
||||||
endpoint=endpoint,
|
|
||||||
auth_ref=self.data.scoped_access_info)
|
|
||||||
settings.OPENSTACK_API_VERSIONS['identity'] = 2.0
|
settings.OPENSTACK_API_VERSIONS['identity'] = 2.0
|
||||||
settings.OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v2.0"
|
settings.OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v2.0"
|
||||||
|
|
||||||
def _mock_unscoped_list_tenants(self, tenants):
|
self.mox.StubOutClassWithMocks(token_endpoint, 'Token')
|
||||||
self.mox.StubOutWithMock(self.keystone_client_unscoped.tenants, "list")
|
self.mox.StubOutClassWithMocks(auth_v2, 'Token')
|
||||||
self.keystone_client_unscoped.tenants.list().AndReturn(tenants)
|
self.mox.StubOutClassWithMocks(auth_v2, 'Password')
|
||||||
|
self.mox.StubOutClassWithMocks(client_v2, 'Client')
|
||||||
|
|
||||||
|
def _mock_unscoped_list_tenants(self, client, tenants):
|
||||||
|
client.tenants = self.mox.CreateMockAnything()
|
||||||
|
client.tenants.list().AndReturn(tenants)
|
||||||
|
|
||||||
def _mock_unscoped_client_list_tenants(self, user, tenants):
|
def _mock_unscoped_client_list_tenants(self, user, tenants):
|
||||||
self._mock_unscoped_client(user)
|
client = self._mock_unscoped_client(user)
|
||||||
self._mock_unscoped_list_tenants(tenants)
|
self._mock_unscoped_list_tenants(client, tenants)
|
||||||
|
|
||||||
|
def _mock_client_delete_token(self, user, token, url=None):
|
||||||
|
if not url:
|
||||||
|
url = settings.OPENSTACK_KEYSTONE_URL
|
||||||
|
|
||||||
|
plugin = token_endpoint.Token(
|
||||||
|
endpoint=url,
|
||||||
|
token=self.data.unscoped_access_info.auth_token)
|
||||||
|
|
||||||
|
client = self.ks_client_module.Client(session=mox.IsA(session.Session),
|
||||||
|
auth=plugin)
|
||||||
|
client.tokens = self.mox.CreateMockAnything()
|
||||||
|
client.tokens.delete(token=token)
|
||||||
|
return client
|
||||||
|
|
||||||
|
def _create_password_auth(self, username=None, password=None, url=None):
|
||||||
|
if not username:
|
||||||
|
username = self.data.user.name
|
||||||
|
|
||||||
|
if not password:
|
||||||
|
password = self.data.user.password
|
||||||
|
|
||||||
|
if not url:
|
||||||
|
url = settings.OPENSTACK_KEYSTONE_URL
|
||||||
|
|
||||||
|
return auth_v2.Password(auth_url=url,
|
||||||
|
password=password,
|
||||||
|
username=username)
|
||||||
|
|
||||||
|
def _create_token_auth(self, project_id, token=None, url=None):
|
||||||
|
if not token:
|
||||||
|
token = self.data.unscoped_access_info.auth_token
|
||||||
|
|
||||||
|
if not url:
|
||||||
|
url = settings.OPENSTACK_KEYSTONE_URL
|
||||||
|
|
||||||
|
return auth_v2.Token(auth_url=url,
|
||||||
|
token=token,
|
||||||
|
tenant_id=project_id,
|
||||||
|
reauthenticate=False)
|
||||||
|
|
||||||
def _login(self):
|
def _login(self):
|
||||||
tenants = [self.data.tenant_one, self.data.tenant_two]
|
tenants = [self.data.tenant_one, self.data.tenant_two]
|
||||||
@ -305,13 +331,16 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
scoped = self.data.scoped_access_info
|
scoped = self.data.scoped_access_info
|
||||||
sc = self.data.service_catalog
|
sc = self.data.service_catalog
|
||||||
et = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
|
et = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
|
||||||
|
endpoint = sc.url_for(endpoint_type=et)
|
||||||
|
|
||||||
form_data = self.get_form_data(user)
|
form_data = self.get_form_data(user)
|
||||||
|
|
||||||
self._mock_unscoped_client_list_tenants(user, tenants)
|
self._mock_unscoped_client_list_tenants(user, tenants)
|
||||||
self._mock_scoped_client_for_tenant(unscoped, self.data.tenant_one.id)
|
self._mock_scoped_client_for_tenant(unscoped, self.data.tenant_one.id)
|
||||||
self._mock_scoped_client_for_tenant(scoped, tenant.id,
|
self._mock_client_delete_token(user, unscoped.auth_token, endpoint)
|
||||||
url=sc.url_for(endpoint_type=et))
|
self._mock_scoped_client_for_tenant(scoped, tenant.id, url=endpoint,
|
||||||
|
client=False)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse('login')
|
url = reverse('login')
|
||||||
@ -346,13 +375,13 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
def test_switch_region(self, next=None):
|
def test_switch_region(self, next=None):
|
||||||
tenants = [self.data.tenant_one, self.data.tenant_two]
|
tenants = [self.data.tenant_one, self.data.tenant_two]
|
||||||
user = self.data.user
|
user = self.data.user
|
||||||
unscoped = self.data.unscoped_access_info
|
scoped = self.data.scoped_access_info
|
||||||
sc = self.data.service_catalog
|
sc = self.data.service_catalog
|
||||||
|
|
||||||
form_data = self.get_form_data(user)
|
form_data = self.get_form_data(user)
|
||||||
|
|
||||||
self._mock_unscoped_client_list_tenants(user, tenants)
|
self._mock_unscoped_client_list_tenants(user, tenants)
|
||||||
self._mock_scoped_client_for_tenant(unscoped, self.data.tenant_one.id)
|
self._mock_scoped_client_for_tenant(scoped, self.data.tenant_one.id)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
@ -395,18 +424,15 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
user = self.data.user
|
user = self.data.user
|
||||||
unscoped = self.data.unscoped_access_info
|
unscoped = self.data.unscoped_access_info
|
||||||
|
|
||||||
self._mock_unscoped_client_with_token(user, unscoped)
|
client = self._mock_unscoped_client_with_token(user, unscoped)
|
||||||
self._mock_unscoped_list_tenants(tenants)
|
self._mock_unscoped_list_tenants(client, tenants)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
tenant_list = utils.get_project_list(
|
tenant_list = utils.get_project_list(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
||||||
token=unscoped.auth_token,
|
token=unscoped.auth_token)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)
|
|
||||||
self.assertEqual(tenant_list, expected_tenants)
|
self.assertEqual(tenant_list, expected_tenants)
|
||||||
|
|
||||||
def test_tenant_list_caching(self):
|
def test_tenant_list_caching(self):
|
||||||
@ -415,17 +441,14 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
user = self.data.user
|
user = self.data.user
|
||||||
unscoped = self.data.unscoped_access_info
|
unscoped = self.data.unscoped_access_info
|
||||||
|
|
||||||
self._mock_unscoped_list_tenants(tenants)
|
client = self._mock_unscoped_client_with_token(user, unscoped)
|
||||||
self._mock_unscoped_client_with_token(user, unscoped)
|
self._mock_unscoped_list_tenants(client, tenants)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
tenant_list = utils.get_project_list(
|
tenant_list = utils.get_project_list(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
||||||
token=unscoped.auth_token,
|
token=unscoped.auth_token)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)
|
|
||||||
self.assertEqual(tenant_list, expected_tenants)
|
self.assertEqual(tenant_list, expected_tenants)
|
||||||
|
|
||||||
# Test to validate that requesting the project list again results
|
# Test to validate that requesting the project list again results
|
||||||
@ -435,10 +458,7 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
tenant_list = utils.get_project_list(
|
tenant_list = utils.get_project_list(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
||||||
token=unscoped.auth_token,
|
token=unscoped.auth_token)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)
|
|
||||||
self.assertEqual(tenant_list, expected_tenants)
|
self.assertEqual(tenant_list, expected_tenants)
|
||||||
|
|
||||||
utils.remove_project_cache(unscoped.auth_token)
|
utils.remove_project_cache(unscoped.auth_token)
|
||||||
@ -448,14 +468,39 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
||||||
|
|
||||||
def _mock_unscoped_client_list_projects(self, user, projects):
|
def _mock_unscoped_client_list_projects(self, user, projects):
|
||||||
self._mock_unscoped_client(user)
|
client = self._mock_unscoped_client(user)
|
||||||
self._mock_unscoped_list_projects(user, projects)
|
self._mock_unscoped_list_projects(client, user, projects)
|
||||||
|
|
||||||
def _mock_unscoped_list_projects(self, user, projects):
|
def _mock_unscoped_list_projects(self, client, user, projects):
|
||||||
self.mox.StubOutWithMock(self.keystone_client_unscoped.projects,
|
client.projects = self.mox.CreateMockAnything()
|
||||||
"list")
|
client.projects.list(user=user.id).AndReturn(projects)
|
||||||
self.keystone_client_unscoped.projects.list(user=user.id) \
|
|
||||||
.AndReturn(projects)
|
def _create_password_auth(self, username=None, password=None, url=None):
|
||||||
|
if not username:
|
||||||
|
username = self.data.user.name
|
||||||
|
|
||||||
|
if not password:
|
||||||
|
password = self.data.user.password
|
||||||
|
|
||||||
|
if not url:
|
||||||
|
url = settings.OPENSTACK_KEYSTONE_URL
|
||||||
|
|
||||||
|
return auth_v3.Password(auth_url=url,
|
||||||
|
password=password,
|
||||||
|
username=username,
|
||||||
|
user_domain_name=DEFAULT_DOMAIN)
|
||||||
|
|
||||||
|
def _create_token_auth(self, project_id, token=None, url=None):
|
||||||
|
if not token:
|
||||||
|
token = self.data.unscoped_access_info.auth_token
|
||||||
|
|
||||||
|
if not url:
|
||||||
|
url = settings.OPENSTACK_KEYSTONE_URL
|
||||||
|
|
||||||
|
return auth_v3.Token(auth_url=url,
|
||||||
|
token=token,
|
||||||
|
project_id=project_id,
|
||||||
|
reauthenticate=False)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(OpenStackAuthTestsV3, self).setUp()
|
super(OpenStackAuthTestsV3, self).setUp()
|
||||||
@ -466,18 +511,20 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
self.addCleanup(override.disable)
|
self.addCleanup(override.disable)
|
||||||
|
|
||||||
self.mox = mox.Mox()
|
self.mox = mox.Mox()
|
||||||
|
self.addCleanup(self.mox.VerifyAll)
|
||||||
|
self.addCleanup(self.mox.UnsetStubs)
|
||||||
|
|
||||||
self.data = data_v3.generate_test_data()
|
self.data = data_v3.generate_test_data()
|
||||||
self.ks_client_module = client_v3
|
self.ks_client_module = client_v3
|
||||||
endpoint = settings.OPENSTACK_KEYSTONE_URL
|
|
||||||
self.keystone_client_unscoped = self.ks_client_module.Client(
|
|
||||||
endpoint=endpoint,
|
|
||||||
auth_ref=self.data.unscoped_access_info)
|
|
||||||
self.keystone_client_scoped = self.ks_client_module.Client(
|
|
||||||
endpoint=endpoint,
|
|
||||||
auth_ref=self.data.scoped_access_info)
|
|
||||||
settings.OPENSTACK_API_VERSIONS['identity'] = 3
|
settings.OPENSTACK_API_VERSIONS['identity'] = 3
|
||||||
settings.OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v3"
|
settings.OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v3"
|
||||||
|
|
||||||
|
self.mox.StubOutClassWithMocks(token_endpoint, 'Token')
|
||||||
|
self.mox.StubOutClassWithMocks(auth_v3, 'Token')
|
||||||
|
self.mox.StubOutClassWithMocks(auth_v3, 'Password')
|
||||||
|
self.mox.StubOutClassWithMocks(client_v3, 'Client')
|
||||||
|
|
||||||
def test_login(self):
|
def test_login(self):
|
||||||
projects = [self.data.project_one, self.data.project_two]
|
projects = [self.data.project_one, self.data.project_two]
|
||||||
user = self.data.user
|
user = self.data.user
|
||||||
@ -615,7 +662,6 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
project = self.data.project_two
|
project = self.data.project_two
|
||||||
projects = [self.data.project_one, self.data.project_two]
|
projects = [self.data.project_one, self.data.project_two]
|
||||||
user = self.data.user
|
user = self.data.user
|
||||||
unscoped = self.data.unscoped_access_info
|
|
||||||
scoped = self.data.scoped_access_info
|
scoped = self.data.scoped_access_info
|
||||||
sc = self.data.service_catalog
|
sc = self.data.service_catalog
|
||||||
et = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
|
et = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
|
||||||
@ -623,11 +669,12 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
form_data = self.get_form_data(user)
|
form_data = self.get_form_data(user)
|
||||||
|
|
||||||
self._mock_unscoped_client_list_projects(user, projects)
|
self._mock_unscoped_client_list_projects(user, projects)
|
||||||
self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id)
|
self._mock_scoped_client_for_tenant(scoped, self.data.project_one.id)
|
||||||
self._mock_scoped_client_for_tenant(
|
self._mock_scoped_client_for_tenant(
|
||||||
unscoped,
|
scoped,
|
||||||
project.id,
|
project.id,
|
||||||
url=sc.url_for(endpoint_type=et))
|
url=sc.url_for(endpoint_type=et),
|
||||||
|
client=False)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
@ -663,12 +710,12 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
def test_switch_region(self, next=None):
|
def test_switch_region(self, next=None):
|
||||||
projects = [self.data.project_one, self.data.project_two]
|
projects = [self.data.project_one, self.data.project_two]
|
||||||
user = self.data.user
|
user = self.data.user
|
||||||
unscoped = self.data.unscoped_access_info
|
scoped = self.data.unscoped_access_info
|
||||||
sc = self.data.service_catalog
|
sc = self.data.service_catalog
|
||||||
|
|
||||||
form_data = self.get_form_data(user)
|
form_data = self.get_form_data(user)
|
||||||
self._mock_unscoped_client_list_projects(user, projects)
|
self._mock_unscoped_client_list_projects(user, projects)
|
||||||
self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id)
|
self._mock_scoped_client_for_tenant(scoped, self.data.project_one.id)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
@ -710,17 +757,14 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
user = self.data.user
|
user = self.data.user
|
||||||
unscoped = self.data.unscoped_access_info
|
unscoped = self.data.unscoped_access_info
|
||||||
|
|
||||||
self._mock_unscoped_client_with_token(user, unscoped)
|
client = self._mock_unscoped_client_with_token(user, unscoped)
|
||||||
self._mock_unscoped_list_projects(user, projects)
|
self._mock_unscoped_list_projects(client, user, projects)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
project_list = utils.get_project_list(
|
project_list = utils.get_project_list(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
||||||
token=unscoped.auth_token,
|
token=unscoped.auth_token)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)
|
|
||||||
self.assertEqual(project_list, expected_projects)
|
self.assertEqual(project_list, expected_projects)
|
||||||
|
|
||||||
def test_tenant_list_caching(self):
|
def test_tenant_list_caching(self):
|
||||||
@ -729,18 +773,15 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
user = self.data.user
|
user = self.data.user
|
||||||
unscoped = self.data.unscoped_access_info
|
unscoped = self.data.unscoped_access_info
|
||||||
|
|
||||||
self._mock_unscoped_client_with_token(user, unscoped)
|
client = self._mock_unscoped_client_with_token(user, unscoped)
|
||||||
self._mock_unscoped_list_projects(user, projects)
|
self._mock_unscoped_list_projects(client, user, projects)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
project_list = utils.get_project_list(
|
project_list = utils.get_project_list(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
||||||
token=unscoped.auth_token,
|
token=unscoped.auth_token)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)
|
|
||||||
self.assertEqual(project_list, expected_projects)
|
self.assertEqual(project_list, expected_projects)
|
||||||
|
|
||||||
# Test to validate that requesting the project list again results
|
# Test to validate that requesting the project list again results
|
||||||
@ -750,10 +791,7 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin, test.TestCase):
|
|||||||
project_list = utils.get_project_list(
|
project_list = utils.get_project_list(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
auth_url=settings.OPENSTACK_KEYSTONE_URL,
|
||||||
token=unscoped.auth_token,
|
token=unscoped.auth_token)
|
||||||
insecure=False,
|
|
||||||
cacert=None,
|
|
||||||
debug=False)
|
|
||||||
self.assertEqual(project_list, expected_projects)
|
self.assertEqual(project_list, expected_projects)
|
||||||
|
|
||||||
utils.remove_project_cache(unscoped.auth_token)
|
utils.remove_project_cache(unscoped.auth_token)
|
||||||
|
@ -270,9 +270,6 @@ class User(models.AnonymousUser):
|
|||||||
@property
|
@property
|
||||||
def authorized_tenants(self):
|
def authorized_tenants(self):
|
||||||
"""Returns a memoized list of tenants this user may access."""
|
"""Returns a memoized list of tenants this user may access."""
|
||||||
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
|
|
||||||
ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
|
|
||||||
|
|
||||||
if self.is_authenticated() and self._authorized_tenants is None:
|
if self.is_authenticated() and self._authorized_tenants is None:
|
||||||
endpoint = self.endpoint
|
endpoint = self.endpoint
|
||||||
token = self.token
|
token = self.token
|
||||||
@ -280,10 +277,7 @@ class User(models.AnonymousUser):
|
|||||||
self._authorized_tenants = utils.get_project_list(
|
self._authorized_tenants = utils.get_project_list(
|
||||||
user_id=self.id,
|
user_id=self.id,
|
||||||
auth_url=endpoint,
|
auth_url=endpoint,
|
||||||
token=token.id,
|
token=token.id)
|
||||||
insecure=insecure,
|
|
||||||
cacert=ca_cert,
|
|
||||||
debug=settings.DEBUG)
|
|
||||||
except (keystone_exceptions.ClientException,
|
except (keystone_exceptions.ClientException,
|
||||||
keystone_exceptions.AuthorizationFailure):
|
keystone_exceptions.AuthorizationFailure):
|
||||||
LOG.exception('Unable to retrieve project list.')
|
LOG.exception('Unable to retrieve project list.')
|
||||||
|
@ -21,6 +21,10 @@ from django.contrib.auth import middleware
|
|||||||
from django.contrib.auth import models
|
from django.contrib.auth import models
|
||||||
from django.utils import decorators
|
from django.utils import decorators
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from keystoneclient.auth.identity import v2 as v2_auth
|
||||||
|
from keystoneclient.auth.identity import v3 as v3_auth
|
||||||
|
from keystoneclient.auth import token_endpoint
|
||||||
|
from keystoneclient import session
|
||||||
from keystoneclient.v2_0 import client as client_v2
|
from keystoneclient.v2_0 import client as client_v2
|
||||||
from keystoneclient.v3 import client as client_v3
|
from keystoneclient.v3 import client as client_v3
|
||||||
from six.moves.urllib import parse as urlparse
|
from six.moves.urllib import parse as urlparse
|
||||||
@ -152,6 +156,16 @@ def get_keystone_version():
|
|||||||
return getattr(settings, 'OPENSTACK_API_VERSIONS', {}).get('identity', 2.0)
|
return getattr(settings, 'OPENSTACK_API_VERSIONS', {}).get('identity', 2.0)
|
||||||
|
|
||||||
|
|
||||||
|
def get_session():
|
||||||
|
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
|
||||||
|
verify = getattr(settings, 'OPENSTACK_SSL_CACERT', True)
|
||||||
|
|
||||||
|
if insecure:
|
||||||
|
verify = False
|
||||||
|
|
||||||
|
return session.Session(verify=verify)
|
||||||
|
|
||||||
|
|
||||||
def get_keystone_client():
|
def get_keystone_client():
|
||||||
if get_keystone_version() < 3:
|
if get_keystone_version() < 3:
|
||||||
return client_v2
|
return client_v2
|
||||||
@ -180,20 +194,60 @@ def url_path_replace(url, old, new, count=None):
|
|||||||
scheme, netloc, path.replace(old, new, *args), query, fragment))
|
scheme, netloc, path.replace(old, new, *args), query, fragment))
|
||||||
|
|
||||||
|
|
||||||
|
def fix_auth_url_version(auth_url):
|
||||||
|
"""Fix up the auth url if an invalid version prefix was given.
|
||||||
|
|
||||||
|
People still give a v2 auth_url even when they specify that they want v3
|
||||||
|
authentication. Fix the URL to say v3. This should be smarter and take the
|
||||||
|
base, unversioned URL and discovery.
|
||||||
|
"""
|
||||||
|
if get_keystone_version() >= 3:
|
||||||
|
if has_in_url_path(auth_url, "/v2.0"):
|
||||||
|
LOG.warning("The settings.py file points to a v2.0 keystone "
|
||||||
|
"endpoint, but v3 is specified as the API version "
|
||||||
|
"to use. Using v3 endpoint for authentication.")
|
||||||
|
auth_url = url_path_replace(auth_url, "/v2.0", "/v3", 1)
|
||||||
|
|
||||||
|
return auth_url
|
||||||
|
|
||||||
|
|
||||||
|
def get_password_auth_plugin(auth_url, username, password, user_domain_name):
|
||||||
|
if get_keystone_version() >= 3:
|
||||||
|
return v3_auth.Password(auth_url=auth_url,
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
user_domain_name=user_domain_name)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return v2_auth.Password(auth_url=auth_url,
|
||||||
|
username=username,
|
||||||
|
password=password)
|
||||||
|
|
||||||
|
|
||||||
|
def get_token_auth_plugin(auth_url, token, project_id):
|
||||||
|
if get_keystone_version() >= 3:
|
||||||
|
return v3_auth.Token(auth_url=auth_url,
|
||||||
|
token=token,
|
||||||
|
project_id=project_id,
|
||||||
|
reauthenticate=False)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return v2_auth.Token(auth_url=auth_url,
|
||||||
|
token=token,
|
||||||
|
tenant_id=project_id,
|
||||||
|
reauthenticate=False)
|
||||||
|
|
||||||
|
|
||||||
@memoize_by_keyword_arg(_PROJECT_CACHE, ('token', ))
|
@memoize_by_keyword_arg(_PROJECT_CACHE, ('token', ))
|
||||||
def get_project_list(*args, **kwargs):
|
def get_project_list(*args, **kwargs):
|
||||||
|
sess = kwargs.get('session') or get_session()
|
||||||
|
auth_url = fix_auth_url_version(kwargs['auth_url'])
|
||||||
|
auth = token_endpoint.Token(auth_url, kwargs['token'])
|
||||||
|
client = get_keystone_client().Client(session=sess, auth=auth)
|
||||||
|
|
||||||
if get_keystone_version() < 3:
|
if get_keystone_version() < 3:
|
||||||
auth_url = url_path_replace(
|
|
||||||
kwargs.get('auth_url', ''), '/v3', '/v2.0', 1)
|
|
||||||
kwargs['auth_url'] = auth_url
|
|
||||||
client = get_keystone_client().Client(*args, **kwargs)
|
|
||||||
projects = client.tenants.list()
|
projects = client.tenants.list()
|
||||||
else:
|
else:
|
||||||
auth_url = url_path_replace(
|
|
||||||
kwargs.get('auth_url', ''), '/v2.0', '/v3', 1)
|
|
||||||
kwargs['auth_url'] = auth_url
|
|
||||||
client = get_keystone_client().Client(*args, **kwargs)
|
|
||||||
client.management_url = auth_url
|
|
||||||
projects = client.projects.list(user=kwargs.get('user_id'))
|
projects = client.projects.list(user=kwargs.get('user_id'))
|
||||||
|
|
||||||
projects.sort(key=lambda project: project.name.lower())
|
projects.sort(key=lambda project: project.name.lower())
|
||||||
|
@ -24,6 +24,7 @@ from django.utils import http
|
|||||||
from django.views.decorators.cache import never_cache # noqa
|
from django.views.decorators.cache import never_cache # noqa
|
||||||
from django.views.decorators.csrf import csrf_protect # noqa
|
from django.views.decorators.csrf import csrf_protect # noqa
|
||||||
from django.views.decorators.debug import sensitive_post_parameters # noqa
|
from django.views.decorators.debug import sensitive_post_parameters # noqa
|
||||||
|
from keystoneclient.auth import token_endpoint
|
||||||
from keystoneclient import exceptions as keystone_exceptions
|
from keystoneclient import exceptions as keystone_exceptions
|
||||||
|
|
||||||
from openstack_auth import forms
|
from openstack_auth import forms
|
||||||
@ -136,23 +137,21 @@ def logout(request, login_url=None, **kwargs):
|
|||||||
|
|
||||||
def delete_token(endpoint, token_id):
|
def delete_token(endpoint, token_id):
|
||||||
"""Delete a token."""
|
"""Delete a token."""
|
||||||
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
|
|
||||||
ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
|
|
||||||
utils.remove_project_cache(token_id)
|
utils.remove_project_cache(token_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if utils.get_keystone_version() >= 3:
|
endpoint = utils.fix_auth_url_version(endpoint)
|
||||||
if not utils.has_in_url_path(endpoint, '/v3'):
|
|
||||||
endpoint = utils.url_path_replace(endpoint, '/v2.0', '/v3', 1)
|
session = utils.get_session()
|
||||||
client = utils.get_keystone_client().Client(
|
auth_plugin = token_endpoint.Token(endpoint=endpoint,
|
||||||
endpoint=endpoint,
|
token=token_id)
|
||||||
token=token_id,
|
client = utils.get_keystone_client().Client(session=session,
|
||||||
insecure=insecure,
|
auth=auth_plugin)
|
||||||
cacert=ca_cert,
|
|
||||||
debug=settings.DEBUG)
|
|
||||||
if utils.get_keystone_version() >= 3:
|
if utils.get_keystone_version() >= 3:
|
||||||
client.tokens.revoke_token(token=token_id)
|
client.tokens.revoke_token(token=token_id)
|
||||||
else:
|
else:
|
||||||
client.tokens.delete(token=token_id)
|
client.tokens.delete(token=token_id)
|
||||||
|
|
||||||
LOG.info('Deleted token %s' % token_id)
|
LOG.info('Deleted token %s' % token_id)
|
||||||
except keystone_exceptions.ClientException:
|
except keystone_exceptions.ClientException:
|
||||||
LOG.info('Could not delete token')
|
LOG.info('Could not delete token')
|
||||||
@ -163,21 +162,15 @@ def switch(request, tenant_id, redirect_field_name=auth.REDIRECT_FIELD_NAME):
|
|||||||
"""Switches an authenticated user from one project to another."""
|
"""Switches an authenticated user from one project to another."""
|
||||||
LOG.debug('Switching to tenant %s for user "%s".'
|
LOG.debug('Switching to tenant %s for user "%s".'
|
||||||
% (tenant_id, request.user.username))
|
% (tenant_id, request.user.username))
|
||||||
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
|
|
||||||
ca_cert = getattr(settings, "OPENSTACK_SSL_CACERT", None)
|
endpoint = utils.fix_auth_url_version(request.user.endpoint)
|
||||||
endpoint = request.user.endpoint
|
session = utils.get_session()
|
||||||
|
auth = utils.get_token_auth_plugin(auth_url=endpoint,
|
||||||
|
token=request.user.token.id,
|
||||||
|
project_id=tenant_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if utils.get_keystone_version() >= 3:
|
auth_ref = auth.get_access(session)
|
||||||
if not utils.has_in_url_path(endpoint, '/v3'):
|
|
||||||
endpoint = utils.url_path_replace(endpoint, '/v2.0', '/v3', 1)
|
|
||||||
client = utils.get_keystone_client().Client(
|
|
||||||
tenant_id=tenant_id,
|
|
||||||
token=request.user.token.id,
|
|
||||||
auth_url=endpoint,
|
|
||||||
insecure=insecure,
|
|
||||||
cacert=ca_cert,
|
|
||||||
debug=settings.DEBUG)
|
|
||||||
auth_ref = client.auth_ref
|
|
||||||
msg = 'Project switch successful for user "%(username)s".' % \
|
msg = 'Project switch successful for user "%(username)s".' % \
|
||||||
{'username': request.user.username}
|
{'username': request.user.username}
|
||||||
LOG.info(msg)
|
LOG.info(msg)
|
||||||
|
Loading…
Reference in New Issue
Block a user