def _validate_user_token(self, user_token, retry=True):
        """Authenticate user using PKI

        :param user_token: user's token id
        :param retry: Ignored, as it is not longer relevant
        :return uncrypted body of the token if the token is valid
        :raise InvalidUserToken if token is rejected
        :no longer raises ServiceError since it no longer makes RPC

        """
        token_id = None

        try:
            token_id = cms.cms_hash_token(user_token)
            cached = self._cache_get(token_id)
            if cached:
                return cached
            if cms.is_ans1_token(user_token):
                verified = self.verify_signed_token(user_token)
                data = jsonutils.loads(verified)
            else:
                data = self.verify_uuid_token(user_token, retry)
            expires = confirm_token_not_expired(data)
            self._cache_put(token_id, data, expires)
            return data
        except NetworkError:
            self.LOG.debug('Token validation failure.', exc_info=True)
            self.LOG.warn("Authorization failed for token %s", token_id)
            raise InvalidUserToken('Token authorization failed')
        except Exception:
            self.LOG.debug('Token validation failure.', exc_info=True)
            if token_id:
                self._cache_store_invalid(token_id)
            self.LOG.warn("Authorization failed for token %s", token_id)
            raise InvalidUserToken('Token authorization failed')
    def test_fetch_revocation_list_with_expire(self):
        # first response to revocation list should return 401 Unauthorized
        # to pretend to be an expired token
        resp1 = FakeHTTPResponse(200, jsonutils.dumps({
            'access': {
                'token': {'id': 'admin_token2'},
            },
        }))
        resp2 = FakeHTTPResponse(401, jsonutils.dumps(''))
        resp3 = FakeHTTPResponse(200, jsonutils.dumps({
            'access': {
                'token': {'id': 'admin_token2'},
            },
        }))
        resp4 = FakeHTTPResponse(200, SIGNED_REVOCATION_LIST)

        # first get_admin_token() call
        FAKE_RESPONSE_STACK.append(resp1)
        # request revocation list, get "unauthorized" due to simulated expired
        # token
        FAKE_RESPONSE_STACK.append(resp2)
        # request a new admin_token
        FAKE_RESPONSE_STACK.append(resp3)
        # request revocation list, get the revocation list properly
        FAKE_RESPONSE_STACK.append(resp4)

        fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list())
        self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST)
Exemple #3
0
 def assertRequestBodyIs(self, body=None, json=None):
     last_request_body = self.requests.last_request.body
     if json:
         val = jsonutils.loads(last_request_body)
         self.assertEqual(json, val)
     elif body:
         self.assertEqual(body, last_request_body)
Exemple #4
0
def from_response(response, body=None):
    """Return an instance of a ClientException or subclass
    based on a requests response.

    Usage::

        resp = requests.request(...)
        if resp.status_code != 200:
            raise exception_from_response(resp, resp.text)
    """
    cls = _code_map.get(response.status_code, ClientException)
    if body is None:
        try:
            body = jsonutils.loads(response.text)
        except Exception:
            body = response.text

    if body:
        if hasattr(body, 'keys'):
            error = body[body.keys()[0]]
            message = error.get('message', None)
            details = error.get('details', None)
        else:
            # If we didn't get back a properly formed error message we
            # probably couldn't communicate with Keystone at all.
            message = "Unable to communicate with identity service: %s." % body
            details = None
        return cls(code=response.status_code, message=message, details=details)
    else:
        return cls(code=response.status_code)
def setUpModule(self):
    signing_path = CMSDIR
    with open(os.path.join(signing_path, 'auth_token_scoped.pem')) as f:
        self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
    with open(os.path.join(signing_path, 'auth_token_unscoped.pem')) as f:
        self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
    with open(os.path.join(signing_path, 'auth_token_revoked.pem')) as f:
        self.REVOKED_TOKEN = cms.cms_to_token(f.read())
    self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN)
    with open(os.path.join(signing_path, 'revocation_list.json')) as f:
        self.REVOCATION_LIST = jsonutils.loads(f.read())
    with open(os.path.join(signing_path, 'revocation_list.pem')) as f:
        self.VALID_SIGNED_REVOCATION_LIST = jsonutils.dumps(
            {'signed': f.read()})
    self.SIGNED_TOKEN_SCOPED_KEY =\
        cms.cms_hash_token(self.SIGNED_TOKEN_SCOPED)
    self.SIGNED_TOKEN_UNSCOPED_KEY =\
        cms.cms_hash_token(self.SIGNED_TOKEN_UNSCOPED)

    self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY] = {
        'access': {
            'token': {
                'id': self.SIGNED_TOKEN_SCOPED_KEY,
            },
            'user': {
                'id': 'user_id1',
                'name': 'user_name1',
                'tenantId': 'tenant_id1',
                'tenantName': 'tenant_name1',
                'roles': [
                    {
                        'name': 'role1'
                    },
                    {
                        'name': 'role2'
                    },
                ],
            },
        },
    }

    self.TOKEN_RESPONSES[SIGNED_TOKEN_UNSCOPED_KEY] = {
        'access': {
            'token': {
                'id': SIGNED_TOKEN_UNSCOPED_KEY,
            },
            'user': {
                'id': 'user_id1',
                'name': 'user_name1',
                'roles': [
                    {
                        'name': 'role1'
                    },
                    {
                        'name': 'role2'
                    },
                ],
            },
        },
    },
