def request(self, method, path, **kwargs):
        """Fakes out several http responses.

        If a POST request is made, we assume the calling code is trying
        to get a new admin token.

        If a GET request is made to validate a token, return success
        if the token is 'token1'. If a different token is provided, return
        a 404, indicating an unknown (therefore unauthorized) token.

        """
        FakeHTTPConnection.last_requested_url = path
        if method == 'POST':
            status = 200
            body = jsonutils.dumps({
                'access': {
                    'token': {'id': 'admin_token2'},
                },
            })

        else:
            token_id = path.rsplit('/', 1)[1]
            if token_id in TOKEN_RESPONSES.keys():
                status = 200
                body = jsonutils.dumps(TOKEN_RESPONSES[token_id])
            elif token_id == "revoked":
                status = 200
                body = SIGNED_REVOCATION_LIST
            else:
                status = 404
                body = str()

        self.resp = FakeHTTPResponse(status, body)
    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)
    def test_discovery_uses_plugin_cache(self):
        # register responses such that if the discovery URL is hit more than
        # once then the response will be invalid and not point to COMPUTE_ADMIN
        disc_body = jsonutils.dumps(self.TEST_DISCOVERY)
        disc_responses = [
            httpretty.Response(body=disc_body, status=200),
            httpretty.Response(body='', status=500)
        ]
        httpretty.register_uri(httpretty.GET,
                               self.TEST_COMPUTE_ADMIN,
                               responses=disc_responses)

        body = 'SUCCESS'
        self.stub_url(httpretty.GET, ['path'], body=body, status=200)

        # now either of the two sessions I use, it should not cause a second
        # request to the discovery url.
        sa = session.Session()
        sb = session.Session()
        auth = self.create_auth_plugin()

        for sess in (sa, sb):
            resp = sess.get('/path',
                            auth=auth,
                            endpoint_filter={
                                'service_type': 'compute',
                                'interface': 'admin',
                                'version': self.version
                            })

            self.assertEqual(200, resp.status_code)
            self.assertEqual(body, resp.text)
    def test_send_authn_response_to_sp(self):
        self.simple_http(
            'POST', self.SHIB_CONSUMER_URL,
            body=jsonutils.dumps(saml2_fixtures.UNSCOPED_TOKEN),
            content_type='application/json',
            status=200,
            headers={'X-Subject-Token': saml2_fixtures.UNSCOPED_TOKEN_HEADER})

        self.saml2plugin.relay_state = etree.XML(
            saml2_fixtures.SP_SOAP_RESPONSE).xpath(
                self.ECP_RELAY_STATE, namespaces=self.ECP_SAML2_NAMESPACES)[0]

        self.saml2plugin.saml2_idp_authn_response = etree.XML(
            saml2_fixtures.SAML2_ASSERTION)

        self.saml2plugin.idp_response_consumer_url = self.SHIB_CONSUMER_URL
        self.saml2plugin._send_service_provider_saml2_authn_response(
            self.session)
        token_json = self.saml2plugin.authenticated_response.json()['token']
        token = self.saml2plugin.authenticated_response.headers[
            'X-Subject-Token']
        self.assertEqual(saml2_fixtures.UNSCOPED_TOKEN['token'],
                         token_json)

        self.assertEqual(saml2_fixtures.UNSCOPED_TOKEN_HEADER,
                         token)
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 test_lesser_version_than_required(self):
     versions = fixture.DiscoveryList(BASE_URL, v3_id='v3.4')
     httpretty.register_uri(httpretty.GET,
                            BASE_URL,
                            status=200,
                            body=jsonutils.dumps(versions))
     self.assertVersionNotAvailable(auth_url=BASE_URL, version=(3, 6))
Пример #7
0
    def test_create_access_token_expires_at(self):
        verifier = uuid.uuid4().hex
        consumer_key = uuid.uuid4().hex
        consumer_secret = uuid.uuid4().hex
        request_key = uuid.uuid4().hex
        request_secret = uuid.uuid4().hex

        t = self._new_oauth_token_with_expires_at()
        access_key, access_secret, expires_at, resp_ref = t

        # NOTE(stevemar) The server expects the body to be JSON. Even though
        # the resp_ref is a string it is not a JSON string.
        self.stub_url(httpretty.POST, [self.path_prefix, 'access_token'],
                      status=201, body=jsonutils.dumps(resp_ref),
                      content_type='application/x-www-form-urlencoded')

        # Assert that the manager creates an access token object
        access_token = self.manager.create(consumer_key, consumer_secret,
                                           request_key, request_secret,
                                           verifier)
        self.assertIsInstance(access_token, self.model)
        self.assertEqual(access_key, access_token.key)
        self.assertEqual(access_secret, access_token.secret)
        self.assertEqual(expires_at, access_token.expires)

        req_headers = httpretty.last_request().headers
        oauth_client = oauth1.Client(consumer_key,
                                     client_secret=consumer_secret,
                                     resource_owner_key=request_key,
                                     resource_owner_secret=request_secret,
                                     signature_method=oauth1.SIGNATURE_HMAC,
                                     verifier=verifier,
                                     timestamp=expires_at)
        self._validate_oauth_headers(req_headers['Authorization'],
                                     oauth_client)
