def process_token(self, region_name=None):
        """Extract and process information from the new auth_ref.

        And set the relevant authentication information.
        """
        # if we got a response without a service catalog, set the local
        # list of tenants for introspection, and leave to client user
        # to determine what to do. Otherwise, load up the service catalog
        if self.auth_ref.project_scoped:
            if not self.auth_ref.tenant_id:
                raise exceptions.AuthorizationFailure(
                    "Token didn't provide tenant_id")
            self._process_management_url(region_name)
            self.project_name = self.auth_ref.tenant_name
            self.project_id = self.auth_ref.tenant_id

        if not self.auth_ref.user_id:
            raise exceptions.AuthorizationFailure(
                "Token didn't provide user_id")

        self.user_id = self.auth_ref.user_id

        self.auth_domain_id = self.auth_ref.domain_id
        self.auth_tenant_id = self.auth_ref.tenant_id
        self.auth_user_id = self.auth_ref.user_id
    def get_auth_ref(self, session, **kwargs):
        headers = {'Accept': 'application/json'}
        body = {'auth': {'identity': {}}}
        ident = body['auth']['identity']

        for method in self.auth_methods:
            name, auth_data = method.get_auth_data(session, self, headers)
            ident.setdefault('methods', []).append(name)
            ident[name] = auth_data

        if not ident:
            raise exceptions.AuthorizationFailure('Authentication method '
                                                  'required (e.g. password)')

        mutual_exclusion = [
            bool(self.domain_id or self.domain_name),
            bool(self.project_id or self.project_name),
            bool(self.trust_id)
        ]

        if sum(mutual_exclusion) > 1:
            raise exceptions.AuthorizationFailure('Authentication cannot be '
                                                  'scoped to multiple '
                                                  'targets. Pick one of: '
                                                  'project, domain or trust')

        if self.domain_id:
            body['auth']['scope'] = {'domain': {'id': self.domain_id}}
        elif self.domain_name:
            body['auth']['scope'] = {'domain': {'name': self.domain_name}}
        elif self.project_id:
            body['auth']['scope'] = {'project': {'id': self.project_id}}
        elif self.project_name:
            scope = body['auth']['scope'] = {'project': {}}
            scope['project']['name'] = self.project_name

            if self.project_domain_id:
                scope['project']['domain'] = {'id': self.project_domain_id}
            elif self.project_domain_name:
                scope['project']['domain'] = {'name': self.project_domain_name}
        elif self.trust_id:
            body['auth']['scope'] = {'OS-TRUST:trust': {'id': self.trust_id}}

        resp = session.post(self.token_url,
                            json=body,
                            headers=headers,
                            authenticated=False)

        try:
            resp_data = resp.json()['token']
        except (KeyError, ValueError):
            raise exceptions.InvalidResponse(response=resp)

        return access.AccessInfoV3(resp.headers['X-Subject-Token'],
                                   **resp_data)
Exemple #3
0
    def get_raw_token_from_identity_service(self,
                                            auth_url,
                                            user_id=None,
                                            username=None,
                                            user_domain_id=None,
                                            user_domain_name=None,
                                            password=None,
                                            domain_id=None,
                                            domain_name=None,
                                            project_id=None,
                                            project_name=None,
                                            project_domain_id=None,
                                            project_domain_name=None,
                                            token=None,
                                            trust_id=None,
                                            **kwargs):
        """Authenticate against the v3 Identity API.

        :returns: access.AccessInfo if authentication was successful.
        :raises: AuthorizationFailure if unable to authenticate or validate
                 the existing authorization token
        :raises: Unauthorized if authentication fails due to invalid token

        """
        try:
            if auth_url is None:
                raise ValueError("Cannot authenticate without an auth_url")

            a = v3_auth.Auth._factory(auth_url,
                                      username=username,
                                      password=password,
                                      token=token,
                                      trust_id=trust_id,
                                      user_id=user_id,
                                      domain_id=domain_id,
                                      domain_name=domain_name,
                                      user_domain_id=user_domain_id,
                                      user_domain_name=user_domain_name,
                                      project_id=project_id,
                                      project_name=project_name,
                                      project_domain_id=project_domain_id,
                                      project_domain_name=project_domain_name)

            return a.get_auth_ref(self.session)
        except (exceptions.AuthorizationFailure, exceptions.Unauthorized):
            _logger.debug('Authorization failed.')
            raise
        except exceptions.EndpointNotFound:
            msg = 'There was no suitable authentication url for this request'
            raise exceptions.AuthorizationFailure(msg)
        except Exception as e:
            raise exceptions.AuthorizationFailure('Authorization failed: '
                                                  '%s' % e)
