Merge "Use requests library in S3 middleware"

This commit is contained in:
Jenkins
2014-02-06 08:15:00 +00:00
committed by Gerrit Code Review
2 changed files with 52 additions and 33 deletions

View File

@@ -33,11 +33,12 @@ This WSGI component:
"""
import httplib
import logging
import urllib
import webob
import requests
from keystoneclient.openstack.common import jsonutils
@@ -105,16 +106,26 @@ class S3Token(object):
self.logger.debug('Starting the %s component' % PROTOCOL_NAME)
self.reseller_prefix = conf.get('reseller_prefix', 'AUTH_')
# where to find the auth service (we use this to validate tokens)
self.auth_host = conf.get('auth_host')
self.auth_port = int(conf.get('auth_port', 35357))
self.auth_protocol = conf.get('auth_protocol', 'https')
if self.auth_protocol == 'http':
self.http_client_class = httplib.HTTPConnection
else:
self.http_client_class = httplib.HTTPSConnection
auth_host = conf.get('auth_host')
auth_port = int(conf.get('auth_port', 35357))
auth_protocol = conf.get('auth_protocol', 'https')
self.request_uri = '%s://%s:%s' % (auth_protocol, auth_host, auth_port)
# SSL
self.cert_file = conf.get('certfile')
self.key_file = conf.get('keyfile')
insecure = conf.get('insecure', False)
cert_file = conf.get('certfile')
key_file = conf.get('keyfile')
if insecure:
self.verify = False
elif cert_file and key_file:
self.verify = (cert_file, key_file)
elif cert_file:
self.verify = cert_file
else:
self.verify = None
def deny_request(self, code):
error_table = {
@@ -132,33 +143,22 @@ class S3Token(object):
def _json_request(self, creds_json):
headers = {'Content-Type': 'application/json'}
if self.auth_protocol == 'http':
conn = self.http_client_class(self.auth_host, self.auth_port)
else:
conn = self.http_client_class(self.auth_host,
self.auth_port,
self.key_file,
self.cert_file)
try:
conn.request('POST', '/v2.0/s3tokens',
body=creds_json,
headers=headers)
response = conn.getresponse()
output = response.read()
except Exception as e:
response = requests.post('%s/v2.0/s3tokens' % self.request_uri,
headers=headers, data=creds_json,
verify=self.verify)
except requests.exceptions.RequestException as e:
self.logger.info('HTTP connection exception: %s' % e)
resp = self.deny_request('InvalidURI')
raise ServiceError(resp)
finally:
conn.close()
if response.status < 200 or response.status >= 300:
if response.status_code < 200 or response.status_code >= 300:
self.logger.debug('Keystone reply error: status=%s reason=%s' %
(response.status, response.reason))
(response.status_code, response.reason))
resp = self.deny_request('AccessDenied')
raise ServiceError(resp)
return (response, output)
return response
def __call__(self, environ, start_response):
"""Handle incoming request. authenticate and send downstream."""
@@ -225,23 +225,23 @@ class S3Token(object):
# identified and not doing a second query and just
# pass it through to swiftauth in this case.
try:
resp, output = self._json_request(creds_json)
resp = self._json_request(creds_json)
except ServiceError as e:
resp = e.args[0]
msg = 'Received error, exiting middleware with error: %s'
self.logger.debug(msg % (resp.status))
self.logger.debug(msg % (resp.status_code))
return resp(environ, start_response)
self.logger.debug('Keystone Reply: Status: %d, Output: %s' % (
resp.status, output))
resp.status_code, resp.content))
try:
identity_info = jsonutils.loads(output)
identity_info = resp.json()
token_id = str(identity_info['access']['token']['id'])
tenant = identity_info['access']['token']['tenant']
except (ValueError, KeyError):
error = 'Error on keystone reply: %d %s'
self.logger.debug(error % (resp.status, str(output)))
self.logger.debug(error % (resp.status_code, str(resp.content)))
return self.deny_request('InvalidURI')(environ, start_response)
req.headers['X-Auth-Token'] = token_id

View File

@@ -16,6 +16,7 @@
import httpretty
import mock
import requests
import testtools
import webob
@@ -120,6 +121,24 @@ class S3TokenMiddlewareTestGood(S3TokenMiddlewareTestBase):
path = req.environ['PATH_INFO']
self.assertTrue(path.startswith('/v1/AUTH_FORCED_TENANT_ID'))
@mock.patch.object(requests, 'post')
def test_insecure(self, MOCK_REQUEST):
self.middleware = (
s3_token.filter_factory({'insecure': True})(FakeApp()))
MOCK_REQUEST.return_value = utils.TestResponse({
'status_code': 201,
'text': jsonutils.dumps(GOOD_RESPONSE)})
req = webob.Request.blank('/v1/AUTH_cfa/c/o')
req.headers['Authorization'] = 'access:signature'
req.headers['X-Storage-Token'] = 'token'
req.get_response(self.middleware)
self.assertTrue(MOCK_REQUEST.called)
mock_args, mock_kwargs = MOCK_REQUEST.call_args
self.assertIs(mock_kwargs['verify'], False)
class S3TokenMiddlewareTestBad(S3TokenMiddlewareTestBase):
def setUp(self):