Ian Cordasco e4a4a98496 Add functions for authenticating to Craton
This adds a cratonclient.auth with craton_auth and keystone_auth
functions to generate cratonclient.session.Session objects with
appropriate authentication plugins set-up.

Closes-bug: 1643961
Change-Id: I661a91241b96ca5c45a91a0add4f74c4ca7e6750
2016-12-06 11:26:09 -06:00

199 lines
6.8 KiB
Python

# Copyright (c) 2016 Rackspace
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Module that simplifies and unifies authentication for Craton."""
from keystoneauth1.identity.v3 import password as ksa_password
from keystoneauth1 import plugin
from keystoneauth1 import session as ksa_session
from cratonclient import exceptions as exc
def craton_auth(username, token, project_id, verify=True):
"""Configure a cratonclient Session to authenticate to Craton.
This will create, configure, and return a Session object that will use
Craton's built-in authentication method.
:param str username:
The username with which to authentiate against the API.
:param str token:
The token with which to authenticate against the API.
:param str project_id:
The project ID that the user belongs to.
:param bool verify:
(Optional) Whether or not to verify HTTPS certificates provided by the
server. Default: True
:returns:
Configured cratonclient session.
:rtype:
cratonclient.session.Session
Example:
.. code-block:: python
from cratonclient import auth
from cratonclient.v1 import client
craton = client.Client(session=auth.craton_auth(
username='demo',
token='demo',
project_id='b9f10eca66ac4c279c139d01e65f96b4',
))
"""
auth_plugin = CratonAuth(
username=username,
token=token,
project_id=project_id,
)
return create_session_with(auth_plugin, verify)
def keystone_auth(auth_url, username, password, verify=True,
project_name=None, project_id=None,
project_domain_name=None, project_domain_id=None,
user_domain_name=None, user_domain_id=None,
**auth_parameters):
r"""Configure a cratonclient Session to authenticate with Keystone.
This will create, configure, and return a Session using thet appropriate
Keystone authentication plugin to be able to communicate and authenticate
to Craton.
.. note::
Presently, this function supports only V3 Password based
authentication to Keystone. We also do not validate that you specify
required attributes. For example, Keystone will require you provide
``project_name`` or ``project_id`` but we will not enforce whether or
not you've specified one.
:param str auth_url:
The URL of the Keystone instance to authenticate to.
:param str username:
The username with which we will authenticate to Keystone.
:param str password:
The password used to authenticate to Keystone.
:param str project_name:
(Optional) The name of the project the user belongs to.
:param str project_id:
(Optional) The ID of the project the user belongs to.
:param str project_domain_name:
(Optional) The name of the project's domain.
:param str project_domain_id:
(Optional) The ID of the project's domain.
:param str user_domain_name:
(Optional) The name of the user's domain.
:param str user_domain_id:
(Optional) The ID of the user's domain.
:param bool verify:
(Optional) Whether or not to verify HTTPS certificates provided by the
server. Default: True
:param \*\*auth_parameters:
Any extra authentication parameters used to authenticate to Keystone.
See the Keystone documentation for usage of:
- ``trust_id``
- ``domain_id``
- ``domain_name``
- ``reauthenticate``
:returns:
Configured cratonclient session.
:rtype:
cratonclient.session.Session
Example:
.. code-block:: python
from cratonclient import auth
from cratonclient.v1 import client
craton = client.Client(session=auth.keystone_auth(
auth_url='https://keystone.cloud.org/v3',
username='admin',
password='s3cr373p@55w0rd',
project_name='admin',
project_domain_name='Default',
user_domain_name='Default',
))
"""
password_auth = ksa_password.Password(
auth_url=auth_url,
username=username,
password=password,
project_id=project_id,
project_name=project_name,
project_domain_id=project_domain_id,
project_domain_name=project_domain_name,
user_domain_id=user_domain_id,
user_domain_name=user_domain_name,
**auth_parameters
)
return create_session_with(password_auth, verify)
def create_session_with(auth_plugin, verify):
"""Create a cratonclient Session with the specified auth and verify values.
:param auth_plugin:
The authentication plugin to use with the keystoneauth1 Session
object.
:type auth_plugin:
keystoneauth1.plugin.BaseAuthPlugin
:param bool verify:
Whether or not to verify HTTPS certificates provided by the server.
:returns:
Configured cratonclient session.
:rtype:
cratonclient.session.Session
"""
from cratonclient import session
return session.Session(session=ksa_session.Session(
auth=auth_plugin,
verify=verify,
))
class CratonAuth(plugin.BaseAuthPlugin):
"""Custom authentication plugin for keystoneauth1.
This is specifically for the case where we're not using Keystone for
authentication.
"""
def __init__(self, username, project_id, token):
"""Initialize our craton authentication class."""
self.username = username
self.project_id = project_id
self.token = token
def get_token(self, session, **kwargs):
"""Return our token."""
return self.token
def get_headers(self, session, **kwargs):
"""Return the craton authentication headers."""
headers = super(CratonAuth, self).get_headers(session, **kwargs)
if headers is None:
# NOTE(sigmavirus24): This means that the token must be None. We
# should not allow this to go further. We're using built-in Craton
# authentication (not authenticating against Keystone) so we will
# be unable to authenticate.
raise exc.UnableToAuthenticate()
headers['X-Auth-User'] = self.username
headers['X-Auth-Project'] = '{}'.format(self.project_id)
return headers