diff --git a/src/server/_config.py b/src/server/_config.py index 5d807635c..5095ec23f 100644 --- a/src/server/_config.py +++ b/src/server/_config.py @@ -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 = { diff --git a/src/server/endpoints/admin.py b/src/server/endpoints/admin.py index d352e473b..17bc9ca9b 100644 --- a/src/server/endpoints/admin.py +++ b/src/server/endpoints/admin.py @@ -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 @@ -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() @@ -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() @@ -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'})