Пример #8
0
    def _http_log_response(self,
                           response=None,
                           json=None,
                           status_code=None,
                           headers=None,
                           text=None):
        if not _logger.isEnabledFor(logging.DEBUG):
            return

        if response:
            if not status_code:
                status_code = response.status_code
            if not headers:
                headers = response.headers
            if not text:
                text = response.text
        if json:
            text = jsonutils.dumps(json)

        string_parts = ['RESP:']

        if status_code:
            string_parts.append('[%s]' % status_code)
        if headers:
            for header in six.iteritems(headers):
                string_parts.append('%s: %s' % Session.process_header(header))
        if text:
            string_parts.append('\nRESP BODY: %s\n' % text)

        _logger.debug(' '.join(string_parts))
Пример #9
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, e:
            self.logger.error('HTTP connection exception: %s' % e)
            raise ServiceError('Unable to communicate with keystone')
Пример #10
0
    def _http_log_request(self,
                          url,
                          method=None,
                          data=None,
                          json=None,
                          headers=None):
        if not _logger.isEnabledFor(logging.DEBUG):
            # NOTE(morganfainberg): This whole debug section is expensive,
            # there is no need to do the work if we're not going to emit a
            # debug log.
            return

        string_parts = ['REQ: curl -i']

        # NOTE(jamielennox): None means let requests do its default validation
        # so we need to actually check that this is False.
        if self.verify is False:
            string_parts.append('--insecure')

        if method:
            string_parts.extend(['-X', method])

        string_parts.append(url)

        if headers:
            for header in six.iteritems(headers):
                string_parts.append('-H "%s: %s"' %
                                    Session.process_header(header))
        if json:
            data = jsonutils.dumps(json)
        if data:
            string_parts.append("-d '%s'" % data)

        _logger.debug(' '.join(string_parts))
    def test_available_cinder_data(self):
        body = jsonutils.dumps(CINDER_EXAMPLES)
        httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=body)

        v1_url = "%sv1/" % BASE_URL
        v2_url = "%sv2/" % BASE_URL

        disc = discover.Discover(auth_url=BASE_URL)
        versions = disc.version_data()

        self.assertEqual((1, 0), versions[0]['version'])
        self.assertEqual('CURRENT', versions[0]['raw_status'])
        self.assertEqual(v1_url, versions[0]['url'])
        self.assertEqual((2, 0), versions[1]['version'])
        self.assertEqual('CURRENT', versions[1]['raw_status'])
        self.assertEqual(v2_url, versions[1]['url'])

        version = disc.data_for('v2.0')
        self.assertEqual((2, 0), version['version'])
        self.assertEqual('CURRENT', version['raw_status'])
        self.assertEqual(v2_url, version['url'])

        version = disc.data_for(1)
        self.assertEqual((1, 0), version['version'])
        self.assertEqual('CURRENT', version['raw_status'])
        self.assertEqual(v1_url, version['url'])

        self.assertIsNone(disc.url_for('v3'))
        self.assertEqual(v2_url, disc.url_for('v2'))
        self.assertEqual(v1_url, disc.url_for('v1'))
 def test_is_signed_token_revoked_returns_false(self):
     #explicitly setting an empty revocation list here to document intent
     self.middleware.token_revocation_list = jsonutils.dumps(
         {"revoked": [], "extra": "success"})
     result = self.middleware.is_signed_token_revoked(
         self.token_dict['revoked_token'])
     self.assertFalse(result)
    def _cache_store(self, token_id, data):
        """Store value into memcache.

        data may be the string 'invalid' or a tuple like (data, expires)

        """
        serialized_data = jsonutils.dumps(data)
        if self._memcache_security_strategy is None:
            cache_key = CACHE_KEY_TEMPLATE % token_id
            data_to_store = serialized_data
        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)
            data_to_store = memcache_crypt.protect_data(keys, serialized_data)

        # Historically the swift cache conection used the argument
        # timeout= for the cache timeout, but this has been unified
        # with the official python memcache client with time= since
        # grizzly, we still need to handle folsom for a while until
        # this could get removed.
        try:
            self._cache.set(cache_key,
                            data_to_store,
                            time=self.token_cache_time)
        except(TypeError):
            self._cache.set(cache_key,
                            data_to_store,
                            timeout=self.token_cache_time)
    def test_allow_experimental(self):
        status = 'experimental'
        version_list = [{
            'id': 'v3.0',
            'links': [{
                'href': V3_URL,
                'rel': 'self'
            }],
            'media-types': V3_MEDIA_TYPES,
            'status': status,
            'updated': UPDATED
        }]
        body = jsonutils.dumps({'versions': version_list})
        httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)

        disc = discover.Discover(auth_url=BASE_URL)

        versions = disc.version_data()
        self.assertEqual(0, len(versions))

        versions = disc.version_data(allow_experimental=True)
        self.assertEqual(1, len(versions))
        self.assertEqual(status, versions[0]['raw_status'])
        self.assertEqual(V3_URL, versions[0]['url'])
        self.assertEqual((3, 0), versions[0]['version'])
