(c: Composition)
| 19 | |
| 20 | |
| 21 | def workflow_default(c: Composition) -> None: |
| 22 | with c.override( |
| 23 | Materialized( |
| 24 | listeners_config_path=f"{MZ_ROOT}/test/http-auth/listener_config_normal_only.json" |
| 25 | ) |
| 26 | ): |
| 27 | c.up("materialized") |
| 28 | base = f"http://localhost:{c.port('materialized', 6876)}" |
| 29 | |
| 30 | # Regression test for database-issues#11340. With `allowed_roles: |
| 31 | # Normal`, header-based Basic auth correctly rejects `mz_system`, but |
| 32 | # `/api/login` previously did not run the same role check — letting an |
| 33 | # internal role obtain a session cookie and bypass the policy on |
| 34 | # subsequent requests. Make sure `/api/login` enforces the listener's |
| 35 | # role policy directly and never mints a session for a disallowed role. |
| 36 | with c.test_case("session_login_rejects_disallowed_role"): |
| 37 | s = requests.Session() |
| 38 | r = s.post( |
| 39 | f"{base}/api/login", |
| 40 | json={"username": "mz_system", "password": "password"}, |
| 41 | ) |
| 42 | assert r.status_code == 401, f"expected 401, got {r.status_code}: {r.text}" |
| 43 | assert ( |
| 44 | "mz_session" not in s.cookies |
| 45 | ), f"login rejection must not set a session cookie: {s.cookies}" |
| 46 | |
| 47 | with c.override( |
| 48 | Materialized( |
| 49 | listeners_config_path=f"{MZ_ROOT}/test/http-auth/listener_config_unauth_normal.json" |
| 50 | ) |
| 51 | ): |
| 52 | c.up("materialized") |
| 53 | ext = f"http://localhost:{c.port('materialized', 6876)}/api/sql" |
| 54 | internal = f"http://localhost:{c.port('materialized', 6878)}/api/sql" |
| 55 | |
| 56 | def sql_post(url, query, user=None): |
| 57 | headers = {} |
| 58 | if user: |
| 59 | headers["x-materialize-user"] = user |
| 60 | return requests.post(url, headers=headers, json={"query": query}) |
| 61 | |
| 62 | def sql_user(url, query, user=None): |
| 63 | r = sql_post(url, query, user) |
| 64 | assert r.status_code == 200, f"expected 200, got {r.status_code}: {r.text}" |
| 65 | return r.json()["results"][0]["rows"][0][0] |
| 66 | |
| 67 | with c.test_case("anonymous_external_request"): |
| 68 | assert sql_user(ext, "SELECT current_user;") == "anonymous_http_user" |
| 69 | |
| 70 | with c.test_case("internal_mz_system_allowed"): |
| 71 | assert ( |
| 72 | sql_user(internal, "SELECT current_user;", "mz_system") == "mz_system" |
| 73 | ) |
| 74 | |
| 75 | # Regression test for database-issues#11346. With |
| 76 | # `authenticator_kind=None` and `allowed_roles=Normal`, the |
| 77 | # `x-materialize-user` header previously injected an authenticated |
| 78 | # user without consulting `allowed_roles`, so external callers could |
nothing calls this directly
no test coverage detected