Exemple #4
0
    def get_raw_token_from_identity_service(self,
                                            auth_url,
                                            username=None,
                                            password=None,
                                            tenant_name=None,
                                            tenant_id=None,
                                            token=None,
                                            project_name=None,
                                            project_id=None,
                                            trust_id=None,
                                            **kwargs):
        """Authenticate against the v2 Identity API.

        If a token is provided it will be used in preference over username and
        password.

        :returns: access.AccessInfo if authentication was successful.
        :raises keystoneclient.exceptions.AuthorizationFailure: if unable to
            authenticate or validate the existing authorization token
        """
        try:
            if auth_url is None:
                raise ValueError(_("Cannot authenticate without an auth_url"))

            new_kwargs = {
                'trust_id': trust_id,
                'tenant_id': project_id or tenant_id,
                'tenant_name': project_name or tenant_name
            }

            if token:
                plugin = v2_auth.Token(auth_url, token, **new_kwargs)
            elif username and password:
                plugin = v2_auth.Password(auth_url, username, password,
                                          **new_kwargs)
            else:
                msg = _('A username and password or token is required.')
                raise exceptions.AuthorizationFailure(msg)

            return plugin.get_auth_ref(self.session)
        except (exceptions.AuthorizationFailure, exceptions.Unauthorized):
            _logger.debug("Authorization Failed.")
            raise
        except exceptions.EndpointNotFound:
            msg = (
                _('There was no suitable authentication url for this request'))
            raise exceptions.AuthorizationFailure(msg)
        except Exception as e:
            raise exceptions.AuthorizationFailure(
                _("Authorization Failed: %s") % e)
    def authenticate(self):
        """ Authenticate against the Identity API.

        Uses the data provided at instantiation to authenticate against
        the Keystone server. This may use either a username and password
        or token for authentication. If a tenant id was provided
        then the resulting authenticated client will be scoped to that
        tenant and contain a service catalog of available endpoints.

        Returns ``True`` if authentication was successful.
        """
        self.management_url = self.auth_url
        try:
            raw_token = self.tokens.authenticate(username=self.username,
                                                 tenant_id=self.tenant_id,
                                                 tenant_name=self.tenant_name,
                                                 password=self.password,
                                                 token=self.auth_token,
                                                 return_raw=True)
            self._extract_service_catalog(self.auth_url, raw_token)
            return True
        except (exceptions.AuthorizationFailure, exceptions.Unauthorized):
            _logger.debug("Authorization Failed.")
            raise
        except Exception, e:
            raise exceptions.AuthorizationFailure("Authorization Failed: "
                                                  "%s" % e)
    def _cs_request(self, url, method, management=True, **kwargs):
        """Makes an authenticated request to keystone endpoint by
        concatenating self.management_url and url and passing in method and
        any associated kwargs.
        """
        # NOTE(jamielennox): remember that if you use the legacy client mode
        # (you create a client without a session) then this HTTPClient object
        # is the auth plugin you are using. Values in the endpoint_filter may
        # be ignored and you should look at get_endpoint to figure out what.
        interface = 'admin' if management else 'public'
        endpoint_filter = kwargs.setdefault('endpoint_filter', {})
        endpoint_filter.setdefault('service_type', 'identity')
        endpoint_filter.setdefault('interface', interface)

        if self.version:
            endpoint_filter.setdefault('version', self.version)

        if self.region_name:
            endpoint_filter.setdefault('region_name', self.region_name)

        kwargs.setdefault('authenticated', None)
        try:
            return self.request(url, method, **kwargs)
        except exceptions.MissingAuthPlugin:
            _logger.info('Cannot get authenticated endpoint without an '
                         'auth plugin')
            raise exceptions.AuthorizationFailure(
                'Current authorization does not have a known management url')