Пример #15
0
    def _http_log_request(self, url, method=None, data=None,
                          json=None, headers=None):
        if not _logger.isEnabledFor(logging.DEBUG):
            # NOTE(morganfainberg): This whole debug section is expensive,
            # there is no need to do the work if we're not going to emit a
            # debug log.
            return

        string_parts = ['REQ: curl -i']

        # NOTE(jamielennox): None means let requests do its default validation
        # so we need to actually check that this is False.
        if self.verify is False:
            string_parts.append('--insecure')

        if method:
            string_parts.extend(['-X', method])

        string_parts.append(url)

        if headers:
            for header in six.iteritems(headers):
                string_parts.append('-H "%s: %s"'
                                    % Session.process_header(header))
        if json:
            data = jsonutils.dumps(json)
        if data:
            string_parts.append("-d '%s'" % data)

        _logger.debug(' '.join(string_parts))
    def test_ignoring_invalid_lnks(self):
        version_list = [{'id': 'v3.0',
                         'links': [{'href': V3_URL, 'rel': 'self'}],
                         'media-types': V3_MEDIA_TYPES,
                         'status': 'stable',
                         'updated': UPDATED},
                        {'id': 'v3.1',
                         'media-types': V3_MEDIA_TYPES,
                         'status': 'stable',
                         'updated': UPDATED},
                        {'media-types': V3_MEDIA_TYPES,
                         'status': 'stable',
                         'updated': UPDATED,
                         'links': [{'href': V3_URL, 'rel': 'self'}],
                         }]

        body = jsonutils.dumps({'versions': version_list})
        httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)

        disc = discover.Discover(auth_url=BASE_URL)

        # raw_version_data will return all choices, even invalid ones
        versions = disc.raw_version_data()
        self.assertEqual(3, len(versions))

        # only the version with both id and links will be actually returned
        versions = disc.version_data()
        self.assertEqual(1, len(versions))
    def test_discovery_uses_plugin_cache(self):
        # register responses such that if the discovery URL is hit more than
        # once then the response will be invalid and not point to COMPUTE_ADMIN
        disc_body = jsonutils.dumps(self.TEST_DISCOVERY)
        disc_responses = [httpretty.Response(body=disc_body, status=200),
                          httpretty.Response(body='', status=500)]
        httpretty.register_uri(httpretty.GET,
                               self.TEST_COMPUTE_ADMIN,
                               responses=disc_responses)

        body = 'SUCCESS'
        self.stub_url(httpretty.GET, ['path'], body=body, status=200)

        # now either of the two sessions I use, it should not cause a second
        # request to the discovery url.
        sa = session.Session()
        sb = session.Session()
        auth = self.create_auth_plugin()

        for sess in (sa, sb):
            resp = sess.get('/path',
                            auth=auth,
                            endpoint_filter={'service_type': 'compute',
                                             'interface': 'admin',
                                             'version': self.version})

            self.assertEqual(200, resp.status_code)
            self.assertEqual(body, resp.text)
    def test_available_versions_basics(self):
        examples = {'keystone': V3_VERSION_LIST,
                    'cinder': jsonutils.dumps(CINDER_EXAMPLES),
                    'glance': jsonutils.dumps(GLANCE_EXAMPLES)}

        for path, ex in six.iteritems(examples):
            url = "%s%s" % (BASE_URL, path)

            httpretty.register_uri(httpretty.GET, url, status=300, body=ex)
            versions = discover.available_versions(url)

            for v in versions:
                for n in ('id', 'status', 'links'):
                    msg = '%s missing from %s version data' % (n, path)
                    self.assertThat(v, matchers.Annotate(msg,
                                                         matchers.Contains(n)))
