Backport scoped token fixes (bug 1592062)
Backported from OSC Idae368a11249f425b14b891fc68b4176e2b3e981 Change-Id: I263bb789b3b19306b81a3c72c11d0b1959542e4a
This commit is contained in:
parent
393a96c500
commit
9d466951e7
@ -130,8 +130,25 @@ def build_auth_params(auth_plugin_name, cmd_options):
|
||||
return (auth_plugin_loader, auth_params)
|
||||
|
||||
|
||||
def check_valid_auth_options(options, auth_plugin_name, required_scope=True):
|
||||
"""Perform basic option checking, provide helpful error messages.
|
||||
def check_valid_authorization_options(options, auth_plugin_name):
|
||||
"""Validate authorization options, and provide helpful error messages."""
|
||||
if (options.auth.get('project_id') and not
|
||||
options.auth.get('domain_id') and not
|
||||
options.auth.get('domain_name') and not
|
||||
options.auth.get('project_name') and not
|
||||
options.auth.get('tenant_id') and not
|
||||
options.auth.get('tenant_name')):
|
||||
raise exc.CommandError(_(
|
||||
'Missing parameter(s): '
|
||||
'Set either a project or a domain scope, but not both. Set a '
|
||||
'project scope with --os-project-name, OS_PROJECT_NAME, or '
|
||||
'auth.project_name. Alternatively, set a domain scope with '
|
||||
'--os-domain-name, OS_DOMAIN_NAME or auth.domain_name.'
|
||||
))
|
||||
|
||||
|
||||
def check_valid_authentication_options(options, auth_plugin_name):
|
||||
"""Validate authentication options, and provide helpful error messages
|
||||
|
||||
:param required_scope: indicate whether a scoped token is required
|
||||
|
||||
@ -149,18 +166,6 @@ def check_valid_auth_options(options, auth_plugin_name, required_scope=True):
|
||||
'Set an authentication URL, with --os-auth-url,'
|
||||
' OS_AUTH_URL or auth.auth_url'
|
||||
))
|
||||
if (required_scope and not
|
||||
options.auth.get('project_id') and not
|
||||
options.auth.get('domain_id') and not
|
||||
options.auth.get('domain_name') and not
|
||||
options.auth.get('project_name') and not
|
||||
options.auth.get('tenant_id') and not
|
||||
options.auth.get('tenant_name')):
|
||||
msgs.append(_(
|
||||
'Set a project scope with --os-project-name, OS_PROJECT_NAME '
|
||||
'or auth.project_name, or set a domain scope with '
|
||||
'--os-domain-name, OS_DOMAIN_NAME or auth.domain_name'
|
||||
))
|
||||
elif auth_plugin_name.endswith('token'):
|
||||
if not options.auth.get('token'):
|
||||
msgs.append(_(
|
||||
|
@ -140,7 +140,7 @@ class ClientManager(object):
|
||||
# prior to dereferrencing auth_ref.
|
||||
self._auth_setup_completed = False
|
||||
|
||||
def setup_auth(self, required_scope=True):
|
||||
def setup_auth(self):
|
||||
"""Set up authentication
|
||||
|
||||
:param required_scope: indicate whether a scoped token is required
|
||||
@ -157,9 +157,10 @@ class ClientManager(object):
|
||||
self.auth_plugin_name = auth.select_auth_plugin(self._cli_options)
|
||||
|
||||
# Basic option checking to avoid unhelpful error messages
|
||||
auth.check_valid_auth_options(self._cli_options,
|
||||
self.auth_plugin_name,
|
||||
required_scope=required_scope)
|
||||
auth.check_valid_authentication_options(
|
||||
self._cli_options,
|
||||
self.auth_plugin_name,
|
||||
)
|
||||
|
||||
# Horrible hack alert...must handle prompt for null password if
|
||||
# password auth is requested.
|
||||
@ -229,6 +230,22 @@ class ClientManager(object):
|
||||
|
||||
self._auth_setup_completed = True
|
||||
|
||||
def validate_scope(self):
|
||||
if self._auth_ref.project_id is not None:
|
||||
# We already have a project scope.
|
||||
return
|
||||
if self._auth_ref.domain_id is not None:
|
||||
# We already have a domain scope.
|
||||
return
|
||||
|
||||
# We do not have a scoped token (and the user's default project scope
|
||||
# was not implied), so the client needs to be explicitly configured
|
||||
# with a scope.
|
||||
auth.check_valid_authorization_options(
|
||||
self._cli_options,
|
||||
self.auth_plugin_name,
|
||||
)
|
||||
|
||||
@property
|
||||
def auth_ref(self):
|
||||
"""Dereference will trigger an auth if it hasn't already"""
|
||||
|
@ -425,9 +425,10 @@ class OpenStackShell(app.App):
|
||||
cmd.__class__.__name__,
|
||||
)
|
||||
if cmd.auth_required:
|
||||
if hasattr(cmd, 'required_scope'):
|
||||
self.client_manager.setup_auth()
|
||||
if hasattr(cmd, 'required_scope') and cmd.required_scope:
|
||||
# let the command decide whether we need a scoped token
|
||||
self.client_manager.setup_auth(cmd.required_scope)
|
||||
self.client_manager.validate_scope()
|
||||
# Trigger the Identity client to initialize
|
||||
self.client_manager.auth_ref
|
||||
return
|
||||
|
@ -388,8 +388,8 @@ class TestClientManager(utils.TestCase):
|
||||
client_manager.setup_auth,
|
||||
)
|
||||
|
||||
@mock.patch('osc_lib.api.auth.check_valid_auth_options')
|
||||
def test_client_manager_auth_setup_once(self, check_auth_options_func):
|
||||
@mock.patch('osc_lib.api.auth.check_valid_authentication_options')
|
||||
def test_client_manager_auth_setup_once(self, check_authn_options_func):
|
||||
client_manager = clientmanager.ClientManager(
|
||||
cli_options=FakeOptions(
|
||||
auth=dict(
|
||||
@ -403,11 +403,11 @@ class TestClientManager(utils.TestCase):
|
||||
)
|
||||
self.assertFalse(client_manager._auth_setup_completed)
|
||||
client_manager.setup_auth()
|
||||
self.assertTrue(check_auth_options_func.called)
|
||||
self.assertTrue(check_authn_options_func.called)
|
||||
self.assertTrue(client_manager._auth_setup_completed)
|
||||
|
||||
# now make sure we don't do auth setup the second time around
|
||||
# by checking whether check_valid_auth_options() gets called again
|
||||
check_auth_options_func.reset_mock()
|
||||
check_authn_options_func.reset_mock()
|
||||
client_manager.auth_ref
|
||||
check_auth_options_func.assert_not_called()
|
||||
check_authn_options_func.assert_not_called()
|
||||
|
Loading…
x
Reference in New Issue
Block a user