コード例 #1
0
ファイル: app.py プロジェクト: mjlacy/Python-BookAPI
def update_one_book_full(object_id):
    try:
        book = request.get_json()

        result = data.update_book_full(object_id, book)

        if result is None:
            return jsonify(error="The id specified is not a valid id"), 400

        if result.upserted_id is not None:
            book['_id'] = str(result.upserted_id)
            resp = Response(json.dumps(book),
                            status=201,
                            mimetype='application/json')
            resp.headers['Location'] = f'/{object_id}'
            resp.autocorrect_location_header = False
            return resp

        book['_id'] = object_id
        resp = Response(json.dumps(book),
                        status=200,
                        mimetype='application/json')
        resp.headers['Location'] = f'/{object_id}'
        resp.autocorrect_location_header = False
        return resp

    except Exception as e:
        print(e)
        return jsonify(error=str(e)), 500
コード例 #2
0
def recipe_step(recipe_id, step_id):
    if request.method == 'GET':
        try:
            step = services.get_step(recipe_id=recipe_id, step_id=step_id)
        except NoResultFound:
            abort(404)
        return jsonify({'steps': step})

    elif request.method == 'PUT':
        recipe_id = request.form['recipe_id']
        order_no = request.form['order_no']
        instructions = request.form['instructions']
        result = services.edit_step(step_id=step_id,
                                    recipe_id=recipe_id,
                                    order_no=order_no,
                                    instructions=instructions)

        resp = jsonify({'step': result.data})
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}/steps/{1}'.format(recipe_id, result.id)
        resp.autocorrect_location_header = False

        return resp

    elif request.method == 'DELETE':
        services.delete_step(step_id)

        resp = Response()
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}/steps'
        resp.autocorrect_location_header = False

        return resp
コード例 #3
0
def index(path=''):
    logger.info(f'<Core> On request {request.url}')

    resp = None
    req_context = HandlerContext(request)
    req_context.update_client_req_time()

    flow_editor_handler.on_request_handler(req_context)

    req_context.update_server_req_time()

    mock_handler.handle(req_context)

    if not req_context.response_source:
        flow_editor_handler.on_request_upstream_handler(req_context)
        proxy_handler.handle(req_context)
        if req_context.is_proxiable:
            req_context.set_response_source_proxy()
            req_context.update_response_headers_code2flow()
            flow_editor_handler.on_response_upstream_handler(req_context)

    req_context.update_server_resp_time()

    flow_editor_handler.on_response_handler(req_context)

    if req_context.response_source:
        gen = req_context.get_response_generator()
        resp = Response(
            gen(),
            status=req_context.flow['response']['code'],
            headers=req_context.flow['response']['headers']
        )
    elif req_context.flow['response']:
        resp = Response(
            req_context.flow['response'].get('data', ''),
            status=req_context.flow['response'].get('code', 200),
            headers=req_context.flow['response'].get('headers', {})
        )
    else:
        path_not_found_handler.handle(req_context)
        req_context.update_client_resp_time()
        resp = req_context.response


    if context.application.is_diff_mode == context.MockMode.MULTIPLE and req_context.response_source == 'mock':
        proxy_handler.handle(req_context)
        if req_context.is_proxiable:
            req_context.update_response_headers_code2flow(output_key='proxy_response')
            req_context.update_response_data2flow(output_key='proxy_response')

    DuplicateHeaderKeyHandler.set_origin_header(resp.headers, req_context.flow['response']['headers'])

    context.emit('action', 'add flow log')

    # Close autocorrect response location.
    resp.autocorrect_location_header = False

    return resp
コード例 #4
0
ファイル: proxy.py プロジェクト: EOEPCA/um-pep-engine
 def proxy_request(request, new_header):
     try:
         endpoint_path = request.full_path
         if request.method == 'POST':
             res = post(g_config["resource_server_endpoint"] +
                        endpoint_path,
                        headers=new_header,
                        data=request.data,
                        stream=False)
         elif request.method == 'GET':
             res = get(g_config["resource_server_endpoint"] + endpoint_path,
                       headers=new_header,
                       stream=False)
         elif request.method == 'PUT':
             res = put(g_config["resource_server_endpoint"] + endpoint_path,
                       headers=new_header,
                       data=request.data,
                       stream=False)
         elif request.method == 'DELETE':
             res = delete(g_config["resource_server_endpoint"] +
                          endpoint_path,
                          headers=new_header,
                          stream=False)
         elif request.method == 'HEAD':
             res = head(g_config["resource_server_endpoint"] +
                        endpoint_path,
                        headers=new_header,
                        stream=False)
         elif request.method == 'PATCH':
             res = patch(g_config["resource_server_endpoint"] +
                         endpoint_path,
                         headers=new_header,
                         data=request.data,
                         stream=False)
         else:
             response = Response()
             response.status_code = 501
             return response
         excluded_headers = ['transfer-encoding']
         headers = [(name, value)
                    for (name, value) in res.raw.headers.items()
                    if name.lower() not in excluded_headers]
         response = Response(res.content, res.status_code, headers)
         if "Location" in response.headers:
             response.autocorrect_location_header = False
             response.headers["Location"] = response.headers[
                 "Location"].replace(g_config["resource_server_endpoint"],
                                     '')
         return response
     except Exception as e:
         response = Response()
         logger.debug("Error while redirecting to resource: " +
                      traceback.format_exc(),
                      file=sys.stderr)
         response.status_code = 500
         response.content = "Error while redirecting to resource: " + str(e)
         return response
