Fix app cred create without project_id for domain admins
Users with domain admin role that are not cloud admins are not able to get scoped context and create an application credential with project_id, so this change forces the scoped context in that particular case. Closes-bug: #1827120 Change-Id: I076a97a6f943ab74a2db8bc5179a7db194009db4
This commit is contained in:
parent
a645545584
commit
6eeaf98524
@ -120,7 +120,7 @@ def _get_endpoint_url(request, endpoint_type, catalog=None):
|
|||||||
return url
|
return url
|
||||||
|
|
||||||
|
|
||||||
def keystoneclient(request, admin=False):
|
def keystoneclient(request, admin=False, force_scoped=False):
|
||||||
"""Returns a client connected to the Keystone backend.
|
"""Returns a client connected to the Keystone backend.
|
||||||
|
|
||||||
Several forms of authentication are supported:
|
Several forms of authentication are supported:
|
||||||
@ -152,7 +152,8 @@ def keystoneclient(request, admin=False):
|
|||||||
|
|
||||||
# If user is Cloud Admin, Domain Admin or Mixed Domain Admin and there
|
# If user is Cloud Admin, Domain Admin or Mixed Domain Admin and there
|
||||||
# is no domain context specified, use domain scoped token
|
# is no domain context specified, use domain scoped token
|
||||||
if is_domain_admin(request) and not is_domain_context_specified:
|
if (is_domain_admin(request) and not is_domain_context_specified and
|
||||||
|
not force_scoped):
|
||||||
domain_token = request.session.get('domain_token')
|
domain_token = request.session.get('domain_token')
|
||||||
if domain_token:
|
if domain_token:
|
||||||
token_id = getattr(domain_token, 'auth_token', None)
|
token_id = getattr(domain_token, 'auth_token', None)
|
||||||
@ -995,7 +996,17 @@ def application_credential_create(request, name, secret=None,
|
|||||||
roles=None, unrestricted=False,
|
roles=None, unrestricted=False,
|
||||||
access_rules=None):
|
access_rules=None):
|
||||||
user = request.user.id
|
user = request.user.id
|
||||||
manager = keystoneclient(request).application_credentials
|
# NOTE(ganso): users with domain admin role that are not cloud admins are
|
||||||
|
# not able to get scoped context and create an application credential with
|
||||||
|
# project_id, so only in this particular case we force a scoped context
|
||||||
|
force_scoped = False
|
||||||
|
if (request.user.project_id and request.session.get("domain_token") and
|
||||||
|
not policy.check(
|
||||||
|
(("identity", "identity:update_domain"),), request)):
|
||||||
|
force_scoped = True
|
||||||
|
|
||||||
|
manager = keystoneclient(
|
||||||
|
request, force_scoped=force_scoped).application_credentials
|
||||||
try:
|
try:
|
||||||
return manager.create(name=name, user=user, secret=secret,
|
return manager.create(name=name, user=user, secret=secret,
|
||||||
description=description, expires_at=expires_at,
|
description=description, expires_at=expires_at,
|
||||||
|
@ -21,6 +21,7 @@ from unittest import mock
|
|||||||
|
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
|
from openstack_dashboard import policy
|
||||||
from openstack_dashboard.test import helpers as test
|
from openstack_dashboard.test import helpers as test
|
||||||
|
|
||||||
|
|
||||||
@ -164,3 +165,46 @@ class APIVersionTests(test.APIMockTestCase):
|
|||||||
keystoneclient.session.get_endpoint_data.assert_called_once_with(
|
keystoneclient.session.get_endpoint_data.assert_called_once_with(
|
||||||
service_type='identity')
|
service_type='identity')
|
||||||
self.assertEqual((3, 10), api_version)
|
self.assertEqual((3, 10), api_version)
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationCredentialsAPITests(test.APIMockTestCase):
|
||||||
|
|
||||||
|
@mock.patch.object(policy, 'check')
|
||||||
|
@mock.patch.object(api.keystone, 'keystoneclient')
|
||||||
|
def test_application_credential_create_domain_token_removed(
|
||||||
|
self, mock_keystoneclient, mock_policy):
|
||||||
|
self.request.session['domain_token'] = 'some_token'
|
||||||
|
mock_policy.return_value = False
|
||||||
|
api.keystone.application_credential_create(self.request, None)
|
||||||
|
mock_keystoneclient.assert_called_once_with(
|
||||||
|
self.request, force_scoped=True)
|
||||||
|
|
||||||
|
@mock.patch.object(policy, 'check')
|
||||||
|
@mock.patch.object(api.keystone, 'keystoneclient')
|
||||||
|
def test_application_credential_create_domain_token_not_removed_policy_true(
|
||||||
|
self, mock_keystoneclient, mock_policy):
|
||||||
|
self.request.session['domain_token'] = 'some_token'
|
||||||
|
mock_policy.return_value = True
|
||||||
|
api.keystone.application_credential_create(self.request, None)
|
||||||
|
mock_keystoneclient.assert_called_once_with(
|
||||||
|
self.request, force_scoped=False)
|
||||||
|
|
||||||
|
@mock.patch.object(policy, 'check')
|
||||||
|
@mock.patch.object(api.keystone, 'keystoneclient')
|
||||||
|
def test_application_credential_create_domain_token_not_removed_no_token(
|
||||||
|
self, mock_keystoneclient, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
|
api.keystone.application_credential_create(self.request, None)
|
||||||
|
mock_keystoneclient.assert_called_once_with(
|
||||||
|
self.request, force_scoped=False)
|
||||||
|
|
||||||
|
@mock.patch.object(policy, 'check')
|
||||||
|
@mock.patch.object(api.keystone, 'keystoneclient')
|
||||||
|
def test_application_credential_create_domain_token_not_removed_no_project(
|
||||||
|
self, mock_keystoneclient, mock_policy):
|
||||||
|
self.request.session['domain_token'] = 'some_token'
|
||||||
|
mock_policy.return_value = True
|
||||||
|
self.request.user.project_id = None
|
||||||
|
api.keystone.application_credential_create(self.request, None)
|
||||||
|
mock_keystoneclient.assert_called_once_with(
|
||||||
|
self.request, force_scoped=False)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user