Пример #19
0
    def test_create_request_token(self):
        project_id = uuid.uuid4().hex
        consumer_key = uuid.uuid4().hex
        consumer_secret = uuid.uuid4().hex

        request_key, request_secret, resp_ref = self._new_oauth_token()

        # NOTE(stevemar) The server expects the body to be JSON. Even though
        # the resp_ref is a string it is not a JSON string.
        self.stub_url(httpretty.POST, [self.path_prefix, 'request_token'],
                      status=201, body=jsonutils.dumps(resp_ref),
                      content_type='application/x-www-form-urlencoded')

        # Assert the manager is returning request token object
        request_token = self.manager.create(consumer_key, consumer_secret,
                                            project_id)
        self.assertIsInstance(request_token, self.model)
        self.assertEqual(request_key, request_token.key)
        self.assertEqual(request_secret, request_token.secret)

        # Assert that the project id is in the header
        self.assertRequestHeaderEqual('requested_project_id', project_id)
        req_headers = httpretty.last_request().headers

        oauth_client = oauth1.Client(consumer_key,
                                     client_secret=consumer_secret,
                                     signature_method=oauth1.SIGNATURE_HMAC,
                                     callback_uri="oob")
        self._validate_oauth_headers(req_headers['Authorization'],
                                     oauth_client)
    def test_allow_deprecated(self):
        status = 'deprecated'
        version_list = [{
            'id': 'v3.0',
            'links': [{
                'href': V3_URL,
                'rel': 'self'
            }],
            'media-types': V3_MEDIA_TYPES,
            'status': status,
            'updated': UPDATED
        }]
        text = jsonutils.dumps({'versions': version_list})
        self.requests.register_uri('GET', BASE_URL, status_code=200, text=text)

        disc = discover.Discover(auth_url=BASE_URL)

        # deprecated is allowed by default
        versions = disc.version_data(allow_deprecated=False)
        self.assertEqual(0, len(versions))

        versions = disc.version_data(allow_deprecated=True)
        self.assertEqual(1, len(versions))
        self.assertEqual(status, versions[0]['raw_status'])
        self.assertEqual(V3_URL, versions[0]['url'])
        self.assertEqual((3, 0), versions[0]['version'])
    def test_available_cinder_data(self):
        body = jsonutils.dumps(CINDER_EXAMPLES)
        httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=body)

        v1_url = "%sv1/" % BASE_URL
        v2_url = "%sv2/" % BASE_URL

        disc = discover.Discover(auth_url=BASE_URL)
        versions = disc.version_data()

        self.assertEqual((1, 0), versions[0]['version'])
        self.assertEqual('CURRENT', versions[0]['raw_status'])
        self.assertEqual(v1_url, versions[0]['url'])
        self.assertEqual((2, 0), versions[1]['version'])
        self.assertEqual('CURRENT', versions[1]['raw_status'])
        self.assertEqual(v2_url, versions[1]['url'])

        version = disc.data_for('v2.0')
        self.assertEqual((2, 0), version['version'])
        self.assertEqual('CURRENT', version['raw_status'])
        self.assertEqual(v2_url, version['url'])

        version = disc.data_for(1)
        self.assertEqual((1, 0), version['version'])
        self.assertEqual('CURRENT', version['raw_status'])
        self.assertEqual(v1_url, version['url'])

        self.assertIsNone(disc.url_for('v3'))
        self.assertEqual(v2_url, disc.url_for('v2'))
        self.assertEqual(v1_url, disc.url_for('v1'))
 def test_greater_version_than_required(self):
     versions = fixture.DiscoveryList(BASE_URL, v3_id='v3.6')
     httpretty.register_uri(httpretty.GET,
                            BASE_URL,
                            status=200,
                            body=jsonutils.dumps(versions))
     self.assertCreatesV3(auth_url=BASE_URL, version=(3, 4))
    def _http_log_response(self, response=None, json=None,
                           status_code=None, headers=None, text=None):
        if not _logger.isEnabledFor(logging.DEBUG):
            return

        if response:
            if not status_code:
                status_code = response.status_code
            if not headers:
                headers = response.headers
            if not text:
                text = response.text
        if json:
            text = jsonutils.dumps(json)

        string_parts = ['RESP:']

        if status_code:
            string_parts.append('[%s]' % status_code)
        if headers:
            string_parts.append('%s' % headers)
        if text:
            string_parts.append('\nRESP BODY: %s\n' % text)

        _logger.debug(' '.join(string_parts))
