def authenticate(self, app): """ authenticate method will run pre-authenticate request and retrieve account information. Note that it currently supports only keystone and tempauth. (no support for the third party authentication middleware) """ sw_req = self.to_swift_req('TEST', None, None, body='') # don't show log message of this request sw_req.environ['swift.proxy_access_log_made'] = True sw_resp = sw_req.get_response(app) if not sw_req.remote_user: raise SignatureDoesNotMatch() _, self.account, _ = split_path(sw_resp.environ['PATH_INFO'], 2, 3, True) self.account = utf8encode(self.account) if 'HTTP_X_USER_NAME' in sw_resp.environ: # keystone self.user_id = "%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'], sw_resp.environ['HTTP_X_USER_NAME']) self.user_id = utf8encode(self.user_id) self.token = sw_resp.environ['HTTP_X_AUTH_TOKEN'] # Need to skip S3 authorization since authtoken middleware # overwrites account in PATH_INFO del self.headers['Authorization'] else: # tempauth self.user_id = self.access_key
def _headers_to_sign(self): """ Select the headers from the request that need to be included in the StringToSign. :return : dict of headers to sign, the keys are all lower case """ headers_lower_dict = dict( (k.lower().strip(), ' '.join(_header_strip(v or '').split())) for (k, v) in six.iteritems(self.headers)) if 'host' in headers_lower_dict and re.match( 'Boto/2.[0-9].[0-2]', headers_lower_dict.get('user-agent', '')): # Boto versions < 2.9.3 strip the port component of the host:port # header, so detect the user-agent via the header and strip the # port if we detect an old boto version. headers_lower_dict['host'] = \ headers_lower_dict['host'].split(':')[0] headers_to_sign = [ (key, value) for key, value in headers_lower_dict.items() if key in self._signed_headers] if len(headers_to_sign) != len(self._signed_headers): # NOTE: if we are missing the header suggested via # signed_header in actual header, it results in # SignatureDoesNotMatch in actual S3 so we can raise # the error immediately here to save redundant check # process. raise SignatureDoesNotMatch() return dict(headers_to_sign)
def _get_response(self, app, method, container, obj, headers=None, body=None, query=None): """ Calls the application with this request's environment. Returns a Response object that wraps up the application's result. """ sw_req = self.to_swift_req(method, container, obj, headers=headers, body=body, query=query) if CONF.s3_acl: sw_req.environ['swift_owner'] = True # needed to set ACL sw_req.environ['swift.authorize_override'] = True sw_req.environ['swift.authorize'] = lambda req: None sw_resp = sw_req.get_response(app) resp = Response.from_swift_resp(sw_resp) status = resp.status_int # pylint: disable-msg=E1101 if CONF.s3_acl: resp.bucket_acl = decode_acl('container', resp.sysmeta_headers) resp.object_acl = decode_acl('object', resp.sysmeta_headers) if not self.user_id: if 'HTTP_X_USER_NAME' in sw_resp.environ: # keystone self.user_id = \ utf8encode("%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'], sw_resp.environ['HTTP_X_USER_NAME'])) else: # tempauth self.user_id = self.access_key success_codes = self._swift_success_codes(method, container, obj) error_codes = self._swift_error_codes(method, container, obj) if status in success_codes: return resp err_msg = resp.body if status in error_codes: err_resp = \ error_codes[sw_resp.status_int] # pylint: disable-msg=E1101 if isinstance(err_resp, tuple): raise err_resp[0](*err_resp[1:]) else: raise err_resp() if status == HTTP_BAD_REQUEST: raise BadSwiftRequest(err_msg) if status == HTTP_UNAUTHORIZED: raise SignatureDoesNotMatch() if status == HTTP_FORBIDDEN: raise AccessDenied() raise InternalError('unexpected status code %d' % status)
def _get_response(self, app, method, container, obj, headers=None, body=None, query=None): """ Calls the application with this request's environment. Returns a Response object that wraps up the application's result. """ method = method or self.environ['REQUEST_METHOD'] if container is None: container = self.container_name if obj is None: obj = self.object_name sw_req = self.to_swift_req(method, container, obj, headers=headers, body=body, query=query) sw_resp = sw_req.get_response(app) resp = Response.from_swift_resp(sw_resp) status = resp.status_int # pylint: disable-msg=E1101 if not self.user_id: if 'HTTP_X_USER_NAME' in sw_resp.environ: # keystone self.user_id = \ utf8encode("%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'], sw_resp.environ['HTTP_X_USER_NAME'])) else: # tempauth self.user_id = self.access_key success_codes = self._swift_success_codes(method, container, obj) error_codes = self._swift_error_codes(method, container, obj) if status in success_codes: return resp err_msg = resp.body if status in error_codes: err_resp = \ error_codes[sw_resp.status_int] # pylint: disable-msg=E1101 if isinstance(err_resp, tuple): raise err_resp[0](*err_resp[1:]) else: raise err_resp() if status == HTTP_BAD_REQUEST: raise BadSwiftRequest(err_msg) if status == HTTP_UNAUTHORIZED: raise SignatureDoesNotMatch() if status == HTTP_FORBIDDEN: raise AccessDenied() raise InternalError('unexpected status code %d' % status)