コード例 #5
0
ファイル: app.py プロジェクト: baiyecha404/CTFWEBchallenge
def redirect(location):
    "drop-in replacement for flask's redirect that doesn't sanitize the redirect target URL"
    response = Response(f'Redirecting... to {location}',
                        302,
                        mimetype="text/html")
    response.headers["Location"] = location
    response.headers["Content-Type"] = 'text/plain'
    response.autocorrect_location_header = False
    return response
コード例 #6
0
ファイル: utils.py プロジェクト: kyoppie/kyoppie
def redirect(path, next_path=None):
    print(next_path)
    if (next_path):
        if (next_path[-1] == "?"):
            next_path = next_path[:-1]
        next_path = urllib.parse.quote(next_path)
        path += "?next=" + next_path
    res = Response("Redirect...")
    res.headers["Content-Type"] = "text/plain"
    res.headers["Location"] = path
    res.autocorrect_location_header = False
    return res, 302
コード例 #7
0
ファイル: utils.py プロジェクト: kyoppie/kyoppie-web
def redirect(path,next_path=None):
    print(next_path)
    if(next_path):
        if(next_path[-1]=="?"):
            next_path = next_path[:-1]
        next_path = urllib.parse.quote(next_path)
        path += "?next=" + next_path
    res = Response("Redirect...")
    res.headers["Content-Type"] = "text/plain"
    res.headers["Location"] = path
    res.autocorrect_location_header = False
    return res,302
コード例 #8
0
def _get_client(client_id):
    if request.method == 'GET':
        try:
            client = services.get_client(client_id=client_id)
        except NoResultFound:
            abort(404)

        resp = jsonify({'client': client})
        resp.headers['Location'] = 'localhost:5000/clients'
        resp.status_code = 200

        return resp

        # js = json.dumps(client)
        #
        # resp = Response(response=js, status=200, mimetype='application/json')
        # resp.headers['Location'] = 'localhost:5000/piece-mea/index'
        #
        # return resp

    elif request.method == 'PUT':
        name = request.form['name']
        nickname = request.form['nickname']
        email = request.form['email']
        home = request.form['home']
        mobile = request.form['mobile']
        work = request.form['work']
        result = services.edit_client(name=name,
                                      nickname=nickname,
                                      email=email,
                                      home=home,
                                      mobile=mobile,
                                      work=work)

        resp = jsonify({'client': result.data})
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/client/{0}'.format(result.id)
        resp.autocorrect_location_header = False

        return resp

    elif request.method == 'DELETE':
        services.delete_client(client_id=client_id)

        resp = Response()
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/clients'
        resp.autocorrect_location_header = False

        return resp
コード例 #9
0
def logout():
    auth = request.authorization
    logout_user = request.args.get('user')

    if auth is not None and logout_user == auth.username:
        return authenticate()
    else:
        response = Response('<p>You should be redirected to URL: '
                            '<a href="%s">%s</a>.' %
                            ('/index.html', '/index.html'),
                            302,
                            mimetype='text/html')
        response.autocorrect_location_header = False
        response.headers['Location'] = '/index.html'
        return response
コード例 #10
0
def _get_recipe(recipe_id):
    if request.method == 'GET':
        try:
            recipe = services.get_recipe(recipe_id=recipe_id)
        except NoResultFound:
            abort(404)

        resp = jsonify({'recipe': recipe.data})
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}'.format(recipe.id)
        resp.autocorrect_location_header = False

        return resp

    elif request.method == 'PUT':
        recipe_name = request.form['recipe_name']
        description = request.form['description']
        style = request.form['style']
        type = request.form['type']
        result = services.edit_recipe(recipe_id=recipe_id,
                                      recipe_name=recipe_name,
                                      description=description,
                                      style=style,
                                      type=type)

        resp = jsonify({'recipe': result.data})
        resp.status_code = 201
        resp.headers['Location'] = '/cah/api/v1.0/recipes/{0}'.format(result.id)
        resp.autocorrect_location_header = False

        # Get the parsed contents of the form data
        json = request.json
        print(json)
        # Render template

        return resp

    elif request.method == 'POST':
        recipe_id = request.form['recipe_id']
        services.delete_recipe(recipe_id)

        resp = Response()
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/recipes'
        resp.autocorrect_location_header = False

        return resp