Exemple #6
0
def from_response(response, body=None):
    """Return an instance of a ClientException or subclass
    based on a requests response.

    Usage::

        resp = requests.request(...)
        if resp.status_code != 200:
            raise exception_from_response(resp, resp.text)
    """
    cls = _code_map.get(response.status_code, ClientException)
    if body is None:
        try:
            body = jsonutils.loads(response.text)
        except Exception:
            body = response.text

    if body:
        if hasattr(body, 'keys'):
            error = body[body.keys()[0]]
            message = error.get('message', None)
            details = error.get('details', None)
        else:
            # If we didn't get back a properly formed error message we
            # probably couldn't communicate with Keystone at all.
            message = "Unable to communicate with identity service: %s." % body
            details = None
        return cls(code=response.status_code, message=message, details=details)
    else:
        return cls(code=response.status_code)
    def _validate_user_token(self, user_token, retry=True):
        """Authenticate user using PKI

        :param user_token: user's token id
        :param retry: Ignored, as it is not longer relevant
        :return uncrypted body of the token if the token is valid
        :raise InvalidUserToken if token is rejected
        :no longer raises ServiceError since it no longer makes RPC

        """
        token_id = None

        try:
            token_id = cms.cms_hash_token(user_token)
            cached = self._cache_get(token_id)
            if cached:
                return cached
            if cms.is_ans1_token(user_token):
                verified = self.verify_signed_token(user_token)
                data = jsonutils.loads(verified)
            else:
                data = self.verify_uuid_token(user_token, retry)
            expires = confirm_token_not_expired(data)
            self._cache_put(token_id, data, expires)
            return data
        except NetworkError:
            self.LOG.debug('Token validation failure.', exc_info=True)
            self.LOG.warn("Authorization failed for token %s", token_id)
            raise InvalidUserToken('Token authorization failed')
        except Exception:
            self.LOG.debug('Token validation failure.', exc_info=True)
            if token_id:
                self._cache_store_invalid(token_id)
            self.LOG.warn("Authorization failed for token %s", token_id)
            raise InvalidUserToken('Token authorization failed')
    def _cache_get(self, token_id, ignore_expires=False):
        """Return token information from cache.

        If token is invalid raise InvalidUserToken
        return token only if fresh (not expired).
        """

        if self._cache and token_id:
            if self._memcache_security_strategy is None:
                key = CACHE_KEY_TEMPLATE % token_id
                serialized = self._cache.get(key)
            else:
                keys = memcache_crypt.derive_keys(
                    token_id,
                    self._memcache_secret_key,
                    self._memcache_security_strategy)
                cache_key = CACHE_KEY_TEMPLATE % (
                    memcache_crypt.get_cache_key(keys))
                raw_cached = self._cache.get(cache_key)
                try:
                    # unprotect_data will return None if raw_cached is None
                    serialized = memcache_crypt.unprotect_data(keys,
                                                               raw_cached)
                except Exception:
                    msg = 'Failed to decrypt/verify cache data'
                    self.LOG.exception(msg)
                    # this should have the same effect as data not
                    # found in cache
                    serialized = None

            if serialized is None:
                return None

            # Note that 'invalid' and (data, expires) are the only
            # valid types of serialized cache entries, so there is not
            # a collision with jsonutils.loads(serialized) == None.
            cached = jsonutils.loads(serialized)
            if cached == 'invalid':
                self.LOG.debug('Cached Token %s is marked unauthorized',
                               token_id)
                raise InvalidUserToken('Token authorization failed')

            data, expires = cached

            try:
                expires = timeutils.parse_isotime(expires)
            except ValueError:
                # Gracefully handle upgrade of expiration times from *nix
                # timestamps to ISO 8601 formatted dates by ignoring old cached
                # values.
                return

            expires = timeutils.normalize_time(expires)
            utcnow = timeutils.utcnow()
            if ignore_expires or utcnow < expires:
                self.LOG.debug('Returning cached token %s', token_id)
                return data
            else:
                self.LOG.debug('Cached Token %s seems expired', token_id)
    def _cache_get(self, token_id, ignore_expires=False):
        """Return token information from cache.

        If token is invalid raise InvalidUserToken
        return token only if fresh (not expired).
        """

        if self._cache and token_id:
            if self._memcache_security_strategy is None:
                key = CACHE_KEY_TEMPLATE % token_id
                serialized = self._cache.get(key)
            else:
                keys = memcache_crypt.derive_keys(
                    token_id, self._memcache_secret_key,
                    self._memcache_security_strategy)
                cache_key = CACHE_KEY_TEMPLATE % (
                    memcache_crypt.get_cache_key(keys))
                raw_cached = self._cache.get(cache_key)
                try:
                    # unprotect_data will return None if raw_cached is None
                    serialized = memcache_crypt.unprotect_data(
                        keys, raw_cached)
                except Exception:
                    msg = 'Failed to decrypt/verify cache data'
                    self.LOG.exception(msg)
                    # this should have the same effect as data not
                    # found in cache
                    serialized = None

            if serialized is None:
                return None

            # Note that 'invalid' and (data, expires) are the only
            # valid types of serialized cache entries, so there is not
            # a collision with jsonutils.loads(serialized) == None.
            cached = jsonutils.loads(serialized)
            if cached == 'invalid':
                self.LOG.debug('Cached Token %s is marked unauthorized',
                               token_id)
                raise InvalidUserToken('Token authorization failed')

            data, expires = cached

            try:
                expires = timeutils.parse_isotime(expires)
            except ValueError:
                # Gracefully handle upgrade of expiration times from *nix
                # timestamps to ISO 8601 formatted dates by ignoring old cached
                # values.
                return

            expires = timeutils.normalize_time(expires)
            utcnow = timeutils.utcnow()
            if ignore_expires or utcnow < expires:
                self.LOG.debug('Returning cached token %s', token_id)
                return data
            else:
                self.LOG.debug('Cached Token %s seems expired', token_id)
def setUpModule(self):
    signing_path = CMSDIR
    with open(os.path.join(signing_path, "auth_token_scoped.pem")) as f:
        self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
    with open(os.path.join(signing_path, "auth_token_unscoped.pem")) as f:
        self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
    with open(os.path.join(signing_path, "auth_v3_token_scoped.pem")) as f:
        self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read())
    with open(os.path.join(signing_path, "auth_token_revoked.pem")) as f:
        self.REVOKED_TOKEN = cms.cms_to_token(f.read())
    self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN)
    with open(os.path.join(signing_path, "auth_v3_token_revoked.pem")) as f:
        self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read())
    self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_v3_TOKEN)
    with open(os.path.join(signing_path, "revocation_list.json")) as f:
        self.REVOCATION_LIST = jsonutils.loads(f.read())
    with open(os.path.join(signing_path, "revocation_list.pem")) as f:
        self.VALID_SIGNED_REVOCATION_LIST = jsonutils.dumps({"signed": f.read()})
    self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token(self.SIGNED_TOKEN_SCOPED)
    self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token(self.SIGNED_TOKEN_UNSCOPED)
    self.SIGNED_v3_TOKEN_SCOPED_KEY = cms.cms_hash_token(self.SIGNED_v3_TOKEN_SCOPED)

    self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY] = {
        "access": {
            "token": {"id": self.SIGNED_TOKEN_SCOPED_KEY},
            "user": {
                "id": "user_id1",
                "name": "user_name1",
                "tenantId": "tenant_id1",
                "tenantName": "tenant_name1",
                "roles": [{"name": "role1"}, {"name": "role2"}],
            },
        }
    }

    self.TOKEN_RESPONSES[SIGNED_TOKEN_UNSCOPED_KEY] = (
        {
            "access": {
                "token": {"id": SIGNED_TOKEN_UNSCOPED_KEY},
                "user": {"id": "user_id1", "name": "user_name1", "roles": [{"name": "role1"}, {"name": "role2"}]},
            }
        },
    )

    self.TOKEN_RESPONSES[self.SIGNED_v3_TOKEN_SCOPED_KEY] = {
        "token": {
            "expires": "2999-01-01T00:00:10Z",
            "user": {"id": "user_id1", "name": "user_name1", "domain": {"id": "domain_id1", "name": "domain_name1"}},
            "project": {
                "id": "tenant_id1",
                "name": "tenant_name1",
                "domain": {"id": "domain_id1", "name": "domain_name1"},
            },
            "roles": [{"name": "role1"}, {"name": "role2"}],
            "catalog": {},
        }
    }
    def token_revocation_list(self, value):
        """Save a revocation list to memory and to disk.

        :param value: A json-encoded revocation list

        """
        self._token_revocation_list = jsonutils.loads(value)
        self.token_revocation_list_fetched_time = timeutils.utcnow()
        with open(self.revoked_file_name, 'w') as f:
            f.write(value)
    def assertRequestBodyIs(self, body=None, json=None):
        last_request_body = httpretty.last_request().body
        if six.PY3:
            last_request_body = last_request_body.decode('utf-8')

        if json:
            val = jsonutils.loads(last_request_body)
            self.assertEqual(json, val)
        elif body:
            self.assertEqual(body, last_request_body)