Пример #24
0
    def test_list(self,
                  ref_list=None,
                  expected_path=None,
                  expected_query=None,
                  **filter_kwargs):
        ref_list = ref_list or [self.new_ref(), self.new_ref()]
        expected_path = self._get_expected_path(expected_path)

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(self.TEST_URL, expected_path),
                               body=jsonutils.dumps(self.encode(ref_list)))

        returned_list = self.manager.list(**filter_kwargs)
        self.assertEqual(len(ref_list), len(returned_list))
        [self.assertIsInstance(r, self.model) for r in returned_list]

        # register_uri doesn't match the querystring component, so we have to
        # explicitly test the querystring component passed by the manager
        qs_args = httpretty.last_request().querystring
        qs_args_expected = expected_query or filter_kwargs
        for key, value in six.iteritems(qs_args_expected):
            self.assertIn(key, qs_args)
            # The httppretty.querystring value is a list
            # Note we convert the value to a string, as the query string
            # is always a string and the filter_kwargs may contain non-string
            # values, for example a boolean, causing the comaprison to fail.
            self.assertIn(str(value), qs_args[key])

        # Also check that no query string args exist which are not expected
        for key in qs_args:
            self.assertIn(key, qs_args_expected)
    def test_list(self, ref_list=None, expected_path=None,
                  expected_query=None, **filter_kwargs):
        ref_list = ref_list or [self.new_ref(), self.new_ref()]
        expected_path = self._get_expected_path(expected_path)

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(self.TEST_URL, expected_path),
                               body=jsonutils.dumps(self.encode(ref_list)))

        returned_list = self.manager.list(**filter_kwargs)
        self.assertEqual(len(ref_list), len(returned_list))
        [self.assertIsInstance(r, self.model) for r in returned_list]

        # register_uri doesn't match the querystring component, so we have to
        # explicitly test the querystring component passed by the manager
        qs_args = httpretty.last_request().querystring
        qs_args_expected = expected_query or filter_kwargs
        for key, value in six.iteritems(qs_args_expected):
            self.assertIn(key, qs_args)
            # The httppretty.querystring value is a list
            # Note we convert the value to a string, as the query string
            # is always a string and the filter_kwargs may contain non-string
            # values, for example a boolean, causing the comaprison to fail.
            self.assertIn(str(value), qs_args[key])

        # Also check that no query string args exist which are not expected
        for key in qs_args:
            self.assertIn(key, qs_args_expected)
    def setUp(self, expected_env=None):
        expected_env = expected_env or {}

        conf = {
            'admin_token': 'admin_token1',
            'auth_host': 'keystone.example.com',
            'auth_port': 1234,
            'auth_admin_prefix': '/testadmin',
            'signing_dir': CERTDIR,
        }

        self.middleware = auth_token.AuthProtocol(FakeApp(expected_env), conf)
        self.middleware.http_client_class = FakeHTTPConnection
        self.middleware._iso8601 = iso8601

        self.response_status = None
        self.response_headers = None
        self.middleware.revoked_file_name = tempfile.mkstemp()[1]
        cache_timeout = datetime.timedelta(days=1)
        self.middleware.token_revocation_list_cache_timeout = cache_timeout
        self.middleware.token_revocation_list = jsonutils.dumps(
            {"revoked": [], "extra": "success"})

        signed_list = 'SIGNED_REVOCATION_LIST'
        valid_signed_list = 'VALID_SIGNED_REVOCATION_LIST'
        globals()[signed_list] = globals()[valid_signed_list]

        super(BaseAuthTokenMiddlewareTest, self).setUp()
    def test_create_request_token(self):
        project_id = uuid.uuid4().hex
        consumer_key = uuid.uuid4().hex
        consumer_secret = uuid.uuid4().hex

        request_key, request_secret, resp_ref = self._new_oauth_token()

        # NOTE(stevemar) The server expects the body to be JSON. Even though
        # the resp_ref is a string it is not a JSON string.
        self.stub_url(httpretty.POST, [self.path_prefix, 'request_token'],
                      status=201,
                      body=jsonutils.dumps(resp_ref),
                      content_type='application/x-www-form-urlencoded')

        # Assert the manager is returning request token object
        request_token = self.manager.create(consumer_key, consumer_secret,
                                            project_id)
        self.assertIsInstance(request_token, self.model)
        self.assertEqual(request_key, request_token.key)
        self.assertEqual(request_secret, request_token.secret)

        # Assert that the project id is in the header
        self.assertRequestHeaderEqual('requested_project_id', project_id)
        req_headers = httpretty.last_request().headers

        oauth_client = oauth1.Client(consumer_key,
                                     client_secret=consumer_secret,
                                     signature_method=oauth1.SIGNATURE_HMAC,
                                     callback_uri="oob")
        self._validate_oauth_headers(req_headers['Authorization'],
                                     oauth_client)
 def test_is_signed_token_revoked_returns_false(self):
     #explicitly setting an empty revocation list here to document intent
     self.middleware.token_revocation_list = jsonutils.dumps(
         {"revoked": [], "extra": "success"})
     result = self.middleware.is_signed_token_revoked(
         self.token_dict['revoked_token'])
     self.assertFalse(result)
    def request(self, method, path, **kwargs):
        """Fakes out several http responses.

        Support the following requests:

        - Create admin token ('POST /testadmin/v2.0/tokens')
        - Get versions ('GET /testadmin/')
        - Get v2 user token responses (see fake_v2_responses)
        - Get v3 user token responses (see fake_v3_responses)

        """
        v3FakeHTTPConnection.last_requested_url = path
        if method == 'POST' and path == '/testadmin/v2.0/tokens':
            status, body = self.fake_v2_admin_token(path)
        else:
            if path == '/testadmin/':
                # It's a GET versions call
                status = 300
                body = jsonutils.dumps(VERSION_LIST_v3)
            elif path.split('/')[2] == 'v2.0':
                status, body = self.fake_v2_responses(path)
            else:
                status, body = self.fake_v3_responses(path, **kwargs)

        self.resp = FakeHTTPResponse(status, body)
