Merge branch 'feature/config-file'
This commit is contained in:
commit
404fcac4dd
8 changed files with 246 additions and 7 deletions
55
tests/test_client_registration.py
Normal file
55
tests/test_client_registration.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
from pathlib import Path
|
||||
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
|
||||
from porchlight.app import create_app
|
||||
from porchlight.config import Settings
|
||||
|
||||
|
||||
async def test_configured_clients_are_registered(tmp_path: Path) -> None:
|
||||
"""Clients defined in config should be registered in the OIDC server."""
|
||||
toml_content = """\
|
||||
issuer = "https://test.example.com"
|
||||
|
||||
[clients.test-rp]
|
||||
client_secret = "test-secret-0123456789abcdef"
|
||||
redirect_uris = ["https://app.example.com/callback"]
|
||||
scope = ["openid", "profile"]
|
||||
"""
|
||||
toml_file = tmp_path / "test.toml"
|
||||
toml_file.write_text(toml_content)
|
||||
|
||||
settings = Settings(_toml_file=str(toml_file))
|
||||
app = create_app(settings)
|
||||
|
||||
async with (
|
||||
AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client,
|
||||
app.router.lifespan_context(app),
|
||||
):
|
||||
response = await client.get("/health")
|
||||
assert response.status_code == 200
|
||||
|
||||
oidc_server = app.state.oidc_server
|
||||
assert "test-rp" in oidc_server.context.cdb
|
||||
cdb_entry = oidc_server.context.cdb["test-rp"]
|
||||
assert cdb_entry["client_id"] == "test-rp"
|
||||
assert cdb_entry["client_secret"] == "test-secret-0123456789abcdef"
|
||||
assert ("https://app.example.com/callback", {}) in cdb_entry["redirect_uris"]
|
||||
assert cdb_entry["scope"] == ["openid", "profile"]
|
||||
assert cdb_entry["allowed_scopes"] == ["openid", "profile"]
|
||||
|
||||
|
||||
async def test_manage_app_always_registered() -> None:
|
||||
"""The internal manage-app client is always registered, even without config file clients."""
|
||||
settings = Settings(issuer="https://test.example.com")
|
||||
app = create_app(settings)
|
||||
|
||||
async with (
|
||||
AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client,
|
||||
app.router.lifespan_context(app),
|
||||
):
|
||||
response = await client.get("/health")
|
||||
assert response.status_code == 200
|
||||
|
||||
oidc_server = app.state.oidc_server
|
||||
assert "manage-app" in oidc_server.context.cdb
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
# tests/test_config.py
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from porchlight.config import Settings, StorageBackend
|
||||
|
|
@ -28,10 +30,71 @@ def test_mongodb_settings() -> None:
|
|||
assert settings.mongodb_database == "test_db"
|
||||
|
||||
|
||||
def test_default_settings_has_empty_clients() -> None:
|
||||
settings = Settings(issuer="http://localhost:8000")
|
||||
assert settings.clients == {}
|
||||
|
||||
|
||||
def test_settings_from_env(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("OIDC_OP_ISSUER", "https://op.example.org")
|
||||
monkeypatch.setenv("OIDC_OP_STORAGE_BACKEND", "mongodb")
|
||||
monkeypatch.setenv("OIDC_OP_MONGODB_URI", "mongodb://remote:27017")
|
||||
settings = Settings() # type: ignore[call-arg]
|
||||
settings = Settings()
|
||||
assert settings.issuer == "https://op.example.org"
|
||||
assert settings.storage_backend == StorageBackend.MONGODB
|
||||
|
||||
|
||||
def test_settings_from_toml_file(tmp_path: Path) -> None:
|
||||
toml_content = """\
|
||||
issuer = "https://toml.example.com"
|
||||
debug = true
|
||||
sqlite_path = "custom/path.db"
|
||||
|
||||
[clients.my-app]
|
||||
client_secret = "secret123"
|
||||
redirect_uris = ["https://app.example.com/callback"]
|
||||
scope = ["openid", "profile"]
|
||||
"""
|
||||
toml_file = tmp_path / "test.toml"
|
||||
toml_file.write_text(toml_content)
|
||||
|
||||
settings = Settings(_toml_file=str(toml_file))
|
||||
assert settings.issuer == "https://toml.example.com"
|
||||
assert settings.debug is True
|
||||
assert settings.sqlite_path == "custom/path.db"
|
||||
assert "my-app" in settings.clients
|
||||
assert settings.clients["my-app"].client_secret == "secret123"
|
||||
assert settings.clients["my-app"].redirect_uris == ["https://app.example.com/callback"]
|
||||
assert settings.clients["my-app"].scope == ["openid", "profile"]
|
||||
assert settings.clients["my-app"].response_types == ["code"]
|
||||
assert settings.clients["my-app"].token_endpoint_auth_method == "client_secret_basic"
|
||||
|
||||
|
||||
def test_env_vars_override_toml_values(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
toml_content = """\
|
||||
issuer = "https://toml.example.com"
|
||||
debug = false
|
||||
"""
|
||||
toml_file = tmp_path / "test.toml"
|
||||
toml_file.write_text(toml_content)
|
||||
|
||||
monkeypatch.setenv("OIDC_OP_ISSUER", "https://env.example.com")
|
||||
monkeypatch.setenv("OIDC_OP_DEBUG", "true")
|
||||
settings = Settings(_toml_file=str(toml_file))
|
||||
assert settings.issuer == "https://env.example.com"
|
||||
assert settings.debug is True
|
||||
|
||||
|
||||
def test_missing_toml_file_uses_defaults() -> None:
|
||||
settings = Settings(issuer="http://localhost:8000", _toml_file="/nonexistent/path.toml")
|
||||
assert settings.issuer == "http://localhost:8000"
|
||||
assert settings.clients == {}
|
||||
|
||||
|
||||
def test_config_file_env_var_override(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
toml_file = tmp_path / "test.toml"
|
||||
toml_file.write_text('issuer = "https://custom-path.example.com"\n')
|
||||
|
||||
monkeypatch.setenv("OIDC_OP_CONFIG_FILE", str(toml_file))
|
||||
settings = Settings()
|
||||
assert settings.issuer == "https://custom-path.example.com"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue