diff options
| author | Claude Sonnet 4.6 | 2026-06-03 00:00:00 +0000 |
|---|---|---|
| committer | Frederick Muriuki Muriithi | 2026-06-03 14:07:32 -0500 |
| commit | 6a0d09960be96619d26d080d8d4c420eb48adb25 (patch) | |
| tree | a60a6990f90f4ee623a0d996e200c7cba21612d6 | |
| parent | a16a0b5c9da77c20664027c659337db0ae521a9f (diff) | |
| download | gn-auth-6a0d09960be96619d26d080d8d4c420eb48adb25.tar.gz | |
wsgi: add create-test-users command
Add create_test_users which auto-generates timestamped emails and random passwords for ephemeral test accounts, delegating DB creation to the __create_one_user__ helper introduced in the previous commit.
| -rw-r--r-- | gn_auth/wsgi.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/gn_auth/wsgi.py b/gn_auth/wsgi.py index 3b3b60b..a6d8b00 100644 --- a/gn_auth/wsgi.py +++ b/gn_auth/wsgi.py @@ -1,5 +1,7 @@ """Main entry point for project""" import os +import re +import secrets import sys import uuid import json @@ -134,6 +136,14 @@ def register_admin(): _VALID_ROLES_ = ("system-admin", "none") +_TEST_EMAIL_DOMAIN_ = "regression-tests.genenetwork.org" + + +def __normalise_name_for_email__(name: str) -> str: + """Lowercase and strip non-alphanumeric characters for use in an email.""" + return re.sub(r"[^a-z0-9]", "", name.lower()) + + def __create_one_user__(cursor, name: str, email: str, password: str, role: str) -> dict: """Create a single user in the DB and return their credential record.""" user = save_user(cursor, email, name, verified=True) @@ -236,6 +246,57 @@ def delete_users(user_ids): deleted = delete_users_by_id(conn, tuple(user_ids)) print(f"Deleted {deleted} user(s).") + +@app.cli.command() +@click.option("--session-timestamp", required=True, + help="Compact ISO 8601 UTC timestamp (e.g. 20260602T122700Z)") +@click.option("--user", "user_specs", multiple=True, + help='User spec: "name=...,role=..."') +@click.option("--output", "output_path", required=True, type=click.Path(), + help="Write credentials as JSON to this file (0600 permissions)") +def create_test_users(session_timestamp, user_specs, output_path): + """Create ephemeral test users with auto-generated email and password. + + Each --user option takes a comma-separated key=value string with the + following keys: name, role. + + Email: <normalised-name><timestamp>@regression-tests.genenetwork.org + Password: randomly generated. + + Output is written with 0600 permissions. Valid roles: system-admin, none. + """ + if not user_specs: + print("No users specified.", file=sys.stderr) + sys.exit(1) + + records = [] + with db.connection(app.config["AUTH_DB"]) as conn, db.cursor(conn) as cursor: + for spec_str in user_specs: + spec = __parse_user_spec__(spec_str) + name = spec.get("name", "").strip() + role = spec.get("role", "none").strip() + + if not name: + print(f"Missing 'name' in user spec: {spec_str!r}", file=sys.stderr) + sys.exit(1) + if role not in _VALID_ROLES_: + print( + f"Invalid role {role!r} in spec: {spec_str!r}. " + f"Valid roles: {_VALID_ROLES_}", + file=sys.stderr) + sys.exit(1) + + email = (f"{__normalise_name_for_email__(name)}" + f"{session_timestamp}@{_TEST_EMAIL_DOMAIN_}") + password = secrets.token_urlsafe(32) + + records.append( + __create_one_user__(cursor, name, email, password, role)) + + __write_output__( + {"session_timestamp": session_timestamp, "users": records}, + output_path) + ##### END: CLI Commands ##### if __name__ == '__main__': |
