From 315dab839f495b8b220f0836e9cf75b356067496 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Sun, 4 Jan 2026 01:47:29 -0300 Subject: [PATCH] portal: allowlist internal request emails --- backend/atlas_portal/routes/access_requests.py | 5 ++++- backend/atlas_portal/settings.py | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/atlas_portal/routes/access_requests.py b/backend/atlas_portal/routes/access_requests.py index 93aefd0..83c9ba9 100644 --- a/backend/atlas_portal/routes/access_requests.py +++ b/backend/atlas_portal/routes/access_requests.py @@ -228,7 +228,10 @@ def register(app) -> None: return jsonify({"error": "email is required"}), 400 if "@" not in email: return jsonify({"error": "invalid email"}), 400 - if email.lower().endswith(f"@{settings.MAILU_DOMAIN.lower()}"): + email_lower = email.lower() + if email_lower.endswith(f"@{settings.MAILU_DOMAIN.lower()}") and ( + email_lower not in settings.ACCESS_REQUEST_INTERNAL_EMAIL_ALLOWLIST + ): return jsonify({"error": "email must be an external address"}), 400 if admin_client().ready() and admin_client().find_user(username): diff --git a/backend/atlas_portal/settings.py b/backend/atlas_portal/settings.py index df2c30f..b6cc59e 100644 --- a/backend/atlas_portal/settings.py +++ b/backend/atlas_portal/settings.py @@ -73,6 +73,11 @@ ACCESS_REQUEST_SUBMIT_RATE_WINDOW_SEC = int( ACCESS_REQUEST_STATUS_RATE_LIMIT = int(os.getenv("ACCESS_REQUEST_STATUS_RATE_LIMIT", "60")) ACCESS_REQUEST_STATUS_RATE_WINDOW_SEC = int(os.getenv("ACCESS_REQUEST_STATUS_RATE_WINDOW_SEC", "60")) ACCESS_REQUEST_EMAIL_VERIFY_TTL_SEC = int(os.getenv("ACCESS_REQUEST_EMAIL_VERIFY_TTL_SEC", str(24 * 60 * 60))) +ACCESS_REQUEST_INTERNAL_EMAIL_ALLOWLIST = { + address.strip().lower() + for address in os.getenv("ACCESS_REQUEST_INTERNAL_EMAIL_ALLOWLIST", "").split(",") + if address.strip() +} ACCESS_REQUEST_PROVISION_RETRY_COOLDOWN_SEC = float( os.getenv("ACCESS_REQUEST_PROVISION_RETRY_COOLDOWN_SEC", "30") )