Exemple #7
0
    def _extract_service_catalog(self, url, body):
        """ Set the client's service catalog from the response data. """
        self.service_catalog = service_catalog.ServiceCatalog(body)
        try:
            sc = self.service_catalog.get_token()
            self.auth_token = sc['id']
            # Save these since we have them and they'll be useful later
            # NOTE(termie): these used to be in the token and then were removed
            #               ... why?
            self.auth_tenant_id = sc.get('tenant_id')
            self.auth_user_id = sc.get('user_id')
        except KeyError:
            raise exceptions.AuthorizationFailure()

        # FIXME(ja): we should be lazy about setting managment_url.
        # in fact we should rewrite the client to support the service
        # catalog (api calls should be directable to any endpoints)
        try:
            self.management_url = self.service_catalog.url_for(
                attr='region',
                filter_value=self.region_name,
                endpoint_type='adminURL')
        except:
            # Unscoped tokens don't return a service catalog
            _logger.exception("unable to retrieve service catalog with token")
Exemple #8
0
    def get_raw_token_from_identity_service(self, auth_url, username=None,
                                            password=None, tenant_name=None,
                                            tenant_id=None, token=None,
                                            project_name=None, project_id=None,
                                            trust_id=None,
                                            **kwargs):
        """Authenticate against the v2 Identity API.

        :returns: access.AccessInfo if authentication was successful.
        :raises: AuthorizationFailure if unable to authenticate or validate
                 the existing authorization token
        """
        try:
            if auth_url is None:
                raise ValueError("Cannot authenticate without an auth_url")

            a = v2_auth.Auth.factory(auth_url,
                                     username=username,
                                     password=password,
                                     token=token,
                                     trust_id=trust_id,
                                     tenant_id=project_id or tenant_id,
                                     tenant_name=project_name or tenant_name)

            return a.get_auth_ref(self.session)
        except (exceptions.AuthorizationFailure, exceptions.Unauthorized):
            _logger.debug("Authorization Failed.")
            raise
        except Exception as e:
            raise exceptions.AuthorizationFailure("Authorization Failed: "
                                                  "%s" % e)
Exemple #9
0
    def test_retrieve_keystone_bad_client_authorization_error(self):
        url = 'myurl'
        tenant_id = '789012345'
        token = 'abcdefABCDEF'
        bttl = 5

        redis_client = fakeredis_connection()

        with mock.patch(
                'keystoneclient.v2_0.client.Client') as MockKeystoneClient:
            MockKeystoneClient.side_effect = exceptions.Unauthorized(
                'Mock - invalid client object')
            keystone_create_error = auth._retrieve_data_from_keystone(
                redis_client, url, tenant_id, token, bttl,
                self.default_max_cache_life)
            self.assertIsNone(keystone_create_error)

        with mock.patch(
                'keystoneclient.v2_0.client.Client') as MockKeystoneClient:
            MockKeystoneClient.side_effect = exceptions.AuthorizationFailure(
                'Mock - invalid client object')
            keystone_create_error = auth._retrieve_data_from_keystone(
                redis_client, url, tenant_id, token, bttl,
                self.default_max_cache_life)
            self.assertIsNone(keystone_create_error)
    def _factory(auth_url, **kwargs):
        """Construct a plugin appropriate to your available arguments.

        This function is intended as a convenience and backwards compatibility.
        If you know the style of authorization you require then you should
        construct that plugin directly.
        """

        methods = []

        # NOTE(jamielennox): kwargs extraction is outside the if statement to
        # clear up additional args that might be passed but not valid for type.
        method_kwargs = PasswordMethod._extract_kwargs(kwargs)
        if method_kwargs.get('password'):
            methods.append(PasswordMethod(**method_kwargs))

        method_kwargs = TokenMethod._extract_kwargs(kwargs)
        if method_kwargs.get('token'):
            methods.append(TokenMethod(**method_kwargs))

        if not methods:
            msg = 'A username and password or token is required.'
            raise exceptions.AuthorizationFailure(msg)

        return Auth(auth_url, methods, **kwargs)
