diff options
author | Jamie Lennox <jamielennox@redhat.com> | 2014-12-12 11:55:02 +1000 |
---|---|---|
committer | Jamie Lennox <jamielennox@redhat.com> | 2015-05-26 17:05:09 +1000 |
commit | 0ecf9b1ab5177fc42d16b4a57e8522769433b156 (patch) | |
tree | 53641915d36feb4bbd484df1f82f28754b9de323 /keystoneclient/session.py | |
parent | deeab3c164171ecdbc3a57e3fe5120f1454438d3 (diff) | |
download | python-keystoneclient-0ecf9b1ab5177fc42d16b4a57e8522769433b156.tar.gz |
Add get_communication_params interface to plugins
To allow authentication plugins such as using client certificates or
doing kerberos authentication with every request we need a way for the
plugins to manipulate the send parameters.
Change-Id: Ib9e81773ab988ea05869bc27097d2b25e963e59c
Blueprint: generic-plugins
Diffstat (limited to 'keystoneclient/session.py')
-rw-r--r-- | keystoneclient/session.py | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/keystoneclient/session.py b/keystoneclient/session.py index 0dbc065..06a1379 100644 --- a/keystoneclient/session.py +++ b/keystoneclient/session.py @@ -379,6 +379,19 @@ class Session(object): send = functools.partial(self._send_request, url, method, redirect, log, logger, connect_retries) + + try: + connection_params = self.get_auth_connection_params(auth=auth) + except exceptions.MissingAuthPlugin: + # NOTE(jamielennox): If we've gotten this far without an auth + # plugin then we should be happy with allowing no additional + # connection params. This will be the typical case for plugins + # anyway. + pass + else: + if connection_params: + kwargs.update(connection_params) + resp = send(**kwargs) # handle getting a 401 Unauthorized response by invalidating the plugin @@ -635,6 +648,59 @@ class Session(object): auth = self._auth_required(auth, msg) return auth.get_endpoint(self, **kwargs) + def get_auth_connection_params(self, auth=None, **kwargs): + """Return auth connection params as provided by the auth plugin. + + An auth plugin may specify connection parameters to the request like + providing a client certificate for communication. + + We restrict the values that may be returned from this function to + prevent an auth plugin overriding values unrelated to connection + parmeters. The values that are currently accepted are: + + - `cert`: a path to a client certificate, or tuple of client + certificate and key pair that are used with this request. + - `verify`: a boolean value to indicate verifying SSL certificates + against the system CAs or a path to a CA file to verify with. + + These values are passed to the requests library and further information + on accepted values may be found there. + + :param auth: The auth plugin to use for tokens. Overrides the plugin + on the session. (optional) + :type auth: keystoneclient.auth.base.BaseAuthPlugin + + :raises keystoneclient.exceptions.AuthorizationFailure: if a new token + fetch fails. + :raises keystoneclient.exceptions.MissingAuthPlugin: if a plugin is not + available. + :raises keystoneclient.exceptions.UnsupportedParameters: if the plugin + returns a parameter that is not supported by this session. + + :returns: Authentication headers or None for failure. + :rtype: dict + """ + msg = _('An auth plugin is required to fetch connection params') + auth = self._auth_required(auth, msg) + params = auth.get_connection_params(self, **kwargs) + + # NOTE(jamielennox): There needs to be some consensus on what + # parameters are allowed to be modified by the auth plugin here. + # Ideally I think it would be only the send() parts of the request + # flow. For now lets just allow certain elements. + params_copy = params.copy() + + for arg in ('cert', 'verify'): + try: + kwargs[arg] = params_copy.pop(arg) + except KeyError: + pass + + if params_copy: + raise exceptions.UnsupportedParameters(list(params_copy.keys())) + + return params + def invalidate(self, auth=None): """Invalidate an authentication plugin. |