8000 Adjust to latest feedback · localstack/localstack@d150b6d · GitHub
[go: up one dir, main page]

Skip to content

Commit d150b6d

Browse files
committed
Adjust to latest feedback
1 parent 876b3ac commit d150b6d

File tree

3 files changed

+47
-12
lines changed

3 files changed

+47
-12
lines changed

localstack-core/localstack/aws/handlers/validation.py

Lines changed: 16 additions & 11 deletions
< 8000 td data-grid-cell-id="diff-a50e0798bccf43a6ee249f013e8f58d5990d6274b716d3905f9c9479c4d75c31-60-66-0" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-deletionNum-bgColor, var(--diffBlob-deletion-bgColor-num));text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative left-side">60
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,21 @@
2727
oas_path = os.path.join(os.path.dirname(__file__), "..", "..", "openapi.yaml")
2828

2929

30-
class OpenAPIRequestValidator(Handler):
30+
class OpenAPIValidator(Handler):
31+
openapi: "OpenAPI"
32+
33+
def __init__(self) -> None:
34+
path = Path(oas_path)
35+
assert path.exists()
36+
self.openapi = OpenAPI.from_path(path)
37+
38+
39+
class OpenAPIRequestValidator(OpenAPIValidator):
3140
"""
3241
Validates the requests to the LocalStack public endpoints (the ones with a _localstack or _aws prefix) against
3342
a OpenAPI specification.
3443
"""
3544

36-
def __init__(self):
37-
self.openapi = OpenAPI.from_path(Path(oas_path))
38-
3945
def __call__(self, chain: HandlerChain, context: RequestContext, response: Response):
4046
if not config.OPENAPI_VALIDATE_REQUEST:
4147
return
@@ -50,25 +56,24 @@ def __call__(self, chain: HandlerChain, context: RequestContext, response: Respo
5056
response.status_code = 400
5157
response.set_json({"error": "Bad Request", "message": str(e)})
5258
chain.stop()
53-
except OpenAPIError as e:
59+
except OpenAPIError:
5460
# Other errors can be raised when validating a request against the OpenAPI specification.
5561
# The most common are: ServerNotFound, OperationNotFound, or PathNotFound.
5662
# We explicitly do not check any other error but RequestValidationError ones.
57-
LOG.debug("OpenAPI validation exception: (%s): %s", e.__class__.__name__, str(e))
58-
63+
# We shallow the exception to avoid excessive logging (e.g., a lot of ServerNotFound), as the only
64+
# purpose of this handler is to check for request validation errors.
65+
pass
5966

-
class OpenAPIResponseValidator(Handler):
61-
def __init__(self):
62-
self.openapi = OpenAPI.from_path(Path(oas_path))
6367

68+
class OpenAPIResponseValidator(OpenAPIValidator):
6469
def __call__(self, chain: HandlerChain, context: RequestContext, response: Response):
6570
# We are more lenient in validating the responses. The use of this flag is intended for test.
6671
if not config.OPENAPI_VALIDATE_RESPONSE:
6772
return
6873

6974
path = context.request.path
7075

71-
if path.startswith(INTERNAL_RESOURCE_PATH) or path.startswith("/_aws/"):
76+
if path.startswith(f"{INTERNAL_RESOURCE_PATH}/") or path.startswith("/_aws/"):
7277
try:
7378
self.openapi.validate_response(
7479
WerkzeugOpenAPIRequest(context.request),

localstack-core/localstack/openapi.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ externalDocs:
1313
description: LocalStack Documentation
1414
url: https://docs.localstack.cloud
1515
servers:
16-
- url: http://localhost.localstack.cloud:{port}
16+
- url: http://{host}:{port}
1717
variables:
1818
port:
1919
default: '4566'
20+
host:
21+
default: 'localhost.localstack.cloud'
2022
components:
2123
parameters:
2224
SesMessageId:

tests/unit/aws/handlers/openapi.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import json
22

3+
import pytest
34
from rolo import Request, Response
45
from rolo.gateway import RequestContext
56
from rolo.gateway.handlers import EmptyResponseHandler
67

8+
from localstack import config
79
from localstack.aws.chain import HandlerChain
810
from localstack.aws.handlers.validation import OpenAPIRequestValidator
911

1012

13+
@pytest.fixture(autouse=True)
14+
def enable_validation_flag(monkeypatch):
15+
monkeypatch.setattr(config, "OPENAPI_VALIDATE_REQUEST", "1")
16+
17+
1118
class TestOpenAPIRequestValidator:
1219
def test_valid_request(self):
1320
chain = HandlerChain([OpenAPIRequestValidator()])
@@ -57,6 +64,27 @@ def test_path_not_found(self):
5764
assert response.status_code == 404
5865
assert response.data == b'{"message": "Not Found"}'
5966

67+
def test_both_validation_and_server_error(self):
68+
# Request with invalid host and body validation error
69+
chain = HandlerChain([OpenAPIRequestValidator()])
70+
context = RequestContext(
71+
Request(
72+
path="/_localstack/config",
73+
method="POST",
74+
body=json.dumps({"variable": "", "value": "BAZ"}),
75+
scheme="http",
76+
headers={
77+
"Host": "unknown:4566",
78+
"Content-Type": "application/json",
79+
},
80+
)
81+
)
82+
response = Response()
83+
chain.handle(context=context, response=response)
84+
assert response.status_code == 400
85+
assert response.json["error"] == "Bad Request"
86+
assert response.json["message"] == "Request body validation error"
87+
6088
def test_body_validation_errors(self):
6189
body = {"variable": "FOO", "value": "BAZ"}
6290
chain = HandlerChain([OpenAPIRequestValidator()])

0 commit comments

Comments
 (0)
0