Exemple #11
0
    def _send_idp_saml2_authn_request(self, session):
        """Present modified SAML2 authn assertion from the Service Provider."""

        self._prepare_idp_saml2_request(self.saml2_authn_request)
        idp_saml2_authn_request = self.saml2_authn_request

        # Currently HTTPBasicAuth method is hardcoded into the plugin
        idp_response = session.post(
            self.identity_provider_url,
            headers={'Content-type': 'text/xml'},
            data=etree.tostring(idp_saml2_authn_request),
            requests_auth=(self.username, self.password),
            authenticated=False,
            log=False)

        try:
            self.saml2_idp_authn_response = etree.XML(idp_response.content)
        except etree.XMLSyntaxError as e:
            msg = _("SAML2: Error parsing XML returned "
                    "from Identity Provider, reason: %s") % e
            raise exceptions.AuthorizationFailure(msg)

        idp_response_consumer_url = self.saml2_idp_authn_response.xpath(
            self.ECP_IDP_CONSUMER_URL, namespaces=self.ECP_SAML2_NAMESPACES)

        self.idp_response_consumer_url = self._first(idp_response_consumer_url)

        self._check_consumer_urls(session, self.idp_response_consumer_url,
                                  self.sp_response_consumer_url)
    def get_raw_token_from_identity_service(self,
                                            auth_url,
                                            username=None,
                                            password=None,
                                            tenant_name=None,
                                            tenant_id=None,
                                            token=None):
        """ Authenticate against the Keystone API.

        :returns: ``raw token`` if authentication was successful.
        :raises: AuthorizationFailure if unable to authenticate or validate
                 the existing authorization token
        :raises: ValueError if insufficient parameters are used.

        """
        try:
            return self._base_authN(auth_url,
                                    username=username,
                                    tenant_id=tenant_id,
                                    tenant_name=tenant_name,
                                    password=password,
                                    token=token)
        except (exceptions.AuthorizationFailure, exceptions.Unauthorized):
            _logger.debug("Authorization Failed.")
            raise
        except Exception as e:
            raise exceptions.AuthorizationFailure("Authorization Failed: "
                                                  "%s" % e)
    def _extract_service_catalog(self, url, body):
        """ Set the client's service catalog from the response data. """
        self.service_catalog = service_catalog.ServiceCatalog(body)
        try:
            sc = self.service_catalog.get_token()
            self.auth_token = sc['id']
            # Save these since we have them and they'll be useful later
            self.auth_tenant_id = sc.get('tenant_id')
            self.auth_user_id = sc.get('user_id')
        except KeyError:
            raise exceptions.AuthorizationFailure()

        # FIXME(ja): we should be lazy about setting managment_url.
        # in fact we should rewrite the client to support the service
        # catalog (api calls should be directable to any endpoints)
        try:
            self.management_url = self.service_catalog.url_for(
                attr='region',
                filter_value=self.region_name,
                endpoint_type='adminURL')
        except exceptions.EmptyCatalog:
            # Unscoped tokens don't return a service catalog;
            # allow those to pass while any other errors bubble up.
            pass
        except exceptions.EndpointNotFound:
            # the client shouldn't expect the authenticating user to
            # be authorized to view adminURL's, nor expect the identity
            # endpoint to publish one
            pass
Exemple #14
0
    def get_token(self, auth=None):
        """Return a token as provided by the auth plugin.

        :param auth: The auth plugin to use for token. Overrides the plugin
                     on the session. (optional)
        :type auth: :py:class:`keystoneclient.auth.base.BaseAuthPlugin`

        :raises keystoneclient.exceptions.AuthorizationFailure: if a new token
                                                                fetch fails.
        :raises keystoneclient.exceptions.MissingAuthPlugin: if a plugin is not
                                                             available.

        :returns: A valid token.
        :rtype: string
        """
        if not auth:
            auth = self.auth

        if not auth:
            raise exceptions.MissingAuthPlugin(_("Token Required"))

        try:
            return auth.get_token(self)
        except exceptions.HttpError as exc:
            raise exceptions.AuthorizationFailure(
                _("Authentication failure: %s") % exc)
