summaryrefslogtreecommitdiff
path: root/keystoneclient/session.py
diff options
context:
space:
mode:
authorJamie Lennox <jamielennox@redhat.com>2014-12-12 11:55:02 +1000
committerJamie Lennox <jamielennox@redhat.com>2015-05-26 17:05:09 +1000
commit0ecf9b1ab5177fc42d16b4a57e8522769433b156 (patch)
tree53641915d36feb4bbd484df1f82f28754b9de323 /keystoneclient/session.py
parentdeeab3c164171ecdbc3a57e3fe5120f1454438d3 (diff)
downloadpython-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.py66
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.