Пример #30
0
    def _cache_store(self, policy):
        """Store value into memcache.

        data may be the string 'invalid' or a tuple like (data, expires)

        """
        serialized_data = jsonutils.dumps(policy['blob'])
        if self._memcache_security_strategy is None:
            cache_key = CACHE_KEY_TEMPLATE
            data_to_store = (policy['timestamp'],serialized_data)
        else:
            keys = memcache_crypt.derive_keys(
                token,
                self._memcache_secret_key,
                self._memcache_security_strategy)
            cache_key = CACHE_KEY_TEMPLATE % memcache_crypt.get_cache_key(keys)
            data_to_store = memcache_crypt.protect_data(keys, serialized_data)
        try:
            self._cache.set(cache_key,
                            data_to_store,
                            time=self.policy_cache_time)
        except(TypeError):
            self._cache.set(cache_key,
                            data_to_store,
                            timeout=self.policy_cache_time)
Пример #31
0
    def _http_log_request(self, url, method=None, data=None, json=None, headers=None):
        if not _logger.isEnabledFor(logging.DEBUG):
            # NOTE(morganfainberg): This whole debug section is expensive,
            # there is no need to do the work if we're not going to emit a
            # debug log.
            return

        def process_header(header):
            secure_headers = ("authorization", "x-auth-token", "x-subject-token")
            if header[0].lower() in secure_headers:
                return (header[0], "TOKEN_REDACTED")
            return header

        string_parts = ["REQ: curl -i"]

        # NOTE(jamielennox): None means let requests do its default validation
        # so we need to actually check that this is False.
        if self.verify is False:
            string_parts.append("--insecure")

        if method:
            string_parts.extend(["-X", method])

        string_parts.append(url)

        if headers:
            for header in six.iteritems(headers):
                string_parts.append('-H "%s: %s"' % process_header(header))
        if json:
            data = jsonutils.dumps(json)
        if data:
            string_parts.append("-d '%s'" % data)

        _logger.debug(" ".join(string_parts))