Exemple #15
0
    def _access_service_provider(self, session):
        """Access protected endpoint and fetch unscoped token.

        After federated authentication workflow a protected endpoint should be
        accessible with the session object. The access is granted basing on the
        cookies stored within the session object. If, for some reason no
        cookies are present (quantity test) it means something went wrong and
        user will not be able to fetch an unscoped token. In that case an
        ``exceptions.AuthorizationFailure` exception is raised and no HTTP call
        is even made.

        :param session : a session object to send out HTTP requests.
        :type session: keystoneclient.session.Session

        :raises keystoneclient.exceptions.AuthorizationFailure: in case session
        object has empty cookie jar.

        """
        if self._cookies(session) is False:
            raise exceptions.AuthorizationFailure(
                _("Session object doesn't contain a cookie, therefore you are "
                  "not allowed to enter the Identity Provider's protected "
                  "area."))
        self.authenticated_response = session.get(self.token_url,
                                                  authenticated=False)
Exemple #16
0
    def test_keystone_request_raises_auth_failure_exception(
            self, mock_from_resp):

        kwargs = {
            "body": {
                "volume": {
                    "status": "creating",
                    "imageRef": "username",
                    "attach_status": "detached"
                },
                "authenticated": "True"
            }
        }

        with mock.patch.object(
                adapter.Adapter,
                'request',
                side_effect=keystone_exception.AuthorizationFailure()):
            mock_session = mock.Mock()
            mock_session.get_endpoint.return_value = fixture_base.VOLUME_V1_URL
            session_client = cinderclient.client.SessionClient(
                session=mock_session)
            self.assertRaises(keystone_exception.AuthorizationFailure,
                              session_client.request,
                              fixture_base.VOLUME_V1_URL, 'POST', **kwargs)

        # As keystonesession.request method will raise
        # AuthorizationFailure exception, check exceptions.from_response
        # is not getting called.
        self.assertFalse(mock_from_resp.called)
Exemple #17
0
    def get_auth_ref(self, session, **kwargs):
        headers = {}
        url = self.auth_url + "/auth/tokens"
        body = {'auth': {'identity': {}}}
        ident = body['auth']['identity']

        for method in self.auth_methods:
            method, auth_data = method.get_auth_data(headers)
            ident.setdefault('methods', []).append(method)
            ident[method] = auth_data

        if not ident:
            raise exceptions.AuthorizationFailure('Authentication method '
                                                  'required (e.g. password)')

        if ((self.domain_id or self.domain_name)
                and (self.project_id or self.project_name)):
            raise exceptions.AuthorizationFailure('Authentication cannot be '
                                                  'scoped to both domain '
                                                  'and project.')

        if self.domain_id:
            body['auth']['scope'] = {'domain': {'id': self.domain_id}}
        elif self.domain_name:
            body['auth']['scope'] = {'domain': {'name': self.domain_name}}
        elif self.project_id:
            body['auth']['scope'] = {'project': {'id': self.project_id}}
        elif self.project_name:
            scope = body['auth']['scope'] = {'project': {}}
            scope['project']['name'] = self.project_name

            if self.project_domain_id:
                scope['project']['domain'] = {'id': self.project_domain_id}
            elif self.project_domain_name:
                scope['project']['domain'] = {'name': self.project_domain_name}

        if self.trust_id:
            scope = body['auth'].setdefault('scope', {})
            scope['OS-TRUST:trust'] = {'id': self.trust_id}

        resp = session.post(url,
                            json=body,
                            headers=headers,
                            authenticated=False)
        return access.AccessInfoV3(resp.headers['X-Subject-Token'],
                                   **resp.json()['token'])
