Example #1
0
    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)
Example #2
0
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
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
 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)
Example #6
0
    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)
Example #7
0
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
Example #8
0
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