Exemple #13
0
    def token_revocation_list(self, value):
        """Save a revocation list to memory and to disk.

        :param value: A json-encoded revocation list

        """
        self._token_revocation_list = jsonutils.loads(value)
        self.token_revocation_list_fetched_time = timeutils.utcnow()
        with open(self.revoked_file_name, 'w') as f:
            f.write(value)
Exemple #14
0
    def assertRequestBodyIs(self, body=None, json=None):
        last_request_body = httpretty.last_request().body
        if six.PY3:
            last_request_body = last_request_body.decode('utf-8')

        if json:
            val = jsonutils.loads(last_request_body)
            self.assertEqual(json, val)
        elif body:
            self.assertEqual(body, last_request_body)
 def token_revocation_list(self):
     timeout = self.token_revocation_list_fetched_time + self.token_revocation_list_cache_timeout
     list_is_current = timeutils.utcnow() < timeout
     if list_is_current:
         # Load the list from disk if required
         if not self._token_revocation_list:
             with open(self.revoked_file_name, "r") as f:
                 self._token_revocation_list = jsonutils.loads(f.read())
     else:
         self.token_revocation_list = self.fetch_revocation_list()
     return self._token_revocation_list
Exemple #16
0
    def _decode_body(resp):
        if resp.text:
            try:
                body_resp = jsonutils.loads(resp.text)
            except (ValueError, TypeError):
                body_resp = None
                _logger.debug("Could not decode JSON from body: %s", resp.text)
        else:
            _logger.debug("No body was returned.")
            body_resp = None

        return body_resp
Exemple #17
0
    def _decode_body(resp):
        if resp.text:
            try:
                body_resp = jsonutils.loads(resp.text)
            except (ValueError, TypeError):
                body_resp = None
                _logger.debug("Could not decode JSON from body: %s" % resp.text)
        else:
            _logger.debug("No body was returned.")
            body_resp = None

        return body_resp
Exemple #18
0
 def token_revocation_list(self):
     timeout = (self.token_revocation_list_fetched_time +
                self.token_revocation_list_cache_timeout)
     list_is_current = timeutils.utcnow() < timeout
     if list_is_current:
         # Load the list from disk if required
         if not self._token_revocation_list:
             with open(self.revoked_file_name, 'r') as f:
                 self._token_revocation_list = jsonutils.loads(f.read())
     else:
         self.token_revocation_list = self.fetch_revocation_list()
     return self._token_revocation_list
def setUpModule(self):
    signing_path = CMSDIR
    with open(os.path.join(signing_path, 'auth_token_scoped.pem')) as f:
        self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
    with open(os.path.join(signing_path, 'auth_token_unscoped.pem')) as f:
        self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
    with open(os.path.join(signing_path, 'auth_token_revoked.pem')) as f:
        self.REVOKED_TOKEN = cms.cms_to_token(f.read())
    self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN)
    with open(os.path.join(signing_path, 'revocation_list.json')) as f:
        self.REVOCATION_LIST = jsonutils.loads(f.read())
    with open(os.path.join(signing_path, 'revocation_list.pem')) as f:
        self.VALID_SIGNED_REVOCATION_LIST = jsonutils.dumps(
            {'signed': f.read()})
    self.SIGNED_TOKEN_SCOPED_KEY =\
        cms.cms_hash_token(self.SIGNED_TOKEN_SCOPED)
    self.SIGNED_TOKEN_UNSCOPED_KEY =\
        cms.cms_hash_token(self.SIGNED_TOKEN_UNSCOPED)

    self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY] = {
        'access': {
            'token': {
                'id': self.SIGNED_TOKEN_SCOPED_KEY,
            },
            'user': {
                'id': 'user_id1',
                'name': 'user_name1',
                'tenantId': 'tenant_id1',
                'tenantName': 'tenant_name1',
                'roles': [
                    {'name': 'role1'},
                    {'name': 'role2'},
                ],
            },
        },
    }

    self.TOKEN_RESPONSES[SIGNED_TOKEN_UNSCOPED_KEY] = {
        'access': {
            'token': {
                'id': SIGNED_TOKEN_UNSCOPED_KEY,
            },
            'user': {
                'id': 'user_id1',
                'name': 'user_name1',
                'roles': [
                    {'name': 'role1'},
                    {'name': 'role2'},
                ],
            },
        },
    },
    def _cache_get(self, token_id, ignore_expires=False):
        """Return token information from cache.

        If token is invalid raise InvalidUserToken
        return token only if fresh (not expired).
        """

        if self._cache and token_id:
            if self._memcache_security_strategy is None:
                key = CACHE_KEY_TEMPLATE % token_id
                serialized = self._cache.get(key)
            else:
                keys = memcache_crypt.derive_keys(
                    token_id,
                    self._memcache_secret_key,
                    self._memcache_security_strategy)
                cache_key = CACHE_KEY_TEMPLATE % (
                    memcache_crypt.get_cache_key(keys))
                raw_cached = self._cache.get(cache_key)
                try:
                    # unprotect_data will return None if raw_cached is None
                    serialized = memcache_crypt.unprotect_data(keys,
                                                               raw_cached)
                except Exception:
                    msg = 'Failed to decrypt/verify cache data'
                    self.LOG.exception(msg)
                    # this should have the same effect as data not
                    # found in cache
                    serialized = None

            if serialized is None:
                return None

            # Note that 'invalid' and (data, expires) are the only
            # valid types of serialized cache entries, so there is not
            # a collision with jsonutils.loads(serialized) == None.
            cached = jsonutils.loads(serialized)
            if cached == 'invalid':
                self.LOG.debug('Cached Token %s is marked unauthorized',
                               token_id)
                raise InvalidUserToken('Token authorization failed')

            data, expires = cached
            if ignore_expires or time.time() < float(expires):
                self.LOG.debug('Returning cached token %s', token_id)
                return data
            else:
                self.LOG.debug('Cached Token %s seems expired', token_id)