Exemple #18
0
 def str_to_xml(content, msg=None, include_exc=True):
     try:
         return etree.XML(content)
     except etree.XMLSyntaxError as e:
         if not msg:
             msg = str(e)
         else:
             msg = msg % e if include_exc else msg
         raise exceptions.AuthorizationFailure(msg)
    def authenticate(self, username=None, password=None, tenant_name=None,
                     tenant_id=None, auth_url=None, token=None):
        """ Authenticate against the Keystone API.

        Uses the data provided at instantiation to authenticate against
        the Keystone server. This may use either a username and password
        or token for authentication. If a tenant name or id was provided
        then the resulting authenticated client will be scoped to that
        tenant and contain a service catalog of available endpoints.

        With the v2.0 API, if a tenant name or ID is not provided, the
        authenication token returned will be 'unscoped' and limited in
        capabilities until a fully-scoped token is acquired.

        If successful, sets the self.auth_ref and self.auth_token with
        the returned token. If not already set, will also set
        self.management_url from the details provided in the token.

        :returns: ``True`` if authentication was successful.
        :raises: AuthorizationFailure if unable to authenticate or validate
                 the existing authorization token
        :raises: ValueError if insufficient parameters are used.
        """
        auth_url = auth_url or self.auth_url
        username = username or self.username
        password = password or self.password
        tenant_name = tenant_name or self.tenant_name
        tenant_id = tenant_id or self.tenant_id
        token = token or self.auth_token

        try:
            raw_token = self._base_authN(auth_url,
                                         username=username,
                                         tenant_id=tenant_id,
                                         tenant_name=tenant_name,
                                         password=password,
                                         token=token)
            self.auth_ref = access.AccessInfo(**raw_token)
            # if we got a response without a service catalog, set the local
            # list of tenants for introspection, and leave to client user
            # to determine what to do. Otherwise, load up the service catalog
            self.auth_token = self.auth_ref.auth_token
            if self.auth_ref.scoped:
                if self.management_url is None:
                    self.management_url = self.auth_ref.management_url[0]
                self.tenant_name = self.auth_ref.tenant_name
                self.tenant_id = self.auth_ref.tenant_id
                self.user_id = self.auth_ref.user_id
            self._extract_service_catalog(self.auth_url, self.auth_ref)
            return True
        except (exceptions.AuthorizationFailure, exceptions.Unauthorized):
            _logger.debug("Authorization Failed.")
            raise
        except Exception as e:
            raise exceptions.AuthorizationFailure("Authorization Failed: "
                                                  "%s" % e)
Exemple #20
0
 def _extract_service_catalog(self, url, body):
     """ Set the client's service catalog from the response data. """
     self.service_catalog = service_catalog.ServiceCatalog(body)
     try:
         sc = self.service_catalog.get_token()
         # Save these since we have them and they'll be useful later
         self.auth_tenant_id = sc.get('tenant_id')
         self.auth_user_id = sc.get('user_id')
     except KeyError:
         raise exceptions.AuthorizationFailure()
Exemple #21
0
    def get_raw_token_from_identity_service(self, auth_url, tenant_id, token):
        LOG.debug('URL: {0}'.format(auth_url))
        LOG.debug('Token: {0}'.format(token))
        LOG.debug('Tenant: {0}'.format(tenant_id))

        if token == 'valid_token' and tenant_id == 'valid_projectid':
            catalog_gen = servicecatalog.ServiceCatalogGenerator(
                token, tenant_id)
            catalog = catalog_gen.generate_full_catalog()['access']
            return access.AccessInfoV2(**catalog)
        else:
            if token == 'valid_token':
                raise exceptions.AuthorizationFailure(
                    'mocking - invalid project id')
            elif tenant_id == 'valid_projectid':
                raise exceptions.AuthorizationFailure(
                    'mocking - invalid token')
            else:
                raise exceptions.AuthorizationFailure(
                    'mocking - invalid or missing token or project id')
Exemple #22
0
        def a(a):
            if a == 1:
                raise keystone_exc.Unauthorized()

            if a == 2:
                raise keystone_exc.AuthorizationFailure()

            if a == 3:
                raise keystone_exc.ConnectionRefused()

            return a
