Merge "Use requests library in S3 middleware"
This commit is contained in:
@@ -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
|
||||
|
@@ -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):
|
||||
|
Reference in New Issue
Block a user