Exemple #21
0
def get_token_for_user_and_project(test_domain, test_project, test_user):
    user_client = (
        client.Client(auth_url='http://localhost:5000/v3',
                      management_url='http://localhost:35357/v3',
                      user_id=test_user.id,
                      user_domain_id=test_domain.id,
                      password=test_user.name,
                      project_id=test_project.id,
                      project_domain_id=test_domain.id))
    token = user_client.auth_ref['auth_token']
    user_token = jsonutils.loads(
        cms.verify_token(
            token,
            '/etc/keystone/ssl/certs/signing_cert.pem',
            '/etc/keystone/ssl/certs/ca.pem'))
    return user_token
    def _json_request(self, method, path, body=None, additional_headers=None):
        """HTTP request helper used to make json requests.

        :param method: http method
        :param path: relative request url
        :param body: dict to encode to json as request body. Optional.
        :param additional_headers: dict of additional headers to send with
                                   http request. Optional.
        :return (http response object, response body parsed as json)
        :raise ServerError when unable to communicate with keystone

        """
        conn = self._get_http_connection()

        kwargs = {
            'headers': {
                'Content-type': 'application/json',
                'Accept': 'application/json',
            },
        }

        if additional_headers:
            kwargs['headers'].update(additional_headers)

        if body:
            kwargs['body'] = jsonutils.dumps(body)

        full_path = self.auth_admin_prefix + path
        try:
            conn.request(method, full_path, **kwargs)
            response = conn.getresponse()
            body = response.read()
        except Exception as e:
            self.LOG.error('HTTP connection exception: %s' % e)
            raise ServiceError('Unable to communicate with keystone')
        finally:
            conn.close()

        try:
            data = jsonutils.loads(body)
        except ValueError:
            self.LOG.debug('Keystone did not return json-encoded body')
            data = {}

        return response, data
Exemple #23
0
    def _json_request(self, method, path, body=None, additional_headers=None):
        """HTTP request helper used to make json requests.

        :param method: http method
        :param path: relative request url
        :param body: dict to encode to json as request body. Optional.
        :param additional_headers: dict of additional headers to send with
                                   http request. Optional.
        :return (http response object, response body parsed as json)
        :raise ServerError when unable to communicate with keystone

        """
        conn = self._get_http_connection()

        kwargs = {
            'headers': {
                'Content-type': 'application/json',
                'Accept': 'application/json',
            },
        }

        if additional_headers:
            kwargs['headers'].update(additional_headers)

        if body:
            kwargs['body'] = jsonutils.dumps(body)

        full_path = self.auth_admin_prefix + path
        try:
            conn.request(method, full_path, **kwargs)
            response = conn.getresponse()
            body = response.read()
        except Exception as e:
            self.LOG.error('HTTP connection exception: %s' % e)
            raise ServiceError('Unable to communicate with keystone')
        finally:
            conn.close()

        try:
            data = jsonutils.loads(body)
        except ValueError:
            self.LOG.debug('Keystone did not return json-encoded body')
            data = {}

        return response, data
    def request(self, url, method, body=None, **kwargs):
        """Send an http request with the specified characteristics.

        Wrapper around requests.request to handle tasks such as
        setting headers, JSON encoding/decoding, and error handling.
        """
        # Copy the kwargs so we can reuse the original in case of redirects
        request_kwargs = copy.copy(kwargs)
        request_kwargs.setdefault('headers', kwargs.get('headers', {}))

        if body:
            request_kwargs['headers']['Content-Type'] = 'application/json'
            request_kwargs['data'] = self.serialize(body)

        if self.cert:
            request_kwargs.setdefault('cert', self.cert)
        if self.timeout is not None:
            request_kwargs.setdefault('timeout', self.timeout)

        resp = request(url,
                       method,
                       original_ip=self.original_ip,
                       verify=self.verify_cert,
                       debug=self.debug_log,
                       **request_kwargs)

        if resp.text:
            try:
                body_resp = jsonutils.loads(resp.text)
            except (ValueError, TypeError):
                body_resp = None
                _logger.debug("Could not decode JSON from body: %s" %
                              resp.text)
        else:
            _logger.debug("No body was returned.")
            body_resp = None

        if resp.status_code in (301, 302, 305):
            # Redirected. Reissue the request to the new location.
            return self.request(resp.headers['location'], method, body,
                                **request_kwargs)

        return resp, body_resp
    def test_auth_url_token_authentication(self):
        fake_token = 'fake_token'
        fake_url = '/fake-url'
        fake_resp = {'result': True}

        self.stub_auth(json=self.TEST_RESPONSE_DICT)
        self.stub_url('GET', [fake_url], json=fake_resp,
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)

        cl = client.Client(auth_url=self.TEST_URL,
                           token=fake_token)
        body = jsonutils.loads(self.requests.last_request.body)
        self.assertEqual(body['auth']['identity']['token']['id'], fake_token)

        resp, body = cl.get(fake_url)
        self.assertEqual(fake_resp, body)

        token = self.requests.last_request.headers.get('X-Auth-Token')
        self.assertEqual(self.TEST_TOKEN, token)
    def request(self, *args, **kwargs):
        headers = kwargs.setdefault('headers', {})
        headers.setdefault('Accept', 'application/json')

        try:
            kwargs['json'] = kwargs.pop('body')
        except KeyError:
            pass

        resp = super(LegacyJsonAdapter, self).request(*args, **kwargs)

        body = None
        if resp.text:
            try:
                body = jsonutils.loads(resp.text)
            except ValueError:
                pass

        return resp, body
    def test_fetch_revocation_list_with_expire(self):
        self.set_middleware()

        # Get a token, then try to retrieve revocation list and get a 401.
        # Get a new token, try to retrieve revocation list and return 200.
        httpretty.register_uri(httpretty.POST, "%s/v2.0/tokens" % BASE_URI, body=FAKE_ADMIN_TOKEN)

        responses = [
            httpretty.Response(body="", status=401),
            httpretty.Response(body=client_fixtures.SIGNED_REVOCATION_LIST),
        ]

        httpretty.register_uri(httpretty.GET, "%s/v2.0/tokens/revoked" % BASE_URI, responses=responses)

        fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list())
        self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST)

        # Check that 4 requests have been made
        self.assertEqual(len(httpretty.httpretty.latest_requests), 4)