Exemple #23
0
    def _get_adfs_security_token(self, session):
        """Send ADFS Security token to the ADFS server.

        Store the result in the instance attribute and raise an exception in
        case the response is not valid XML data.

        If a user cannot authenticate due to providing bad credentials, the
        ADFS2.0 server will return a HTTP 500 response and a XML Fault message.
        If ``exceptions.InternalServerError`` is caught, the method tries to
        parse the XML response.
        If parsing is unsuccessful, an ``exceptions.AuthorizationFailure`` is
        raised with a reason from the XML fault. Otherwise an original
        ``exceptions.InternalServerError`` is re-raised.

        :param session : a session object to send out HTTP requests.
        :type session: keystoneclient.session.Session

        :raises keystoneclient.exceptions.AuthorizationFailure: when HTTP
                 response from the ADFS server is not a valid XML ADFS security
                 token.
        :raises keystoneclient.exceptions.InternalServerError: If response
                 status code is HTTP 500 and the response XML cannot be
                 recognized.

        """
        def _get_failure(e):
            xpath = '/s:Envelope/s:Body/s:Fault/s:Code/s:Subcode/s:Value'
            content = e.response.content
            try:
                obj = self.str_to_xml(content).xpath(
                    xpath, namespaces=self.NAMESPACES)
                obj = self._first(obj)
                return obj.text
            # NOTE(marek-denis): etree.Element.xpath() doesn't raise an
            # exception, it just returns an empty list. In that case, _first()
            # will raise IndexError and we should treat it as an indication XML
            # is not valid. exceptions.AuthorizationFailure can be raised from
            # str_to_xml(), however since server returned HTTP 500 we should
            # re-raise exceptions.InternalServerError.
            except (IndexError, exceptions.AuthorizationFailure):
                raise e

        request_security_token = self.xml_to_str(self.prepared_request)
        try:
            response = session.post(url=self.identity_provider_url,
                                    headers=self.HEADER_SOAP,
                                    data=request_security_token,
                                    authenticated=False)
        except exceptions.InternalServerError as e:
            reason = _get_failure(e)
            raise exceptions.AuthorizationFailure(reason)
        msg = _("Error parsing XML returned from "
                "the ADFS Identity Provider, reason: %s")
        self.adfs_token = self.str_to_xml(response.content, msg)
Exemple #24
0
 def _extract_service_catalog(self, url, body):
     """ Set the client's service catalog from the response data. """
     self.service_catalog = service_catalog.ServiceCatalog(body)
     try:
         self.auth_token = self.service_catalog.get_token()
     except KeyError:
         raise exceptions.AuthorizationFailure()
     if self.project_id:
         # Unscoped tokens don't return a service catalog
         self.management_url = self.service_catalog.url_for(
             attr='region', filter_value=self.region_name)
     return self.service_catalog
    def process_token(self, **kwargs):
        """Extract and process information from the new auth_ref.

        And set the relevant authentication information.
        """
        super(Client, self).process_token(**kwargs)
        if self.auth_ref.domain_scoped:
            if not self.auth_ref.domain_id:
                raise exceptions.AuthorizationFailure(
                    "Token didn't provide domain_id")
            self._process_management_url(kwargs.get('region_name'))
            self.domain_name = self.auth_ref.domain_name
            self.domain_id = self.auth_ref.domain_id
 def _check_keystone_versions(self, url):
     """Calls Keystone URL and detects the available API versions."""
     try:
         client = httpclient.HTTPClient()
         resp, body = client.request(url,
                                     "GET",
                                     headers={'Accept': 'application/json'})
         # Multiple Choices status code is returned by the root
         # identity endpoint, with references to one or more
         # Identity API versions -- v3 spec
         # some cases we get No Content
         if resp.status_code in (200, 204, 300):
             try:
                 results = {}
                 if 'version' in body:
                     results['message'] = "Keystone found at %s" % url
                     version = body['version']
                     # Stable/diablo incorrect format
                     id, status, version_url = \
                         self._get_version_info(version, url)
                     results[str(id)] = {
                         "id": id,
                         "status": status,
                         "url": version_url
                     }
                     return results
                 elif 'versions' in body:
                     # Correct format
                     results['message'] = "Keystone found at %s" % url
                     for version in body['versions']['values']:
                         id, status, version_url = \
                             self._get_version_info(version, url)
                         results[str(id)] = {
                             "id": id,
                             "status": status,
                             "url": version_url
                         }
                     return results
                 else:
                     results['message'] = ("Unrecognized response from %s" %
                                           url)
                 return results
             except KeyError:
                 raise exceptions.AuthorizationFailure()
         elif resp.status_code == 305:
             return self._check_keystone_versions(resp['location'])
         else:
             raise exceptions.from_response(resp, "GET", url)
     except Exception as e:
         _logger.exception(e)
