def __call__(self, env, start_response): def custom_start_response(status, headers): if self.delay_auth_decision: headers.append(('WWW-Authenticate', "Basic realm='API Realm'")) return start_response(status, headers) #TODO(Rasib): PERFORM OPENID AUTH #Auth processed, headers added now decide how to pass on the call if self.app: # Pass to downstream WSGI component env['HTTP_AUTHORIZATION'] = "Basic %s" % self.service_pass return self.app(env, custom_start_response) proxy_headers = [] proxy_headers['AUTHORIZATION'] = "Basic %s" % self.service_pass # We are forwarding to a remote service (no downstream WSGI app) req = Request(proxy_headers) parsed = urlparse(req.url) conn = http_connect(self.service_host, self.service_port, \ req.method, parsed.path, \ proxy_headers, \ ssl=(self.service_protocol == 'https')) resp = conn.getresponse() data = resp.read() #TODO(ziad): use a more sophisticated proxy # we are rewriting the headers now return Response(status=resp.status, body=data)(env, start_response)
def csv_response(request, filename, header, data, generate_row_fn): request.response_content_type = 'text/plain' download_header = 'attachment; filename="%s"' % filename header_list = [('Content-Disposition', download_header)] buffer = StringIO() writer = csv.writer(buffer) writer.writerow(header) for elt in data: row = generate_row_fn(elt) encoded_row = [] for cell in row: if isinstance(cell, unicode): encoded_row.append(cell.encode('utf-8')) else: encoded_row.append(cell) writer.writerow(encoded_row) response = Response( status=200, headerlist=header_list, content_type='text/csv', body=buffer.getvalue(), ) buffer.close() return response
def __call__(self, env, start_response): """ Handle incoming request. Transform. And send downstream. """ request = Request(env) if request.path == "/extensions": if env['KEYSTONE_API_VERSION'] == '2.0': request = Request(env) response = request.get_response(self.app) if response.status_int == 200: if response.content_type == 'application/json': #load json for this extension from file thisextension = open(os.path.join( os.path.dirname(__file__), "extension.json")).read() thisextensionjson = json.loads(thisextension) #load json in response body = json.loads(response.body) extensionsarray = body["extensions"]["values"] #add this extension and return the response extensionsarray.append(thisextensionjson) newresp = Response( content_type='application/json', body=json.dumps(body)) return newresp(env, start_response) elif response.content_type == 'application/xml': #load xml for this extension from file thisextensionxml = etree.parse(os.path.join( os.path.dirname(__file__), "extension.xml")).getroot() #load xml being returned in response body = etree.fromstring(response.body) #add this extension and return the response body.append(thisextensionxml) newresp = Response( content_type='application/xml', body=etree.tostring(body)) return newresp(env, start_response) # return the response return response(env, start_response) #default action, bypass return self.app(env, start_response)
def _forward_request(self, env, start_response, proxy_headers): """Token/Auth processed & claims added to headers""" self._decorate_request('AUTHORIZATION', "Basic %s" % self.service_pass, env, proxy_headers) #now decide how to pass on the call if self.app: # Pass to downstream WSGI component logger.debug("Sending request to next app in WSGI pipeline") return self.app(env, start_response) #.custom_start_response) else: # We are forwarding to a remote service (no downstream WSGI app) logger.debug("Sending request to %s" % self.service_url) req = Request(proxy_headers) parsed = urlparse(req.url) # pylint: disable=E1101 conn = http_connect(self.service_host, self.service_port, req.method, parsed.path, proxy_headers, ssl=(self.service_protocol == 'https'), timeout=self.service_timeout) resp = conn.getresponse() data = resp.read() logger.debug("Response was %s" % resp.status) #TODO(ziad): use a more sophisticated proxy # we are rewriting the headers now if resp.status in (401, 305): # Add our own headers to the list headers = [("WWW_AUTHENTICATE", "Keystone uri='%s'" % self.auth_location)] return Response(status=resp.status, body=data, headerlist=headers)(env, start_response) else: return Response(status=resp.status, body=data)(env, start_response)
def _forward_request(self): """Token/Auth processed & claims added to headers""" #now decide how to pass on the call if self.app: # Pass to downstream WSGI component return self.app(self.env, self.start_response) #.custom_start_response) else: # We are forwarding to a remote service (no downstream WSGI app) req = Request(self.proxy_headers) # pylint: disable=E1101 parsed = urlparse(req.url) conn = http_connect(self.service_host, self.service_port, req.method, parsed.path, self.proxy_headers, ssl=(self.service_protocol == 'https')) resp = conn.getresponse() data = resp.read() return Response(status=resp.status, body=data)(self.proxy_headers, self.start_response)
def __call__(self, env, start_response): def custom_start_response(status, headers): if self.delay_auth_decision: headers.append(('WWW-Authenticate', "Basic realm='Use guest/guest'")) return start_response(status, headers) #Prep headers to proxy request to remote service proxy_headers = env.copy() user = '' #Look for authentication if 'HTTP_AUTHORIZATION' not in env: #No credentials were provided if self.delay_auth_decision: _decorate_request_headers("X_IDENTITY_STATUS", "Invalid", proxy_headers, env) else: # If the user isn't authenticated, we reject the request and # return 401 indicating we need Basic Auth credentials. ret = HTTPUnauthorized("Authentication required", [('WWW-Authenticate', 'Basic realm="Use guest/guest"')]) return ret(env, start_response) else: # Claims were provided - validate them import base64 auth_header = env['HTTP_AUTHORIZATION'] _auth_type, encoded_creds = auth_header.split(None, 1) user, password = base64.b64decode(encoded_creds).split(':', 1) if not self.validateCreds(user, password): #Claims were rejected if not self.delay_auth_decision: # Reject request (or ask for valid claims) ret = HTTPUnauthorized("Authentication required", [('WWW-Authenticate', 'Basic realm="Use guest/guest"')]) return ret(env, start_response) else: # Claims are valid, forward request _decorate_request_headers("X_IDENTITY_STATUS", "Invalid", proxy_headers, env) # TODO(Ziad): add additional details we may need, # like tenant and group info _decorate_request_headers('X_AUTHORIZATION', "Proxy %s" % user, proxy_headers, env) _decorate_request_headers("X_IDENTITY_STATUS", "Confirmed", proxy_headers, env) _decorate_request_headers('X_TENANT', 'blank', proxy_headers, env) #Auth processed, headers added now decide how to pass on the call if self.app: # Pass to downstream WSGI component env['HTTP_AUTHORIZATION'] = "Basic %s" % self.service_pass return self.app(env, custom_start_response) proxy_headers['AUTHORIZATION'] = "Basic %s" % self.service_pass # We are forwarding to a remote service (no downstream WSGI app) req = Request(proxy_headers) parsed = urlparse(req.url) conn = http_connect(self.service_host, self.service_port, \ req.method, parsed.path, \ proxy_headers, \ ssl=(self.service_protocol == 'https')) resp = conn.getresponse() data = resp.read() #TODO(ziad): use a more sophisticated proxy # we are rewriting the headers now return Response(status=resp.status, body=data)(env, start_response)
def json_response(http_status, data): """Create a JSON response with a specific HTTP code.""" response = Response(json.dumps(data)) response.status = http_status response.content_type = 'application/json' return response