From 5556599b5750d1839aee39c5e39e22ef93d9ca3a Mon Sep 17 00:00:00 2001 From: Morgan Fainberg Date: Tue, 1 Jul 2014 17:27:31 -0700 Subject: [PATCH] Privatize Everything Make s3_token and ec2_token middleware match auth_token and all properties except the class itself are now private. The memcache_crypt module is now private to the keystonemiddleware package. Change-Id: Id5103f4e9689bc2dbc6f79705030c903ae5cc406 --- .../{memcache_crypt.py => _memcache_crypt.py} | 0 keystonemiddleware/auth_token.py | 2 +- keystonemiddleware/ec2_token.py | 4 +- keystonemiddleware/s3_token.py | 85 ++++++++++--------- .../tests/test_memcache_crypt.py | 2 +- .../tests/test_s3_token_middleware.py | 54 ++++++------ 6 files changed, 74 insertions(+), 73 deletions(-) rename keystonemiddleware/{memcache_crypt.py => _memcache_crypt.py} (100%) diff --git a/keystonemiddleware/memcache_crypt.py b/keystonemiddleware/_memcache_crypt.py similarity index 100% rename from keystonemiddleware/memcache_crypt.py rename to keystonemiddleware/_memcache_crypt.py diff --git a/keystonemiddleware/auth_token.py b/keystonemiddleware/auth_token.py index cd79eeee..6f3a4b0c 100644 --- a/keystonemiddleware/auth_token.py +++ b/keystonemiddleware/auth_token.py @@ -162,7 +162,7 @@ from oslo.config import cfg import six from six.moves import urllib -from keystonemiddleware import memcache_crypt +from keystonemiddleware import _memcache_crypt as memcache_crypt from keystonemiddleware.openstack.common import jsonutils from keystonemiddleware.openstack.common import memorycache from keystonemiddleware.openstack.common import timeutils diff --git a/keystonemiddleware/ec2_token.py b/keystonemiddleware/ec2_token.py index bb9b8c73..ef58efa7 100644 --- a/keystonemiddleware/ec2_token.py +++ b/keystonemiddleware/ec2_token.py @@ -53,7 +53,7 @@ class EC2Token(object): def __init__(self, application): super(EC2Token, self).__init__() - self.application = application + self._application = application @webob.dec.wsgify() def __call__(self, req): @@ -112,7 +112,7 @@ class EC2Token(object): # Authenticated! req.headers['X-Auth-Token'] = token_id - return self.application + return self._application def filter_factory(global_conf, **local_conf): diff --git a/keystonemiddleware/s3_token.py b/keystonemiddleware/s3_token.py index 3a00abf1..c02f093b 100644 --- a/keystonemiddleware/s3_token.py +++ b/keystonemiddleware/s3_token.py @@ -45,15 +45,15 @@ PROTOCOL_NAME = 'S3 Token Authentication' # TODO(kun): remove it after oslo merge this. -def split_path(path, minsegs=1, maxsegs=None, rest_with_last=False): +def _split_path(path, minsegs=1, maxsegs=None, rest_with_last=False): """Validate and split the given HTTP request path. **Examples**:: - ['a'] = split_path('/a') - ['a', None] = split_path('/a', 1, 2) - ['a', 'c'] = split_path('/a/c', 1, 2) - ['a', 'c', 'o/r'] = split_path('/a/c/o/r', 1, 3, True) + ['a'] = _split_path('/a') + ['a', None] = _split_path('/a', 1, 2) + ['a', 'c'] = _split_path('/a/c', 1, 2) + ['a', 'c', 'o/r'] = _split_path('/a/c/o/r', 1, 3, True) :param path: HTTP Request path to be split :param minsegs: Minimum number of segments to be extracted @@ -100,17 +100,18 @@ class S3Token(object): def __init__(self, app, conf): """Common initialization code.""" - self.app = app - self.logger = logging.getLogger(conf.get('log_name', __name__)) - self.logger.debug('Starting the %s component', PROTOCOL_NAME) - self.reseller_prefix = conf.get('reseller_prefix', 'AUTH_') + self._app = app + self._logger = logging.getLogger(conf.get('log_name', __name__)) + 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) 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) + self._request_uri = '%s://%s:%s' % (auth_protocol, auth_host, + auth_port) # SSL insecure = conf.get('insecure', False) @@ -118,15 +119,15 @@ class S3Token(object): key_file = conf.get('keyfile') if insecure: - self.verify = False + self._verify = False elif cert_file and key_file: - self.verify = (cert_file, key_file) + self._verify = (cert_file, key_file) elif cert_file: - self.verify = cert_file + self._verify = cert_file else: - self.verify = None + self._verify = None - def deny_request(self, code): + def _deny_request(self, code): error_table = { 'AccessDenied': (401, 'Access denied'), 'InvalidURI': (400, 'Could not parse the specified URI'), @@ -145,18 +146,18 @@ class S3Token(object): def _json_request(self, creds_json): headers = {'Content-Type': 'application/json'} try: - response = requests.post('%s/v2.0/s3tokens' % self.request_uri, + response = requests.post('%s/v2.0/s3tokens' % self._request_uri, headers=headers, data=creds_json, - verify=self.verify) + verify=self._verify) except requests.exceptions.RequestException as e: - self.logger.info('HTTP connection exception: %s', e) - resp = self.deny_request('InvalidURI') + self._logger.info('HTTP connection exception: %s', e) + resp = self._deny_request('InvalidURI') raise ServiceError(resp) if response.status_code < 200 or response.status_code >= 300: - self.logger.debug('Keystone reply error: status=%s reason=%s', - response.status_code, response.reason) - resp = self.deny_request('AccessDenied') + self._logger.debug('Keystone reply error: status=%s reason=%s', + response.status_code, response.reason) + resp = self._deny_request('AccessDenied') raise ServiceError(resp) return response @@ -164,36 +165,36 @@ class S3Token(object): def __call__(self, environ, start_response): """Handle incoming request. authenticate and send downstream.""" req = webob.Request(environ) - self.logger.debug('Calling S3Token middleware.') + self._logger.debug('Calling S3Token middleware.') try: - parts = split_path(req.path, 1, 4, True) + parts = _split_path(req.path, 1, 4, True) version, account, container, obj = parts except ValueError: msg = 'Not a path query, skipping.' - self.logger.debug(msg) - return self.app(environ, start_response) + self._logger.debug(msg) + return self._app(environ, start_response) # Read request signature and access id. if 'Authorization' not in req.headers: msg = 'No Authorization header. skipping.' - self.logger.debug(msg) - return self.app(environ, start_response) + self._logger.debug(msg) + return self._app(environ, start_response) token = req.headers.get('X-Auth-Token', req.headers.get('X-Storage-Token')) if not token: msg = 'You did not specify an auth or a storage token. skipping.' - self.logger.debug(msg) - return self.app(environ, start_response) + self._logger.debug(msg) + return self._app(environ, start_response) auth_header = req.headers['Authorization'] try: access, signature = auth_header.split(' ')[-1].rsplit(':', 1) except ValueError: msg = 'You have an invalid Authorization header: %s' - self.logger.debug(msg, auth_header) - return self.deny_request('InvalidURI')(environ, start_response) + self._logger.debug(msg, auth_header) + return self._deny_request('InvalidURI')(environ, start_response) # NOTE(chmou): This is to handle the special case with nova # when we have the option s3_affix_tenant. We will force it to @@ -215,8 +216,8 @@ class S3Token(object): 'token': token, 'signature': signature}} creds_json = jsonutils.dumps(creds) - self.logger.debug('Connecting to Keystone sending this JSON: %s', - creds_json) + self._logger.debug('Connecting to Keystone sending this JSON: %s', + creds_json) # NOTE(vish): We could save a call to keystone by having # keystone return token, tenant, user, and roles # from this call. @@ -230,11 +231,11 @@ class S3Token(object): except ServiceError as e: resp = e.args[0] msg = 'Received error, exiting middleware with error: %s' - self.logger.debug(msg, resp.status_code) + self._logger.debug(msg, resp.status_code) return resp(environ, start_response) - self.logger.debug('Keystone Reply: Status: %d, Output: %s', - resp.status_code, resp.content) + self._logger.debug('Keystone Reply: Status: %d, Output: %s', + resp.status_code, resp.content) try: identity_info = resp.json() @@ -242,16 +243,16 @@ class S3Token(object): tenant = identity_info['access']['token']['tenant'] except (ValueError, KeyError): error = 'Error on keystone reply: %d %s' - self.logger.debug(error, resp.status_code, resp.content) - return self.deny_request('InvalidURI')(environ, start_response) + self._logger.debug(error, resp.status_code, resp.content) + return self._deny_request('InvalidURI')(environ, start_response) req.headers['X-Auth-Token'] = token_id tenant_to_connect = force_tenant or tenant['id'] - self.logger.debug('Connecting with tenant: %s', tenant_to_connect) - new_tenant_name = '%s%s' % (self.reseller_prefix, tenant_to_connect) + self._logger.debug('Connecting with tenant: %s', tenant_to_connect) + new_tenant_name = '%s%s' % (self._reseller_prefix, tenant_to_connect) environ['PATH_INFO'] = environ['PATH_INFO'].replace(account, new_tenant_name) - return self.app(environ, start_response) + return self._app(environ, start_response) def filter_factory(global_conf, **local_conf): diff --git a/keystonemiddleware/tests/test_memcache_crypt.py b/keystonemiddleware/tests/test_memcache_crypt.py index b4596d53..9219e1da 100644 --- a/keystonemiddleware/tests/test_memcache_crypt.py +++ b/keystonemiddleware/tests/test_memcache_crypt.py @@ -13,7 +13,7 @@ import six import testtools -from keystonemiddleware import memcache_crypt +from keystonemiddleware import _memcache_crypt as memcache_crypt class MemcacheCryptPositiveTests(testtools.TestCase): diff --git a/keystonemiddleware/tests/test_s3_token_middleware.py b/keystonemiddleware/tests/test_s3_token_middleware.py index 1fbba35b..dc6ff8c6 100644 --- a/keystonemiddleware/tests/test_s3_token_middleware.py +++ b/keystonemiddleware/tests/test_s3_token_middleware.py @@ -158,7 +158,7 @@ class S3TokenMiddlewareTestBad(S3TokenMiddlewareTestBase): 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') + 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) @@ -168,13 +168,13 @@ class S3TokenMiddlewareTestBad(S3TokenMiddlewareTestBase): req.headers['X-Storage-Token'] = 'token' resp = req.get_response(self.middleware) self.assertEqual(resp.status_int, 400) - s3_invalid_req = self.middleware.deny_request('InvalidURI') + s3_invalid_req = self.middleware._deny_request('InvalidURI') self.assertEqual(resp.body, s3_invalid_req.body) self.assertEqual(resp.status_int, s3_invalid_req.status_int) def test_fail_to_connect_to_keystone(self): with mock.patch.object(self.middleware, '_json_request') as o: - s3_invalid_req = self.middleware.deny_request('InvalidURI') + s3_invalid_req = self.middleware._deny_request('InvalidURI') o.side_effect = s3_token.ServiceError(s3_invalid_req) req = webob.Request.blank('/v1/AUTH_cfa/c/o') @@ -192,45 +192,45 @@ class S3TokenMiddlewareTestBad(S3TokenMiddlewareTestBase): req.headers['Authorization'] = 'access:signature' req.headers['X-Storage-Token'] = 'token' resp = req.get_response(self.middleware) - s3_invalid_req = self.middleware.deny_request('InvalidURI') + s3_invalid_req = self.middleware._deny_request('InvalidURI') self.assertEqual(resp.body, s3_invalid_req.body) self.assertEqual(resp.status_int, s3_invalid_req.status_int) class S3TokenMiddlewareTestUtil(testtools.TestCase): def test_split_path_failed(self): - self.assertRaises(ValueError, s3_token.split_path, '') - self.assertRaises(ValueError, s3_token.split_path, '/') - self.assertRaises(ValueError, s3_token.split_path, '//') - self.assertRaises(ValueError, s3_token.split_path, '//a') - self.assertRaises(ValueError, s3_token.split_path, '/a/c') - self.assertRaises(ValueError, s3_token.split_path, '//c') - self.assertRaises(ValueError, s3_token.split_path, '/a/c/') - self.assertRaises(ValueError, s3_token.split_path, '/a//') - self.assertRaises(ValueError, s3_token.split_path, '/a', 2) - self.assertRaises(ValueError, s3_token.split_path, '/a', 2, 3) - self.assertRaises(ValueError, s3_token.split_path, '/a', 2, 3, True) - self.assertRaises(ValueError, s3_token.split_path, '/a/c/o/r', 3, 3) - self.assertRaises(ValueError, s3_token.split_path, '/a', 5, 4) + self.assertRaises(ValueError, s3_token._split_path, '') + self.assertRaises(ValueError, s3_token._split_path, '/') + self.assertRaises(ValueError, s3_token._split_path, '//') + self.assertRaises(ValueError, s3_token._split_path, '//a') + self.assertRaises(ValueError, s3_token._split_path, '/a/c') + self.assertRaises(ValueError, s3_token._split_path, '//c') + self.assertRaises(ValueError, s3_token._split_path, '/a/c/') + self.assertRaises(ValueError, s3_token._split_path, '/a//') + self.assertRaises(ValueError, s3_token._split_path, '/a', 2) + self.assertRaises(ValueError, s3_token._split_path, '/a', 2, 3) + self.assertRaises(ValueError, s3_token._split_path, '/a', 2, 3, True) + self.assertRaises(ValueError, s3_token._split_path, '/a/c/o/r', 3, 3) + self.assertRaises(ValueError, s3_token._split_path, '/a', 5, 4) def test_split_path_success(self): - self.assertEqual(s3_token.split_path('/a'), ['a']) - self.assertEqual(s3_token.split_path('/a/'), ['a']) - self.assertEqual(s3_token.split_path('/a/c', 2), ['a', 'c']) - self.assertEqual(s3_token.split_path('/a/c/o', 3), ['a', 'c', 'o']) - self.assertEqual(s3_token.split_path('/a/c/o/r', 3, 3, True), + self.assertEqual(s3_token._split_path('/a'), ['a']) + self.assertEqual(s3_token._split_path('/a/'), ['a']) + self.assertEqual(s3_token._split_path('/a/c', 2), ['a', 'c']) + self.assertEqual(s3_token._split_path('/a/c/o', 3), ['a', 'c', 'o']) + self.assertEqual(s3_token._split_path('/a/c/o/r', 3, 3, True), ['a', 'c', 'o/r']) - self.assertEqual(s3_token.split_path('/a/c', 2, 3, True), + self.assertEqual(s3_token._split_path('/a/c', 2, 3, True), ['a', 'c', None]) - self.assertEqual(s3_token.split_path('/a/c/', 2), ['a', 'c']) - self.assertEqual(s3_token.split_path('/a/c/', 2, 3), ['a', 'c', '']) + self.assertEqual(s3_token._split_path('/a/c/', 2), ['a', 'c']) + self.assertEqual(s3_token._split_path('/a/c/', 2, 3), ['a', 'c', '']) def test_split_path_invalid_path(self): try: - s3_token.split_path('o\nn e', 2) + s3_token._split_path('o\nn e', 2) except ValueError as err: self.assertEqual(str(err), 'Invalid path: o%0An%20e') try: - s3_token.split_path('o\nn e', 2, 3, True) + s3_token._split_path('o\nn e', 2, 3, True) except ValueError as err: self.assertEqual(str(err), 'Invalid path: o%0An%20e')