Exemple #27
0
    def _cs_request(self, url, method, **kwargs):
        """ Makes an authenticated request to keystone endpoint by
        concatenating self.management_url and url and passing in method and
        any associated kwargs. """

        if self.management_url is None:
            raise exceptions.AuthorizationFailure(
                'Current authorization does not have a known management url')
        kwargs.setdefault('headers', {})
        if self.auth_token:
            kwargs['headers']['X-Auth-Token'] = self.auth_token

        resp, body = self.request(self.management_url + url, method, **kwargs)
        return resp, body
Exemple #28
0
    def process_token(self):
        """Extract and process information from the new auth_ref.

        And set the relevant authentication information.
        """
        super(Client, self).process_token()
        if self.auth_ref.domain_scoped:
            if not self.auth_ref.domain_id:
                raise exceptions.AuthorizationFailure(
                    "Token didn't provide domain_id")
            if self.management_url is None and self.auth_ref.management_url:
                self.management_url = self.auth_ref.management_url[0]
            self.domain_name = self.auth_ref.domain_name
            self.domain_id = self.auth_ref.domain_id
Exemple #29
0
 def keystone_auth(auth_details):
     keystone = None
     try:
         if (int(auth_details['OS_IDENTITY_API_VERSION']) == 3 or
                 auth_details['OS_AUTH_URL'].endswith('v3')):
             keystone = k3_client.Client(
                 username=auth_details['OS_USERNAME'],
                 password=auth_details['OS_PASSWORD'],
                 user_domain_name=auth_details.get(
                     'OS_USER_DOMAIN_NAME',
                     'Default'
                 ),
                 project_domain_name=auth_details.get(
                     'OS_PROJECT_DOMAIN_NAME',
                     'Default'
                 ),
                 project_name=auth_details.get(
                     'OS_PROJECT_NAME',
                     'admin'
                 ),
                 auth_url=auth_details['OS_AUTH_URL'],
                 region_name=auth_details.get('OS_REGION_NAME'),
                 insecure=AUTH_DETAILS['OS_API_INSECURE']
             )
         else:
             keystone = k2_client.Client(
                 username=auth_details['OS_USERNAME'],
                 password=auth_details['OS_PASSWORD'],
                 tenant_name=auth_details['OS_TENANT_NAME'],
                 auth_url=auth_details['OS_AUTH_URL'],
                 region_name=auth_details['OS_REGION_NAME'],
                 insecure=AUTH_DETAILS['OS_API_INSECURE']
             )
     except Exception as e:
         metric_bool('client_success', False, m_name='maas_keystone')
         status_err(str(e), m_name='maas_keystone')
     else:
         if keystone:
             return keystone.auth_ref
         else:
             raise k_exc.AuthorizationFailure()
     finally:
         try:
             if keystone:
                 with open(TOKEN_FILE, 'w') as token_file:
                     json.dump(keystone.auth_ref, token_file)
         except IOError:
             # if we can't write the file we go on
             pass
Exemple #30
0
    def get_token(self):
        """Return a token as provided by the auth plugin.

        :raises AuthorizationFailure: if a new token fetch fails.

        :returns string: A valid token.
        """
        if not self.auth:
            raise exceptions.MissingAuthPlugin("Token Required")

        try:
            return self.auth.get_token(self)
        except exceptions.HTTPError as exc:
            raise exceptions.AuthorizationFailure("Authentication failure: "
                                                  "%s" % exc)