Пример #32
0
    def _cache_store(self, token_id, data):
        """Store value into memcache.

        data may be the string 'invalid' or a tuple like (data, expires)

        """
        serialized_data = jsonutils.dumps(data)
        if self._memcache_security_strategy is None:
            cache_key = CACHE_KEY_TEMPLATE % token_id
            data_to_store = serialized_data
        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)
            data_to_store = memcache_crypt.protect_data(keys, serialized_data)

        # Historically the swift cache conection used the argument
        # timeout= for the cache timeout, but this has been unified
        # with the official python memcache client with time= since
        # grizzly, we still need to handle folsom for a while until
        # this could get removed.
        try:
            self._cache.set(cache_key,
                            data_to_store,
                            time=self.token_cache_time)
        except (TypeError):
            self._cache.set(cache_key,
                            data_to_store,
                            timeout=self.token_cache_time)
    def test_discover_unstable_versions(self):
        version_list = fixture.DiscoveryList(BASE_URL, v3_status='beta')
        httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
                               body=jsonutils.dumps(version_list))

        self.assertCreatesV2(auth_url=BASE_URL)
        self.assertVersionNotAvailable(auth_url=BASE_URL, version=3)
        self.assertCreatesV3(auth_url=BASE_URL, unstable=True)
    def test_discovery_fail_for_missing_v3(self):
        versions = fixture.DiscoveryList(v2=True, v3=False)
        httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
                               body=jsonutils.dumps(versions))

        disc = discover.Discover(auth_url=BASE_URL)
        self.assertRaises(exceptions.DiscoveryFailure,
                          disc.create_client, version=(3, 0))
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 test_get_unscoped_token_when_authenticated(self):
        headers = {'X-Subject-Token': saml2_fixtures.UNSCOPED_TOKEN_HEADER}
        self.simple_http('GET', self.FEDERATION_AUTH_URL,
                         body=jsonutils.dumps(saml2_fixtures.UNSCOPED_TOKEN),
                         headers=headers)
        token, token_body = self.saml2plugin._get_unscoped_token(self.session)
        self.assertEqual(saml2_fixtures.UNSCOPED_TOKEN['token'], token_body)

        self.assertEqual(saml2_fixtures.UNSCOPED_TOKEN_HEADER, token)
 def fake_v2_admin_token(self, path):
     status = 200
     body = jsonutils.dumps({
         'access': {
             'token': {'id': 'admin_token2',
                       'expires': '2022-10-03T16:58:01Z'}
         },
     })
     return status, body
    def test_available_versions_basics(self):
        examples = {
            'keystone': V3_VERSION_LIST,
            'cinder': jsonutils.dumps(CINDER_EXAMPLES),
            'glance': jsonutils.dumps(GLANCE_EXAMPLES)
        }

        for path, ex in six.iteritems(examples):
            url = "%s%s" % (BASE_URL, path)

            httpretty.register_uri(httpretty.GET, url, status=300, body=ex)
            versions = discover.available_versions(url)

            for v in versions:
                for n in ('id', 'status', 'links'):
                    msg = '%s missing from %s version data' % (n, path)
                    self.assertThat(
                        v, matchers.Annotate(msg, matchers.Contains(n)))
 def get_revocation_list_json(self, token_ids=None):
     if token_ids is None:
         token_ids = [REVOKED_TOKEN_HASH]
     revocation_list = {
         'revoked': [{
             'id': x,
             'expires': timeutils.utcnow()
         } for x in token_ids]
     }
     return jsonutils.dumps(revocation_list)
 def getresponse(self):
     # If self.resp is set then this is just the response to
     # the earlier request.  If it is not set, then we expect
     # a stack of responses to have been pre-prepared
     if self.resp:
         return self.resp
     else:
         if len(FAKE_RESPONSE_STACK):
             return FAKE_RESPONSE_STACK.pop()
         return FakeHTTPResponse(500, jsonutils.dumps("UNEXPECTED RESPONSE"))
    def test_discover_unstable_versions(self):
        version_list = fixture.DiscoveryList(BASE_URL, v3_status='beta')
        httpretty.register_uri(httpretty.GET,
                               BASE_URL,
                               status=300,
                               body=jsonutils.dumps(version_list))

        self.assertCreatesV2(auth_url=BASE_URL)
        self.assertVersionNotAvailable(auth_url=BASE_URL, version=3)
        self.assertCreatesV3(auth_url=BASE_URL, unstable=True)
    def test_scope_saml2_token_to_domain(self):
        self.simple_http('POST', self.TEST_URL + '/auth/tokens',
                         body=jsonutils.dumps(self.DOMAIN_SCOPED_TOKEN_JSON),
                         content_type='application/json',
                         headers=client_fixtures.AUTH_RESPONSE_HEADERS)

        token = self.saml2_scope_plugin.get_auth_ref(self.session)
        self.assertTrue(token.domain_scoped, "Received token is not scoped")
        self.assertEqual(client_fixtures.AUTH_SUBJECT_TOKEN, token.auth_token)
        self.assertEqual(self.TEST_DOMAIN_ID, token.domain_id)
        self.assertEqual(self.TEST_DOMAIN_NAME, token.domain_name)
Пример #43
0
    def test_list(self, ref_list=None, expected_path=None, **filter_kwargs):
        ref_list = ref_list or [self.new_ref(), self.new_ref()]
        expected_path = self._get_expected_path(expected_path)

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(self.TEST_URL, expected_path),
                               body=jsonutils.dumps(self.encode(ref_list)))

        returned_list = self.manager.list(**filter_kwargs)
        self.assertEqual(len(ref_list), len(returned_list))
        [self.assertIsInstance(r, self.model) for r in returned_list]
Пример #44
0
    def test_list_params(self):
        ref_list = [self.new_ref()]
        filter_kwargs = {uuid.uuid4().hex: uuid.uuid4().hex}
        expected_path = self._get_expected_path()

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(self.TEST_URL, expected_path),
                               body=jsonutils.dumps(self.encode(ref_list)))

        self.manager.list(**filter_kwargs)
        self.assertQueryStringContains(**filter_kwargs)
Пример #45
0
    def test_list_params(self):
        ref_list = [self.new_ref()]
        filter_kwargs = {uuid.uuid4().hex: uuid.uuid4().hex}
        expected_path = self._get_expected_path()

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(self.TEST_URL, expected_path),
                               body=jsonutils.dumps(self.encode(ref_list)))

        self.manager.list(**filter_kwargs)
        self.assertQueryStringContains(**filter_kwargs)
