diff options
Diffstat (limited to 'openstack_auth/plugin/k2k.py')
-rw-r--r-- | openstack_auth/plugin/k2k.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/openstack_auth/plugin/k2k.py b/openstack_auth/plugin/k2k.py new file mode 100644 index 0000000..03a85f0 --- /dev/null +++ b/openstack_auth/plugin/k2k.py @@ -0,0 +1,104 @@ +# 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. + +import logging + +from django.conf import settings +from django.utils.translation import ugettext_lazy as _ +from keystoneauth1.identity import v3 as v3_auth + +from openstack_auth import exceptions +from openstack_auth.plugin import base +from openstack_auth import utils + +LOG = logging.getLogger(__name__) + +__all__ = ['K2KAuthPlugin'] + + +class K2KAuthPlugin(base.BasePlugin): + + def get_plugin(self, service_provider=None, auth_url=None, plugins=[], + **kwargs): + """Authenticate using keystone to keystone federation. + + This plugin uses other v3 plugins to authenticate a user to a + identity provider in order to authenticate the user to a service + provider + + :param service_provider: service provider ID + :param auth_url: Keystone auth url + :param plugins: list of openstack_auth plugins to check + :returns Keystone2Keystone keystone auth plugin + """ + + # service_provider being None prevents infinite recursion + if utils.get_keystone_version() < 3 or not service_provider: + return None + + keystone_idp_id = getattr(settings, 'KEYSTONE_PROVIDER_IDP_ID', + 'localkeystone') + if service_provider == keystone_idp_id: + return None + + for plugin in plugins: + unscoped_idp_auth = plugin.get_plugin(plugins=plugins, + auth_url=auth_url, **kwargs) + if unscoped_idp_auth: + break + else: + LOG.debug('Could not find base authentication backend for ' + 'K2K plugin with the provided credentials.') + return None + + idp_exception = None + scoped_idp_auth = None + unscoped_auth_ref = base.BasePlugin.get_access_info( + self, unscoped_idp_auth) + try: + scoped_idp_auth, __ = self.get_project_scoped_auth( + unscoped_idp_auth, unscoped_auth_ref) + except exceptions.KeystoneAuthException as idp_excp: + idp_exception = idp_excp + + if not scoped_idp_auth or idp_exception: + msg = 'Identity provider authentication Failed.' + raise exceptions.KeystoneAuthException(msg) + + session = utils.get_session() + + if scoped_idp_auth.get_sp_auth_url(session, service_provider) is None: + msg = _('Could not find service provider ID on Keystone.') + raise exceptions.KeystoneAuthException(msg) + + unscoped_auth = v3_auth.Keystone2Keystone( + base_plugin=scoped_idp_auth, + service_provider=service_provider) + return unscoped_auth + + def get_access_info(self, unscoped_auth): + """Get the access info object + + We attempt to get the auth ref. If it fails and if the K2K auth plugin + was being used then we will prepend a message saying that the error was + on the service provider side. + :param: unscoped_auth: Keystone auth plugin for unscoped user + :returns: keystoneclient.access.AccessInfo object + """ + try: + unscoped_auth_ref = base.BasePlugin.get_access_info( + self, unscoped_auth) + except exceptions.KeystoneAuthException as excp: + msg = _('Service provider authentication failed. %s') + raise exceptions.KeystoneAuthException(msg % str(excp)) + return unscoped_auth_ref |