Exemple #28
0
    def test_auth_url_token_authentication(self):
        fake_token = "fake_token"
        fake_url = "/fake-url"
        fake_resp = {"result": True}

        self.stub_auth(json=self.TEST_RESPONSE_DICT)
        self.stub_url("GET", [fake_url], json=fake_resp, base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)

        cl = client.Client(auth_url=self.TEST_URL, token=fake_token)
        body = httpretty.last_request().body
        if six.PY3:
            body = body.decode("utf-8")
        body = jsonutils.loads(body)
        self.assertEqual(body["auth"]["token"]["id"], fake_token)

        resp, body = cl.get(fake_url)
        self.assertEqual(fake_resp, body)

        self.assertEqual(httpretty.last_request().headers.get("X-Auth-Token"), self.TEST_TOKEN)
    def request(self, *args, **kwargs):
        headers = kwargs.setdefault('headers', {})
        headers.setdefault('Accept', 'application/json')

        try:
            kwargs['json'] = kwargs.pop('body')
        except KeyError:
            pass

        resp = super(LegacyJsonAdapter, self).request(*args, **kwargs)

        body = None
        if resp.text:
            try:
                body = jsonutils.loads(resp.text)
            except ValueError:
                pass

        return resp, body
    def test_auth_url_token_authentication(self):
        fake_token = 'fake_token'
        fake_url = '/fake-url'
        fake_resp = {'result': True}

        self.stub_auth(json=self.TEST_RESPONSE_DICT)
        self.stub_url('GET', [fake_url], json=fake_resp,
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)

        cl = client.Client(auth_url=self.TEST_URL,
                           token=fake_token)
        json_body = jsonutils.loads(self.requests.last_request.body)
        self.assertEqual(json_body['auth']['token']['id'], fake_token)

        resp, body = cl.get(fake_url)
        self.assertEqual(fake_resp, body)

        token = self.requests.last_request.headers.get('X-Auth-Token')
        self.assertEqual(self.TEST_TOKEN, token)
    def request(self, url, method, body=None, **kwargs):
        """Send an http request with the specified characteristics.

        Wrapper around requests.request to handle tasks such as
        setting headers, JSON encoding/decoding, and error handling.
        """
        # Copy the kwargs so we can reuse the original in case of redirects
        _logger.debug("url in request is %s", url)
        request_kwargs = copy.copy(kwargs)
        request_kwargs.setdefault('headers', kwargs.get('headers', {}))

        if body:
            request_kwargs['headers']['Content-Type'] = 'application/json'
            request_kwargs['data'] = self.serialize(body)

        if self.cert:
            request_kwargs.setdefault('cert', self.cert)
        if self.timeout is not None:
            request_kwargs.setdefault('timeout', self.timeout)

        _logger.debug("url11111 is : %s", url)
        resp = request(url, method, original_ip=self.original_ip,
                       verify=self.verify_cert, debug=self.debug_log,
                       **request_kwargs)

        if resp.text:
            try:
                body_resp = jsonutils.loads(resp.text)
            except (ValueError, TypeError):
                body_resp = None
                _logger.debug("Could not decode JSON from body: %s"
                              % resp.text)
        else:
            _logger.debug("No body was returned.")
            body_resp = None

        if resp.status_code in (301, 302, 305):
            # Redirected. Reissue the request to the new location.
            return self.request(resp.headers['location'], method, body,
                                **request_kwargs)

        return resp, body_resp
    def _cache_get(self, policy, token):
        """Return policy information from cache.
        """

        if self._cache and policy:
            if self._memcache_security_strategy is None:
                key = CACHE_KEY_TEMPLATE
                try:
                   timestamp, serialized = self._cache.get(key)
                except: 
                   timestamp = None
                   serialized = None
            else:
                keys = memcache_crypt.derive_keys(
                    token,
                    self._memcache_secret_key,
                    self._memcache_security_strategy)
                try:
                    cache_key = CACHE_KEY_TEMPLATE % (
                        memcache_crypt.get_cache_key(keys))
                    raw_cached = self._cache.get(cache_key)
                    serialized = memcache_crypt.unprotect_data(keys,
                                                               raw_cached)
                except Exception:
                    msg = 'Failed to decrypt/verify cache data'
                    self.logger.exception(msg)
                    serialized = None

            #if serialized is None:
            #    return None

            if serialized and timestamp == policy[0]['timestamp']:
                cached = jsonutils.loads(serialized)
                self.logger.debug('Policy is synced')
                return cached
            else:
                #self.LOG.debug('Cached Policy %s seems expired', policy)
                new_policy = self._fetch_policy(token, policy[0])
                self._cache_store(new_policy)
                return new_policy['blob']
    def test_auth_url_token_authentication(self):
        fake_token = 'fake_token'
        fake_url = '/fake-url'
        fake_resp = {'result': True}

        self.stub_auth(json=self.TEST_RESPONSE_DICT)
        self.stub_url('GET', [fake_url], json=fake_resp,
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)

        cl = client.Client(auth_url=self.TEST_URL,
                           token=fake_token)
        body = httpretty.last_request().body
        if six.PY3:
            body = body.decode('utf-8')
        body = jsonutils.loads(body)
        self.assertEqual(body['auth']['token']['id'], fake_token)

        resp, body = cl.get(fake_url)
        self.assertEqual(fake_resp, body)

        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
                         self.TEST_TOKEN)
Exemple #34
0
    def test_auth_url_token_authentication(self):
        fake_token = 'fake_token'
        fake_url = '/fake-url'
        fake_resp = {'result': True}

        self.stub_auth(json=self.TEST_RESPONSE_DICT)
        self.stub_url('GET', [fake_url],
                      json=fake_resp,
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)

        cl = client.Client(auth_url=self.TEST_URL, token=fake_token)
        body = httpretty.last_request().body
        if six.PY3:
            body = body.decode('utf-8')
        body = jsonutils.loads(body)
        self.assertEqual(body['auth']['token']['id'], fake_token)

        resp, body = cl.get(fake_url)
        self.assertEqual(fake_resp, body)

        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
                         self.TEST_TOKEN)
    def _json_request(self, method, path, body=None, additional_headers=None):
        """HTTP request helper used to make json requests.

        :param method: http method
        :param path: relative request url
        :param body: dict to encode to json as request body. Optional.
        :param additional_headers: dict of additional headers to send with
                                   http request. Optional.
        :return (http response object, response body parsed as json)
        :raise ServerError when unable to communicate with keystone

        """
        kwargs = {
            'headers': {
                'Content-type': 'application/json',
                'Accept': 'application/json',
            },
        }

        if additional_headers:
            kwargs['headers'].update(additional_headers)

        if body:
            kwargs['data'] = jsonutils.dumps(body)

        path = self.auth_admin_prefix + path

        self.LOG.debug('Calling _http_request')
        response = self._http_request(method, path, **kwargs)

        try:
            data = jsonutils.loads(response.text)
        except ValueError:
            self.LOG.debug('Keystone did not return json-encoded body')
            data = {}

        return response, data
    def _json_request(self, method, path, body=None, additional_headers=None):
        """HTTP request helper used to make json requests.

        :param method: http method
        :param path: relative request url
        :param body: dict to encode to json as request body. Optional.
        :param additional_headers: dict of additional headers to send with
                                   http request. Optional.
        :return (http response object, response body parsed as json)
        :raise ServerError when unable to communicate with keystone

        """
        kwargs = {
            'headers': {
                'Content-type': 'application/json',
                'Accept': 'application/json',
            },
        }

        if additional_headers:
            kwargs['headers'].update(additional_headers)

        if body:
            kwargs['data'] = jsonutils.dumps(body)

        path = self.auth_admin_prefix + path

        response = self._http_request(method, path, **kwargs)

        try:
            data = jsonutils.loads(response.text)
        except ValueError:
            self.LOG.debug('Keystone did not return json-encoded body')
            data = {}

        return response, data
