| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 | from http import HTTPStatusimport pytestfrom fastapi.testclient import TestClientfrom clean_python import ctxfrom clean_python import InMemoryGatewayfrom clean_python.fastapi import getfrom clean_python.fastapi import Resourcefrom clean_python.fastapi import Servicefrom clean_python.fastapi import vfrom clean_python.oauth2 import OAuth2SPAClientSettingsfrom clean_python.oauth2 import TokenVerifierSettingsclass FooResource(Resource, version=v(1), name="testing"):    @get("/foo")    def testing(self):        return "ok"    @get("/bar", scope="admin")    def scoped(self):        return "ok"    @get("/context")    def context(self):        return {            "path": str(ctx.path),            "user": ctx.user,            "tenant": ctx.tenant,        }@pytest.fixture(params=["noclient", "client"])def app(request, settings: TokenVerifierSettings):    if request.param == "noclient":        auth_client = None    elif request.param == "client":        auth_client = OAuth2SPAClientSettings(            client_id="123",            token_url="https://server/token",            authorization_url="https://server/token",        )    return Service(FooResource()).create_app(        title="test",        description="testing",        hostname="testserver",        auth=settings,        auth_client=auth_client,        access_logger_gateway=InMemoryGateway([]),    )@pytest.fixturedef client(app):    return TestClient(app)@pytest.mark.usefixtures("jwk_patched")def test_no_header(app, client: TestClient):    response = client.get(app.url_path_for("v1/testing"))    assert response.status_code == HTTPStatus.UNAUTHORIZED@pytest.mark.usefixtures("jwk_patched")def test_ok(app, client: TestClient, token_generator):    response = client.get(        app.url_path_for("v1/testing"),        headers={"Authorization": "Bearer " + token_generator()},    )    assert response.status_code == HTTPStatus.OK@pytest.mark.usefixtures("jwk_patched")def test_scoped_ok(app, client: TestClient, token_generator):    response = client.get(        app.url_path_for("v1/scoped"),        headers={"Authorization": "Bearer " + token_generator(scope="user admin")},    )    assert response.status_code == HTTPStatus.OK@pytest.mark.usefixtures("jwk_patched")def test_scoped_forbidden(app, client: TestClient, token_generator):    response = client.get(        app.url_path_for("v1/scoped"),        headers={"Authorization": "Bearer " + token_generator(scope="user")},    )    assert response.status_code == HTTPStatus.FORBIDDEN@pytest.mark.usefixtures("jwk_patched")def test_context(app, client: TestClient, token_generator):    response = client.get(        app.url_path_for("v1/context"),        headers={            "Authorization": "Bearer " + token_generator(tenant=2, tenant_name="bar")        },    )    assert response.status_code == HTTPStatus.OK    assert response.json() == {        "path": "http://testserver/v1/context",        "user": {"id": "foo", "name": "piet"},        "tenant": {"id": 2, "name": "bar"},    }    assert ctx.user.id != "foo"    assert ctx.tenant is None
 |