コード例 #11
0
ファイル: app.py プロジェクト: mjlacy/Python-BookAPI
def get_one_book(object_id):
    try:
        book = data.get_book(object_id)

        if book is None:
            return jsonify(error="No book with an id of " + object_id +
                           " found"), 404

        resp = Response(json.dumps(book),
                        status=200,
                        mimetype='application/json')
        resp.headers['Location'] = f'/{object_id}'
        resp.autocorrect_location_header = False
        return resp

    except Exception as e:
        print(e)
        return jsonify(error=str(e)), 500
コード例 #12
0
ファイル: app.py プロジェクト: mjlacy/Python-BookAPI
def update_one_book_partial(object_id):
    try:
        result = data.update_book_partial(object_id, request.get_json())

        if result is None:
            return jsonify(error="The id specified is not a valid id"), 400

        if result.matched_count == 0:
            return jsonify(
                error=f"No book with an id of {object_id} found to update"
            ), 404

        resp = Response(status=200, mimetype='application/json')
        resp.headers['Location'] = f'/{object_id}'
        resp.autocorrect_location_header = False
        return resp

    except Exception as e:
        print(e)
        return jsonify(error=str(e)), 500
コード例 #13
0
ファイル: app.py プロジェクト: mjlacy/Python-BookAPI
def create_one_book():
    try:
        book = request.get_json()
        result = data.create_book(book)

        if result is None:
            return jsonify(error="The id specified is not a valid id"), 400

        if "_id" in book:
            book['_id'] = str(book['_id'])

        resp = Response(json.dumps(book),
                        status=201,
                        mimetype='application/json')
        resp.headers['Location'] = f'/{result.inserted_id}'
        resp.autocorrect_location_header = False
        return resp

    except Exception as e:
        print(e)
        return jsonify(error=str(e)), 500
コード例 #14
0
def _get_menu(menu_id):
    if request.method == 'GET':
        try:
            menu = services.get_menu(menu_id=menu_id)
        except NoResultFound:
            abort(404)
        return jsonify({'menu': menu})

    elif request.method == 'PUT':
        id = request.form['menu_id']
        description = request.form['description']
        start_date = request.form['start_date']
        end_date = request.form['end_date']
        result = services.edit_menu(id=id,
                                    start_date=start_date,
                                    description=description,
                                    end_date=end_date)

        resp = jsonify({'ingredient': result.data})
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/ingredients/{0}'.format(result.id)
        resp.autocorrect_location_header = False

        # Get the parsed contents of the form data
        json = request.json

        return resp

    elif request.method == 'DELETE':
        services.delete_menu(menu_id=menu_id)

        resp = Response()
        resp.status_code = 200
        resp.headers['Location'] = '/cah/api/v1.0/menus'
        resp.autocorrect_location_header = False

        return resp
