mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-15 01:12:56 +00:00
137 lines
4.0 KiB
Python
137 lines
4.0 KiB
Python
from __future__ import annotations
|
|
|
|
import psycopg2
|
|
import pytest
|
|
from fixtures.neon_fixtures import (
|
|
NeonProxy,
|
|
VanillaPostgres,
|
|
)
|
|
from pytest_httpserver import HTTPServer
|
|
|
|
TABLE_NAME = "neon_control_plane.endpoints"
|
|
|
|
|
|
def test_proxy_psql_not_allowed_ips(
|
|
static_proxy: NeonProxy,
|
|
vanilla_pg: VanillaPostgres,
|
|
httpserver: HTTPServer,
|
|
):
|
|
[(rolpassword,)] = vanilla_pg.safe_psql(
|
|
"select rolpassword from pg_catalog.pg_authid where rolname = 'proxy'"
|
|
)
|
|
|
|
# Shouldn't be able to connect to this project
|
|
httpserver.expect_request("/cplane/proxy_get_role_secret").respond_with_json(
|
|
{
|
|
"role_secret": rolpassword,
|
|
"allowed_ips": ["8.8.8.8"],
|
|
"project_id": "foo-bar",
|
|
}
|
|
)
|
|
|
|
def check_cannot_connect(**kwargs):
|
|
with pytest.raises(psycopg2.Error) as exprinfo:
|
|
static_proxy.safe_psql(**kwargs)
|
|
text = str(exprinfo.value).strip()
|
|
assert "not allowed to connect" in text
|
|
|
|
# no SNI, deprecated `options=project` syntax (before we had several endpoint in project)
|
|
check_cannot_connect(query="select 1", sslsni=0, options="project=private-project")
|
|
|
|
# no SNI, new `options=endpoint` syntax
|
|
check_cannot_connect(query="select 1", sslsni=0, options="endpoint=private-project")
|
|
|
|
# with SNI
|
|
check_cannot_connect(query="select 1", host="private-project.localtest.me")
|
|
|
|
|
|
def test_proxy_psql_allowed_ips(
|
|
static_proxy: NeonProxy,
|
|
vanilla_pg: VanillaPostgres,
|
|
httpserver: HTTPServer,
|
|
):
|
|
[(rolpassword,)] = vanilla_pg.safe_psql(
|
|
"select rolpassword from pg_catalog.pg_authid where rolname = 'proxy'"
|
|
)
|
|
|
|
# Should be able to connect to this project
|
|
httpserver.expect_request("/cplane/proxy_get_role_secret").respond_with_json(
|
|
{
|
|
"role_secret": rolpassword,
|
|
"allowed_ips": ["::1", "127.0.0.1"],
|
|
"project_id": "foo-bar",
|
|
}
|
|
)
|
|
|
|
# no SNI, deprecated `options=project` syntax (before we had several endpoint in project)
|
|
out = static_proxy.safe_psql(query="select 1", sslsni=0, options="project=generic-project")
|
|
assert out[0][0] == 1
|
|
|
|
# no SNI, new `options=endpoint` syntax
|
|
out = static_proxy.safe_psql(query="select 1", sslsni=0, options="endpoint=generic-project")
|
|
assert out[0][0] == 1
|
|
|
|
# with SNI
|
|
out = static_proxy.safe_psql(query="select 1", host="generic-project.localtest.me")
|
|
assert out[0][0] == 1
|
|
|
|
|
|
def test_proxy_http_not_allowed_ips(
|
|
static_proxy: NeonProxy,
|
|
vanilla_pg: VanillaPostgres,
|
|
httpserver: HTTPServer,
|
|
):
|
|
vanilla_pg.safe_psql("create user http_auth with password 'http' superuser")
|
|
|
|
[(rolpassword,)] = vanilla_pg.safe_psql(
|
|
"select rolpassword from pg_catalog.pg_authid where rolname = 'http_auth'"
|
|
)
|
|
|
|
httpserver.expect_oneshot_request("/cplane/proxy_get_role_secret").respond_with_json(
|
|
{
|
|
"role_secret": rolpassword,
|
|
"allowed_ips": ["8.8.8.8"],
|
|
"project_id": "foo-bar",
|
|
}
|
|
)
|
|
|
|
with httpserver.wait() as waiting:
|
|
static_proxy.http_query(
|
|
"select 1;",
|
|
[],
|
|
user="http_auth",
|
|
password="http",
|
|
expected_code=400,
|
|
)
|
|
assert waiting.result
|
|
|
|
|
|
def test_proxy_http_allowed_ips(
|
|
static_proxy: NeonProxy,
|
|
vanilla_pg: VanillaPostgres,
|
|
httpserver: HTTPServer,
|
|
):
|
|
vanilla_pg.safe_psql("create user http_auth with password 'http' superuser")
|
|
|
|
[(rolpassword,)] = vanilla_pg.safe_psql(
|
|
"select rolpassword from pg_catalog.pg_authid where rolname = 'http_auth'"
|
|
)
|
|
|
|
httpserver.expect_oneshot_request("/cplane/proxy_get_role_secret").respond_with_json(
|
|
{
|
|
"role_secret": rolpassword,
|
|
"allowed_ips": ["8.8.8.8", "127.0.0.1"],
|
|
"project_id": "foo-bar",
|
|
}
|
|
)
|
|
|
|
with httpserver.wait() as waiting:
|
|
static_proxy.http_query(
|
|
"select 1;",
|
|
[],
|
|
user="http_auth",
|
|
password="http",
|
|
expected_code=200,
|
|
)
|
|
assert waiting.result
|