Пример #46
0
    def test_list(self, ref_list=None, expected_path=None, **filter_kwargs):
        ref_list = ref_list or [self.new_ref(), self.new_ref()]
        expected_path = self._get_expected_path(expected_path)

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(self.TEST_URL, expected_path),
                               body=jsonutils.dumps(self.encode(ref_list)))

        returned_list = self.manager.list(**filter_kwargs)
        self.assertEqual(len(ref_list), len(returned_list))
        [self.assertIsInstance(r, self.model) for r in returned_list]
 def getresponse(self):
     # If self.resp is set then this is just the response to
     # the earlier request.  If it is not set, then we expect
     # a stack of responses to have been pre-prepared
     if self.resp:
         return self.resp
     else:
         if len(FAKE_RESPONSE_STACK):
             return FAKE_RESPONSE_STACK.pop()
         return FakeHTTPResponse(
             500, jsonutils.dumps('UNEXPECTED RESPONSE'))
    def test_discovery_fail_for_missing_v3(self):
        versions = fixture.DiscoveryList(v2=True, v3=False)
        httpretty.register_uri(httpretty.GET,
                               BASE_URL,
                               status=300,
                               body=jsonutils.dumps(versions))

        disc = discover.Discover(auth_url=BASE_URL)
        self.assertRaises(exceptions.DiscoveryFailure,
                          disc.create_client,
                          version=(3, 0))
    def test_invalidate_response(self):
        resp_data1 = copy.deepcopy(self.TEST_RESPONSE_DICT)
        resp_data2 = copy.deepcopy(self.TEST_RESPONSE_DICT)

        resp_data1['access']['token']['id'] = 'token1'
        resp_data2['access']['token']['id'] = 'token2'

        auth_responses = [httpretty.Response(body=jsonutils.dumps(resp_data1),
                                             status=200),
                          httpretty.Response(body=jsonutils.dumps(resp_data2),
                                             status=200)]

        self.stub_auth(responses=auth_responses)

        a = v2.Password(self.TEST_URL, username=self.TEST_USER,
                        password=self.TEST_PASS)
        s = session.Session(auth=a)

        self.assertEqual('token1', s.get_token())
        a.invalidate()
        self.assertEqual('token2', s.get_token())
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'},
                ],
            },
        },
    },
Пример #51
0
    def test_invalidate_response(self):
        resp_data1 = copy.deepcopy(self.TEST_RESPONSE_DICT)
        resp_data2 = copy.deepcopy(self.TEST_RESPONSE_DICT)

        resp_data1['access']['token']['id'] = 'token1'
        resp_data2['access']['token']['id'] = 'token2'

        auth_responses = [
            httpretty.Response(body=jsonutils.dumps(resp_data1), status=200),
            httpretty.Response(body=jsonutils.dumps(resp_data2), status=200)
        ]

        self.stub_auth(responses=auth_responses)

        a = v2.Password(self.TEST_URL,
                        username=self.TEST_USER,
                        password=self.TEST_PASS)
        s = session.Session(auth=a)

        self.assertEqual('token1', s.get_token())
        a.invalidate()
        self.assertEqual('token2', s.get_token())
Пример #52
0
 def test_unauthorized_token(self):
     ret = {"error":
            {"message": "EC2 access key not found.",
             "code": 401,
             "title": "Unauthorized"}}
     httpretty.register_uri(httpretty.POST, self.TEST_URL,
                            status=403, body=jsonutils.dumps(ret))
     req = webob.Request.blank('/v1/AUTH_cfa/c/o')
     req.headers['Authorization'] = 'access:signature'
     req.headers['X-Storage-Token'] = 'token'
     resp = req.get_response(self.middleware)
     s3_denied_req = self.middleware.deny_request('AccessDenied')
     self.assertEqual(resp.body, s3_denied_req.body)
     self.assertEqual(resp.status_int, s3_denied_req.status_int)
    def test_available_glance_data(self):
        text = jsonutils.dumps(GLANCE_EXAMPLES)
        self.requests.register_uri('GET', BASE_URL, status_code=200, text=text)

        versions = discover.available_versions(BASE_URL)
        self.assertEqual(5, len(versions))

        for v in versions:
            if v['id'] in ('v2.2', 'v1.1'):
                self.assertEqual(v['status'], 'CURRENT')
            elif v['id'] in ('v2.1', 'v2.0', 'v1.0'):
                self.assertEqual(v['status'], 'SUPPORTED')
            else:
                self.fail("Invalid version found")
Пример #54
0
    def stub_url(self, method, parts=None, base_url=None, json=None, **kwargs):
        if not base_url:
            base_url = self.TEST_URL

        if json:
            kwargs['body'] = jsonutils.dumps(json)
            kwargs['content_type'] = 'application/json'

        if parts:
            url = '/'.join([p.strip('/') for p in [base_url] + parts])
        else:
            url = base_url

        httpretty.register_uri(method, url, **kwargs)
    def test_available_glance_data(self):
        body = jsonutils.dumps(GLANCE_EXAMPLES)
        httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)

        versions = discover.available_versions(BASE_URL)
        self.assertEqual(5, len(versions))

        for v in versions:
            if v['id'] in ('v2.2', 'v1.1'):
                self.assertEqual(v['status'], 'CURRENT')
            elif v['id'] in ('v2.1', 'v2.0', 'v1.0'):
                self.assertEqual(v['status'], 'SUPPORTED')
            else:
                self.fail("Invalid version found")