def test_revoke_token_with_access_info_instance(self):
     token_id = uuid.uuid4().hex
     token_ref = self.examples.TOKEN_RESPONSES[
         self.examples.v3_UUID_TOKEN_DEFAULT]
     token = access.AccessInfoV3(token_id, token_ref['token'])
     self.stub_url('DELETE', ['/auth/tokens'], status_code=204)
     self.client.tokens.revoke_token(token)
     self.assertRequestHeaderEqual('X-Subject-Token', token_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)
    def test_validate_token_with_access_info(self):
        # Can validate a token passing an access info.
        token_id = uuid.uuid4().hex
        token_ref = self.examples.TOKEN_RESPONSES[
            self.examples.v3_UUID_TOKEN_DEFAULT]
        token = access.AccessInfoV3(token_id, token_ref['token'])
        self.stub_url('GET', ['auth', 'tokens'],
                      headers={'X-Subject-Token': token_id, }, json=token_ref)
        access_info = self.client.tokens.validate(token)

        self.assertRequestHeaderEqual('X-Subject-Token', token_id)
        self.assertIsInstance(access_info, access.AccessInfoV3)
        self.assertEqual(token_id, access_info.auth_token)
Beispiel #4
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'])
Beispiel #5
0
    def get_unscoped_auth_ref(self, session):
        """Authenticate with OpenID Connect and get back claims.

        This is a multi-step process. First an access token must be retrieved,
        to do this, the username and password, the OpenID Connect client ID
        and secret, and the access token endpoint must be known.

        Secondly, we then exchange the access token upon accessing the
        protected Keystone endpoint (federated auth URL). This will trigger
        the OpenID Connect Provider to perform a user introspection and
        retrieve information (specified in the scope) about the user in
        the form of an OpenID Connect Claim. These claims will be sent
        to Keystone in the form of environment variables.

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

        :returns: a token data representation
        :rtype: :py:class:`keystoneclient.access.AccessInfo`
        """

        # get an access token
        client_auth = (self.client_id, self.client_secret)
        payload = {
            'grant_type': self.grant_type,
            'username': self.username,
            'password': self.password,
            'scope': self.scope
        }
        response = self._get_access_token(session, client_auth, payload,
                                          self.access_token_endpoint)
        access_token = response.json()['access_token']

        # use access token against protected URL
        headers = {'Authorization': 'Bearer ' + access_token}
        response = self._get_keystone_token(session, headers,
                                            self.federated_token_url)

        # grab the unscoped token
        token = response.headers['X-Subject-Token']
        token_json = response.json()['token']
        return access.AccessInfoV3(token, **token_json)
Beispiel #6
0
    def get_auth_ref(self, session, **kwargs):
        """Authenticate via SAML2 protocol and retrieve unscoped token.

        This is a multi-step process where a client does federated authn
        receives an unscoped token.

        Federated authentication utilizing SAML2 Enhanced Client or Proxy
        extension. See ``Saml2UnscopedToken_get_unscoped_token()``
        for more information on that step.
        Upon successful authentication and assertion mapping an
        unscoped token is returned and stored within the plugin object for
        further use.

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

        :return access.AccessInfoV3: an object with scoped token's id and
                                     unscoped token json included.

        """
        token, token_json = self._get_unscoped_token(session, **kwargs)
        return access.AccessInfoV3(token, **token_json)
Beispiel #7
0
    def get_auth_ref(self, session, **kwargs):
        headers = {'Accept': 'application/json'}
        body = {'auth': {'identity': {}}}
        ident = body['auth']['identity']
        rkwargs = {}

        for method in self.auth_methods:
            name, auth_data = method.get_auth_data(session,
                                                   self,
                                                   headers,
                                                   request_kwargs=rkwargs)
            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),
            bool(self.unscoped)
        ]

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

        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}}
        elif self.unscoped:
            body['auth']['scope'] = {'unscoped': {}}

        # NOTE(jamielennox): we add nocatalog here rather than in token_url
        # directly as some federation plugins require the base token_url
        token_url = self.token_url
        if not self.include_catalog:
            token_url += '?nocatalog'

        _logger.debug('Making authentication request to %s', token_url)
        resp = session.post(token_url,
                            json=body,
                            headers=headers,
                            authenticated=False,
                            log=False,
                            **rkwargs)

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

        return access.AccessInfoV3(resp.headers['X-Subject-Token'],
                                   **resp_data)
Beispiel #8
0
 def get_auth_ref(self, session, **kwargs):
     token, token_json = self._get_unscoped_token(session)
     return access.AccessInfoV3(token, **token_json)