コード例 #15
0
ファイル: main.py プロジェクト: uktrade/dit-cf-security
def handle_request():
    request_id = request.headers.get('X-B3-TraceId') or ''.join(choices(request_id_alphabet, k=8))

    logger.info('[%s] Start', request_id)

    # Must have X-CF-Forwarded-Url to match route
    try:
        forwarded_url = request.headers['X-CF-Forwarded-Url']
    except KeyError:
        logger.error('[%s] Missing X-CF-Forwarded-Url header', request_id)
        return render_access_denied('Unknown', 'Unknown', request_id)

    logger.info('[%s] Forwarded URL: %s', request_id, forwarded_url)
    parsed_url = urllib.parse.urlsplit(forwarded_url)

    # Find x-forwarded-for
    try:
        x_forwarded_for = request.headers['X-Forwarded-For']
    except KeyError:
        logger.error('[%s] X-Forwarded-For header is missing', request_id)
        return render_access_denied('Unknown', forwarded_url, request_id)

    logger.debug('[%s] X-Forwarded-For: %s', request_id, x_forwarded_for)

    def get_client_ip(route):
        try:
            return x_forwarded_for.split(',')[int(route['IP_DETERMINED_BY_X_FORWARDED_FOR_INDEX'])].strip()
        except IndexError:
            logger.debug('[%s] Not enough addresses in x-forwarded-for %s', request_id, x_forwarded_for)

    routes = env['ROUTES']
    hostname_ok = [
        re.match(route['HOSTNAME_REGEX'], parsed_url.hostname)
        for route in routes
    ]
    client_ips = [
        get_client_ip(route)
        for route in routes
    ]
    ip_ok = [
        any(client_ips[i] and IPv4Address(client_ips[i]) in IPv4Network(ip_range) for ip_range in route['IP_RANGES'])
        for i, route in enumerate(routes)
    ]
    shared_secrets = [
        route.get('SHARED_SECRET_HEADER', [])
        for route in routes
    ]
    shared_secret_ok = [
        [
            (
                shared_secret['NAME'] in request.headers
                and constant_time_is_equal(shared_secret['VALUE'].encode(), request.headers[shared_secret['NAME']].encode())
            )
            for shared_secret in shared_secrets[i]
        ]
        for i, _ in enumerate(routes)
    ]

    # In general, any matching basic auth credentials are accepted. However,
    # on authentication paths, only those with that path are accepted, and
    # on failure, a 401 is returned to request the correct credentials
    basic_auths = [
        route.get('BASIC_AUTH', [])
        for route in routes
    ]
    basic_auths_ok = [
        [
            request.authorization and
            constant_time_is_equal(basic_auth['USERNAME'].encode(), request.authorization.username.encode()) and
            constant_time_is_equal(basic_auth['PASSWORD'].encode(), request.authorization.password.encode())
            for basic_auth in basic_auths[i]
        ]
        for i, _ in enumerate(routes)
    ]
    on_auth_path_and_ok = [
        [
            basic_auths_ok[i][j]
            for j, basic_auth in enumerate(basic_auths[i])
            if parsed_url.path == basic_auth['AUTHENTICATE_PATH']
        ]
        for i, _ in enumerate(routes)
    ]
    any_on_auth_path_and_ok = any([
        any(on_auth_path_and_ok[i])
        for i, _ in enumerate(routes)
    ])
    should_request_auth = not any_on_auth_path_and_ok and any(
        (
            hostname_ok[i] and
            ip_ok[i] and
            (not shared_secrets[i] or any(shared_secret_ok[i])) and
            len(on_auth_path_and_ok[i]) and
            all(not ok for ok in on_auth_path_and_ok[i])
        )
        for i, _ in enumerate(routes)
    )
    should_respond_ok_to_auth_request = any(
        (
            hostname_ok[i] and
            ip_ok[i] and
            (not shared_secrets[i] or any(shared_secret_ok[i])) and
            len(on_auth_path_and_ok[i]) and
            any(on_auth_path_and_ok[i])
        )
        for i, _ in enumerate(routes)
    )

    any_route_with_all_checks_passed = any(
        (
            hostname_ok[i] and
            ip_ok[i] and
            (not shared_secrets[i] or any(shared_secret_ok[i])) and
            (not basic_auths[i] or any(basic_auths_ok[i]))
        )
        for i, _ in enumerate(routes)
    )

    # There is no perfect answer as to which IP to present to the client in
    # the light of multiple routes with different indexes of the
    # x-forwarded-for header. However, in real cases it is likely that if the
    # host matches, then that will be the correct one. If 'Unknown' is then
    # shown to the user, it suggests something has been misconfigured
    client_ip = next(
        (client_ips[i] for i, _ in enumerate(routes) if hostname_ok[i])
    , 'Unknown')

    headers_to_remove = tuple(set(
        shared_secret['NAME'].lower()
        for i, _ in enumerate(routes)
        for shared_secret in shared_secrets[i]
    )) + ('host', 'x-cf-forwarded-url', 'connection')

    if should_request_auth:
        return Response(
            'Could not verify your access level for that URL.\n'
            'You have to login with proper credentials', 401,
            {'WWW-Authenticate': 'Basic realm="Login Required"'})

    if should_respond_ok_to_auth_request:
        return 'ok'

    if not any_route_with_all_checks_passed:
        logger.warning(
            '[%s] No matching route; host: %s client ip: %s',
            request_id, parsed_url.hostname, client_ip)
        return render_access_denied(client_ip, forwarded_url, request_id)

    logger.info('[%s] Making request to origin', request_id)

    def downstream_data():
        while True:
            contents = request.stream.read(65536)
            if not contents:
                break
            yield contents

    origin_response = http.request(
        request.method,
        forwarded_url,
        headers={
            k: v for k, v in request.headers
            if k.lower() not in headers_to_remove
        },
        preload_content=False,
        redirect=False,
        assert_same_host=False,
        body=downstream_data(),
    )
    logger.info('[%s] Origin response status: %s', request_id, origin_response.status)

    def release_conn():
        origin_response.release_conn()
        logger.info('[%s] End', request_id)

    downstream_response = Response(
        origin_response.stream(65536, decode_content=False),
        status=origin_response.status,
        headers=[
            (k, v) for k, v in origin_response.headers.items()
            if k.lower() != 'connection'
        ],
    )
    downstream_response.autocorrect_location_header = False
    downstream_response.call_on_close(release_conn)

    logger.info('[%s] Starting response to client', request_id)

    return downstream_response