Skip to content

update/fix PROXY_DEPTH default value, add 'diagnostics' endpoint #1193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/server/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@
setting REVERSE_PROXY_DEPTH to "0" essentially indicates there are no proxies between this server and the outside
world. in this case, the "X-Forwarded-For" header is ignored.
"""
REVERSE_PROXY_DEPTH = int(os.environ.get("PROXY_DEPTH", 2))
REVERSE_PROXY_DEPTH = int(os.environ.get("PROXY_DEPTH", 4))
# TODO: ^ this value should be "4" for the prod CC API server processes, and is currently unclear
# for prod AWS API server processes (but should be the same or lower)... when thats properly
# determined, set the default to the minimum of the two environments and special case the
# other in conf file(s).


REGION_TO_STATE = {
Expand Down
49 changes: 32 additions & 17 deletions src/server/endpoints/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from werkzeug.exceptions import NotFound, Unauthorized
from werkzeug.utils import redirect

from .._common import log_info_with_request
from .._config import ADMIN_PASSWORD, API_KEY_REGISTRATION_FORM_LINK, API_KEY_REMOVAL_REQUEST_LINK, REGISTER_WEBHOOK_TOKEN
from .._security import resolve_auth_token
from ..admin.models import User, UserRole
Expand Down Expand Up @@ -44,6 +45,24 @@ def user_exists(user_email: str = None, api_key: str = None):
return True if user else False


# ~~~~ PUBLIC ROUTES ~~~~


@bp.route("/registration_form", methods=["GET"])
def registration_form_redirect():
# TODO: replace this with our own hosted registration form instead of external
return redirect(API_KEY_REGISTRATION_FORM_LINK, code=302)


@bp.route("/removal_request", methods=["GET"])
def removal_request_redirect():
# TODO: replace this with our own hosted form instead of external
return redirect(API_KEY_REMOVAL_REQUEST_LINK, code=302)


# ~~~~ PRIVLEGED ROUTES ~~~~


@bp.route("/", methods=["GET", "POST"])
def _index():
token = _require_admin()
Expand Down Expand Up @@ -88,21 +107,6 @@ def _detail(user_id: int):
return _render("detail", token, flags, user=user.as_dict)


def register_new_key(api_key: str, email: str) -> str:
User.create_user(api_key=api_key, email=email)
return api_key


@bp.route("/registration_form", methods=["GET"])
def registration_form_redirect():
# TODO: replace this with our own hosted registration form instead of external
return redirect(API_KEY_REGISTRATION_FORM_LINK, code=302)

@bp.route("/removal_request", methods=["GET"])
def removal_request_redirect():
# TODO: replace this with our own hosted form instead of external
return redirect(API_KEY_REMOVAL_REQUEST_LINK, code=302)

@bp.route("/register", methods=["POST"])
def _register():
body = request.get_json()
Expand All @@ -117,5 +121,16 @@ def _register():
"User with email and/or API Key already exists, use different parameters or contact us for help",
409,
)
api_key = register_new_key(user_api_key, user_email)
return make_response(f"Successfully registered API key '{api_key}'", 200)
User.create_user(api_key=user_api_key, email=user_email)
return make_response(f"Successfully registered API key '{user_api_key}'", 200)


@bp.route("/diagnostics", methods=["GET", "PUT", "POST", "DELETE"])
def diags():
# allows us to get useful diagnostic information written into server logs,
# such as a full current "X-Forwarded-For" path as inserted into headers by intermediate proxies...
# (but only when initiated purposefully by us to keep junk out of the logs)
_require_admin()
log_info_with_request("diagnostics", headers=request.headers)
response_text = f"request path: {request.headers.get('X-Forwarded-For', 'idk')}"
return make_response(response_text, 200, {'content-type': 'text/plain'})

Check failure

Code scanning / SonarCloud

Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks

<!--SONAR_ISSUE_KEY:AYiiiasClPkNFakDi1W--->Change this code to not reflect user-controlled data. <p>See more on <a href="https://sonarcloud.io/project/issues?id=cmu-delphi_delphi-epidata&issues=AYiiiasClPkNFakDi1W-&open=AYiiiasClPkNFakDi1W-&pullRequest=1193">SonarCloud</a></p>