Skip to content

Commit

Permalink
allow the app to be hosted at a prefix in script_name but still valid…
Browse files Browse the repository at this point in the history
…ate against allowed servers
  • Loading branch information
mmerickel authored and zupo committed Dec 7, 2024
1 parent 92797d9 commit 3d16116
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 2 deletions.
104 changes: 104 additions & 0 deletions pyramid_openapi3/tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,110 @@ def test_request_validation_disabled_response_validation_enabled(self) -> None:
self.assertEqual(start_response.status, "500 Internal Server Error")


class TestServerRequestValidation(RequestValidationBase): # noqa: D101

openapi_spec = (
b"openapi: '3.1.0'\n"
b"info:\n"
b" version: '1.0.0'\n"
b" title: Foo API\n"
b"servers:\n"
b" - url: /prefix/v1\n"
b" - url: http://example.com/prefix\n"
b"paths:\n"
b" /foo:\n"
b" get:\n"
b" responses:\n"
b" 200:\n"
b" description: A foo\n"
b" content:\n"
b" application/json:\n"
b" schema:\n"
b" type: object\n"
b" properties:\n"
b" test:\n"
b" type: string\n"
b" 400:\n"
b" description: Bad Request\n"
)

def test_server_validation_works_with_script_name(self) -> None:
"""Expect to find a match for http://localhost:8080/prefix/v1/foo."""
self._add_view(lambda *arg: {"test": "correct"})
# run request through router
router = Router(self.config.registry)
environ = {
"wsgi.url_scheme": "http",
"SERVER_NAME": "localhost",
"SERVER_PORT": "8080",
"REQUEST_METHOD": "GET",
"SCRIPT_NAME": "/prefix/v1",
"PATH_INFO": "/foo",
"HTTP_ACCEPT": "application/json",
}
start_response = DummyStartResponse()
response = router(environ, start_response)

self.assertEqual(start_response.status, "200 OK")
self.assertEqual(json.loads(response[0]), {"test": "correct"})

def test_server_validation_works_with_script_name_and_hostname(self) -> None:
"""Expect to find a match for http://example.com/prefix/foo."""
self._add_view(lambda *arg: {"test": "correct"})
# run request through router
router = Router(self.config.registry)
environ = {
"wsgi.url_scheme": "http",
"SERVER_NAME": "localhost",
"SERVER_PORT": "8080",
"REQUEST_METHOD": "GET",
"SCRIPT_NAME": "/prefix",
"PATH_INFO": "/foo",
"HTTP_HOST": "example.com",
"HTTP_ACCEPT": "application/json",
}
start_response = DummyStartResponse()
response = router(environ, start_response)

self.assertEqual(start_response.status, "200 OK")
self.assertEqual(json.loads(response[0]), {"test": "correct"})

def test_server_validation_fails_with_bad_hostname(self) -> None:
"""Expect to fail for /prefix/v2/foo."""
self._add_view()
# run request through router
router = Router(self.config.registry)
environ = {
"wsgi.url_scheme": "http",
"SERVER_NAME": "localhost",
"SERVER_PORT": "8080",
"REQUEST_METHOD": "GET",
"SCRIPT_NAME": "/prefix/v2",
"PATH_INFO": "/foo",
"HTTP_HOST": "example.com",
"HTTP_ACCEPT": "application/json",
}
start_response = DummyStartResponse()
with self.assertLogs(level="ERROR") as cm:
response = router(environ, start_response)
self.assertEqual(start_response.status, "500 Internal Server Error")
self.assertEqual(
json.loads(response[0]),
[
{
"exception": "ServerNotFound",
"message": "Server not found for http://example.com/prefix/v2/foo",
}
],
)
self.assertEqual(
cm.output,
[
"ERROR:pyramid_openapi3:Server not found for http://example.com/prefix/v2/foo"
],
)


class TestImproperAPISpecValidation(RequestValidationBase): # noqa: D101

openapi_spec = (
Expand Down
2 changes: 1 addition & 1 deletion pyramid_openapi3/tests/test_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def test_relative_app_request() -> None:
)
assert openapi_request.host_url == "http://example.com"
assert openapi_request.path == "/subpath/foo"
assert openapi_request.path_pattern == "/foo"
assert openapi_request.path_pattern == "/subpath/foo"
assert openapi_request.method == "get"
assert openapi_request.body == b""
assert openapi_request.mimetype == "text/html"
Expand Down
2 changes: 1 addition & 1 deletion pyramid_openapi3/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def path_pattern(self) -> str:
if self.request.matched_route
else self.request.path_info
)
return path_pattern
return self.request.script_name + path_pattern

@property
def method(self) -> str:
Expand Down

0 comments on commit 3d16116

Please sign in to comment.