# in the signing subdirectory.  In order to keep the values consistent between
# the tests and the signed documents, we read them in for use in the tests.
with open(os.path.join(CMSDIR, "auth_token_scoped.pem")) as f:
    SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, "auth_token_unscoped.pem")) as f:
    SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, "auth_v3_token_scoped.pem")) as f:
    SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, "auth_token_revoked.pem")) as f:
    REVOKED_TOKEN = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, "auth_token_scoped_expired.pem")) as f:
    SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, "auth_v3_token_revoked.pem")) as f:
    REVOKED_v3_TOKEN = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, "revocation_list.json")) as f:
    REVOCATION_LIST = jsonutils.loads(f.read())
with open(os.path.join(CMSDIR, "revocation_list.pem")) as f:
    SIGNED_REVOCATION_LIST = jsonutils.dumps({"signed": f.read()})
with open(os.path.join(CERTDIR, "signing_cert.pem")) as f:
    SIGNING_CERT = f.read()
with open(os.path.join(CERTDIR, "cacert.pem")) as f:
    SIGNING_CA = f.read()

UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d"
UUID_TOKEN_NO_SERVICE_CATALOG = "8286720fbe4941e69fa8241723bb02df"
UUID_TOKEN_UNSCOPED = "731f903721c14827be7b2dc912af7776"
VALID_DIABLO_TOKEN = "b0cf19b55dbb4f20a6ee18e6c6cf1726"
v3_UUID_TOKEN_DEFAULT = "5603457654b346fdbb93437bfe76f2f1"
v3_UUID_TOKEN_UNSCOPED = "d34835fdaec447e695a0a024d84f8d79"
v3_UUID_TOKEN_DOMAIN_SCOPED = "e8a7b63aaa4449f38f0c5c05c3581792"
 def load_json(cls, data, default_rule=None):
     """Init a brain using json instead of a rules dictionary."""
     rules_dict = jsonutils.loads(data)
     return cls(rules=rules_dict, default_rule=default_rule)
# in the signing subdirectory.  In order to keep the values consistent between
# the tests and the signed documents, we read them in for use in the tests.
with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f:
    SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f:
    SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f:
    SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f:
    REVOKED_TOKEN = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f:
    SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f:
    REVOKED_v3_TOKEN = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'revocation_list.json')) as f:
    REVOCATION_LIST = jsonutils.loads(f.read())
with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f:
    SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()})
with open(os.path.join(CERTDIR, 'signing_cert.pem')) as f:
    SIGNING_CERT = f.read()
with open(os.path.join(CERTDIR, 'cacert.pem')) as f:
    SIGNING_CA = f.read()

UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d"
UUID_TOKEN_NO_SERVICE_CATALOG = '8286720fbe4941e69fa8241723bb02df'
UUID_TOKEN_UNSCOPED = '731f903721c14827be7b2dc912af7776'
VALID_DIABLO_TOKEN = 'b0cf19b55dbb4f20a6ee18e6c6cf1726'
v3_UUID_TOKEN_DEFAULT = '5603457654b346fdbb93437bfe76f2f1'
v3_UUID_TOKEN_UNSCOPED = 'd34835fdaec447e695a0a024d84f8d79'
v3_UUID_TOKEN_DOMAIN_SCOPED = 'e8a7b63aaa4449f38f0c5c05c3581792'
 def assertRequestBodyIs(self, body=None, json=None):
     if json:
         val = jsonutils.loads(httpretty.last_request().body)
         self.assertEqual(json, val)
     elif body:
         self.assertEqual(body, httpretty.last_request().body)
        if body:
            kwargs['body'] = jsonutils.dumps(body)

        full_path = self.auth_admin_prefix + path
        try:
            conn.request(method, full_path, **kwargs)
            response = conn.getresponse()
            body = response.read()
        except Exception, e:
            self.logger.error('HTTP connection exception: %s' % e)
            raise ServiceError('Unable to communicate with keystone')
        finally:
            conn.close()

        try:
            data = jsonutils.loads(body)
        except ValueError:
            self.logger.debug('Keystone did not return json-encoded body')
            data = {}

        return response, data

    def _request_admin_token(self):
        """Retrieve new token as admin user from keystone.

        :return token id upon success
        :raises ServerError when unable to communicate with keystone

        """
        params = {
            'auth': {
 def test_fetch_revocation_list(self):
     # auth_token uses v2 to fetch this, so don't allow the v3
     # tests to override the fake http connection
     self.set_fake_http(FakeHTTPConnection)
     fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list())
     self.assertEqual(fetched_list, REVOCATION_LIST)
 def test_fetch_revocation_list(self):
     fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list())
     self.assertEqual(fetched_list, REVOCATION_LIST)
 def test_fetch_revocation_list(self):
     # auth_token uses v2 to fetch this, so don't allow the v3
     # tests to override the fake http connection
     self.set_fake_http(FakeHTTPConnection)
     fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list())
     self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST)
 def test_fetch_revocation_list(self):
     # auth_token uses v2 to fetch this, so don't allow the v3
     # tests to override the fake http connection
     fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list())
     self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST)
 def assertRequestBodyIs(self, body=None, json=None):
     if json:
         val = jsonutils.loads(httpretty.last_request().body)
         self.assertEqual(json, val)
     elif body:
         self.assertEqual(body, httpretty.last_request().body)
    def setUp(self):
        super(Examples, self).setUp()

        # The data for several tests are signed using openssl and are stored in
        # files in the signing subdirectory.  In order to keep the values
        # consistent between the tests and the signed documents, we read them
        # in for use in the tests.

        with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f:
            self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f:
            self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f:
            self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f:
            self.REVOKED_TOKEN = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f:
            self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f:
            self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'revocation_list.json')) as f:
            self.REVOCATION_LIST = jsonutils.loads(f.read())
        with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f:
            self.SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()})

        self.SIGNING_CERT_FILE = os.path.join(CERTDIR, 'signing_cert.pem')
        with open(self.SIGNING_CERT_FILE) as f:
            self.SIGNING_CERT = f.read()

        self.KERBEROS_BIND = 'USER@REALM'

        self.SIGNING_KEY_FILE = os.path.join(KEYDIR, 'signing_key.pem')
        with open(self.SIGNING_KEY_FILE) as f:
            self.SIGNING_KEY = f.read()

        self.SIGNING_CA_FILE = os.path.join(CERTDIR, 'cacert.pem')
        with open(self.SIGNING_CA_FILE) as f:
            self.SIGNING_CA = f.read()

        self.UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d"
        self.UUID_TOKEN_NO_SERVICE_CATALOG = '8286720fbe4941e69fa8241723bb02df'
        self.UUID_TOKEN_UNSCOPED = '731f903721c14827be7b2dc912af7776'
        self.UUID_TOKEN_BIND = '3fc54048ad64405c98225ce0897af7c5'
        self.UUID_TOKEN_UNKNOWN_BIND = '8885fdf4d42e4fb9879e6379fa1eaf48'
        self.VALID_DIABLO_TOKEN = 'b0cf19b55dbb4f20a6ee18e6c6cf1726'
        self.v3_UUID_TOKEN_DEFAULT = '5603457654b346fdbb93437bfe76f2f1'
        self.v3_UUID_TOKEN_UNSCOPED = 'd34835fdaec447e695a0a024d84f8d79'
        self.v3_UUID_TOKEN_DOMAIN_SCOPED = 'e8a7b63aaa4449f38f0c5c05c3581792'
        self.v3_UUID_TOKEN_BIND = '2f61f73e1c854cbb9534c487f9bd63c2'
        self.v3_UUID_TOKEN_UNKNOWN_BIND = '7ed9781b62cd4880b8d8c6788ab1d1e2'

        revoked_token = self.REVOKED_TOKEN
        if isinstance(revoked_token, six.text_type):
            revoked_token = revoked_token.encode('utf-8')
        self.REVOKED_TOKEN_HASH = utils.hash_signed_token(revoked_token)
        self.REVOKED_TOKEN_LIST = (
            {'revoked': [{'id': self.REVOKED_TOKEN_HASH,
                          'expires': timeutils.utcnow()}]})
        self.REVOKED_TOKEN_LIST_JSON = jsonutils.dumps(self.REVOKED_TOKEN_LIST)

        revoked_v3_token = self.REVOKED_v3_TOKEN
        if isinstance(revoked_v3_token, six.text_type):
            revoked_v3_token = revoked_v3_token.encode('utf-8')
        self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(revoked_v3_token)
        self.REVOKED_v3_TOKEN_LIST = (
            {'revoked': [{'id': self.REVOKED_v3_TOKEN_HASH,
                          'expires': timeutils.utcnow()}]})
        self.REVOKED_v3_TOKEN_LIST_JSON = jsonutils.dumps(
            self.REVOKED_v3_TOKEN_LIST)

        self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token(
            self.SIGNED_TOKEN_SCOPED)
        self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token(
            self.SIGNED_TOKEN_UNSCOPED)
        self.SIGNED_v3_TOKEN_SCOPED_KEY = cms.cms_hash_token(
            self.SIGNED_v3_TOKEN_SCOPED)

        self.INVALID_SIGNED_TOKEN = (
            "MIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
            "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
            "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
            "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
            "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            "0000000000000000000000000000000000000000000000000000000000000000"
            "1111111111111111111111111111111111111111111111111111111111111111"
            "2222222222222222222222222222222222222222222222222222222222222222"
            "3333333333333333333333333333333333333333333333333333333333333333"
            "4444444444444444444444444444444444444444444444444444444444444444"
            "5555555555555555555555555555555555555555555555555555555555555555"
            "6666666666666666666666666666666666666666666666666666666666666666"
            "7777777777777777777777777777777777777777777777777777777777777777"
            "8888888888888888888888888888888888888888888888888888888888888888"
            "9999999999999999999999999999999999999999999999999999999999999999"
            "0000000000000000000000000000000000000000000000000000000000000000")

        # JSON responses keyed by token ID
        self.TOKEN_RESPONSES = {
            self.UUID_TOKEN_DEFAULT: {
                'access': {
                    'token': {
                        'id': self.UUID_TOKEN_DEFAULT,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                    'serviceCatalog': {}
                },
            },
            self.VALID_DIABLO_TOKEN: {
                'access': {
                    'token': {
                        'id': self.VALID_DIABLO_TOKEN,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenantId': 'tenant_id1',
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.UUID_TOKEN_UNSCOPED: {
                'access': {
                    'token': {
                        'id': self.UUID_TOKEN_UNSCOPED,
                        'expires': '2020-01-01T00:00:10.000123Z',
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.UUID_TOKEN_NO_SERVICE_CATALOG: {
                'access': {
                    'token': {
                        'id': 'valid-token',
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    }
                },
            },
            self.UUID_TOKEN_BIND: {
                'access': {
                    'token': {
                        'bind': {'kerberos': self.KERBEROS_BIND},
                        'id': self.UUID_TOKEN_BIND,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                    'serviceCatalog': {}
                },
            },
            self.UUID_TOKEN_UNKNOWN_BIND: {
                'access': {
                    'token': {
                        'bind': {'FOO': 'BAR'},
                        'id': self.UUID_TOKEN_UNKNOWN_BIND,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                    'serviceCatalog': {}
                },
            },
            self.v3_UUID_TOKEN_DEFAULT: {
                'token': {
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
            self.v3_UUID_TOKEN_UNSCOPED: {
                'token': {
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    }
                }
            },
            self.v3_UUID_TOKEN_DOMAIN_SCOPED: {
                'token': {
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'domain': {
                        'id': 'domain_id1',
                        'name': 'domain_name1',
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
            self.SIGNED_TOKEN_SCOPED_KEY: {
                'access': {
                    'token': {
                        'id': self.SIGNED_TOKEN_SCOPED_KEY,
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'tenantId': 'tenant_id1',
                        'tenantName': 'tenant_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.SIGNED_TOKEN_UNSCOPED_KEY: {
                'access': {
                    'token': {
                        'id': self.SIGNED_TOKEN_UNSCOPED_KEY,
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.SIGNED_v3_TOKEN_SCOPED_KEY: {
                'token': {
                    'expires': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1'},
                        {'name': 'role2'}
                    ],
                    'catalog': {}
                }
            },
            self.v3_UUID_TOKEN_BIND: {
                'token': {
                    'bind': {'kerberos': self.KERBEROS_BIND},
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
            self.v3_UUID_TOKEN_UNKNOWN_BIND: {
                'token': {
                    'bind': {'FOO': 'BAR'},
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
        }

        self.JSON_TOKEN_RESPONSES = dict([(k, jsonutils.dumps(v)) for k, v in
                                          six.iteritems(self.TOKEN_RESPONSES)])
    def setUp(self):
        super(Examples, self).setUp()

        # The data for several tests are signed using openssl and are stored in
        # files in the signing subdirectory.  In order to keep the values
        # consistent between the tests and the signed documents, we read them
        # in for use in the tests.

        with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f:
            self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f:
            self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f:
            self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f:
            self.REVOKED_TOKEN = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f:
            self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f:
            self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read())
        with open(os.path.join(CMSDIR, 'revocation_list.json')) as f:
            self.REVOCATION_LIST = jsonutils.loads(f.read())
        with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f:
            self.SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()})

        self.SIGNING_CERT_FILE = os.path.join(CERTDIR, 'signing_cert.pem')
        with open(self.SIGNING_CERT_FILE) as f:
            self.SIGNING_CERT = f.read()

        self.KERBEROS_BIND = 'USER@REALM'

        self.SIGNING_KEY_FILE = os.path.join(KEYDIR, 'signing_key.pem')
        with open(self.SIGNING_KEY_FILE) as f:
            self.SIGNING_KEY = f.read()

        self.SIGNING_CA_FILE = os.path.join(CERTDIR, 'cacert.pem')
        with open(self.SIGNING_CA_FILE) as f:
            self.SIGNING_CA = f.read()

        self.UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d"
        self.UUID_TOKEN_NO_SERVICE_CATALOG = '8286720fbe4941e69fa8241723bb02df'
        self.UUID_TOKEN_UNSCOPED = '731f903721c14827be7b2dc912af7776'
        self.UUID_TOKEN_BIND = '3fc54048ad64405c98225ce0897af7c5'
        self.UUID_TOKEN_UNKNOWN_BIND = '8885fdf4d42e4fb9879e6379fa1eaf48'
        self.VALID_DIABLO_TOKEN = 'b0cf19b55dbb4f20a6ee18e6c6cf1726'
        self.v3_UUID_TOKEN_DEFAULT = '5603457654b346fdbb93437bfe76f2f1'
        self.v3_UUID_TOKEN_UNSCOPED = 'd34835fdaec447e695a0a024d84f8d79'
        self.v3_UUID_TOKEN_DOMAIN_SCOPED = 'e8a7b63aaa4449f38f0c5c05c3581792'
        self.v3_UUID_TOKEN_BIND = '2f61f73e1c854cbb9534c487f9bd63c2'
        self.v3_UUID_TOKEN_UNKNOWN_BIND = '7ed9781b62cd4880b8d8c6788ab1d1e2'

        self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN)
        self.REVOKED_TOKEN_LIST = (
            {'revoked': [{'id': self.REVOKED_TOKEN_HASH,
                          'expires': timeutils.utcnow()}]})
        self.REVOKED_TOKEN_LIST_JSON = jsonutils.dumps(self.REVOKED_TOKEN_LIST)

        self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(
            self.REVOKED_v3_TOKEN)
        self.REVOKED_v3_TOKEN_LIST = (
            {'revoked': [{'id': self.REVOKED_v3_TOKEN_HASH,
                          'expires': timeutils.utcnow()}]})
        self.REVOKED_v3_TOKEN_LIST_JSON = jsonutils.dumps(
            self.REVOKED_v3_TOKEN_LIST)

        self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token(
            self.SIGNED_TOKEN_SCOPED)
        self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token(
            self.SIGNED_TOKEN_UNSCOPED)
        self.SIGNED_v3_TOKEN_SCOPED_KEY = cms.cms_hash_token(
            self.SIGNED_v3_TOKEN_SCOPED)

        self.INVALID_SIGNED_TOKEN = (
            "MIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
            "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
            "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
            "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
            "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            "0000000000000000000000000000000000000000000000000000000000000000"
            "1111111111111111111111111111111111111111111111111111111111111111"
            "2222222222222222222222222222222222222222222222222222222222222222"
            "3333333333333333333333333333333333333333333333333333333333333333"
            "4444444444444444444444444444444444444444444444444444444444444444"
            "5555555555555555555555555555555555555555555555555555555555555555"
            "6666666666666666666666666666666666666666666666666666666666666666"
            "7777777777777777777777777777777777777777777777777777777777777777"
            "8888888888888888888888888888888888888888888888888888888888888888"
            "9999999999999999999999999999999999999999999999999999999999999999"
            "0000000000000000000000000000000000000000000000000000000000000000")

        # JSON responses keyed by token ID
        self.TOKEN_RESPONSES = {
            self.UUID_TOKEN_DEFAULT: {
                'access': {
                    'token': {
                        'id': self.UUID_TOKEN_DEFAULT,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                    'serviceCatalog': {}
                },
            },
            self.VALID_DIABLO_TOKEN: {
                'access': {
                    'token': {
                        'id': self.VALID_DIABLO_TOKEN,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenantId': 'tenant_id1',
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.UUID_TOKEN_UNSCOPED: {
                'access': {
                    'token': {
                        'id': self.UUID_TOKEN_UNSCOPED,
                        'expires': '2020-01-01T00:00:10.000123Z',
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.UUID_TOKEN_NO_SERVICE_CATALOG: {
                'access': {
                    'token': {
                        'id': 'valid-token',
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    }
                },
            },
            self.UUID_TOKEN_BIND: {
                'access': {
                    'token': {
                        'bind': {'kerberos': self.KERBEROS_BIND},
                        'id': self.UUID_TOKEN_BIND,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                    'serviceCatalog': {}
                },
            },
            self.UUID_TOKEN_UNKNOWN_BIND: {
                'access': {
                    'token': {
                        'bind': {'FOO': 'BAR'},
                        'id': self.UUID_TOKEN_UNKNOWN_BIND,
                        'expires': '2020-01-01T00:00:10.000123Z',
                        'tenant': {
                            'id': 'tenant_id1',
                            'name': 'tenant_name1',
                        },
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                    'serviceCatalog': {}
                },
            },
            self.v3_UUID_TOKEN_DEFAULT: {
                'token': {
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
            self.v3_UUID_TOKEN_UNSCOPED: {
                'token': {
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    }
                }
            },
            self.v3_UUID_TOKEN_DOMAIN_SCOPED: {
                'token': {
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'domain': {
                        'id': 'domain_id1',
                        'name': 'domain_name1',
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
            self.SIGNED_TOKEN_SCOPED_KEY: {
                'access': {
                    'token': {
                        'id': self.SIGNED_TOKEN_SCOPED_KEY,
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'tenantId': 'tenant_id1',
                        'tenantName': 'tenant_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.SIGNED_TOKEN_UNSCOPED_KEY: {
                'access': {
                    'token': {
                        'id': self.SIGNED_TOKEN_UNSCOPED_KEY,
                    },
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'roles': [
                            {'name': 'role1'},
                            {'name': 'role2'},
                        ],
                    },
                },
            },
            self.SIGNED_v3_TOKEN_SCOPED_KEY: {
                'token': {
                    'expires': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1'},
                        {'name': 'role2'}
                    ],
                    'catalog': {}
                }
            },
            self.v3_UUID_TOKEN_BIND: {
                'token': {
                    'bind': {'kerberos': self.KERBEROS_BIND},
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
            self.v3_UUID_TOKEN_UNKNOWN_BIND: {
                'token': {
                    'bind': {'FOO': 'BAR'},
                    'expires_at': '2020-01-01T00:00:10.000123Z',
                    'user': {
                        'id': 'user_id1',
                        'name': 'user_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'project': {
                        'id': 'tenant_id1',
                        'name': 'tenant_name1',
                        'domain': {
                            'id': 'domain_id1',
                            'name': 'domain_name1'
                        }
                    },
                    'roles': [
                        {'name': 'role1', 'id': 'Role1'},
                        {'name': 'role2', 'id': 'Role2'},
                    ],
                    'catalog': {}
                }
            },
        }

        self.JSON_TOKEN_RESPONSES = dict([(k, jsonutils.dumps(v)) for k, v in
                                          six.iteritems(self.TOKEN_RESPONSES)])