Skip to content

Commit 48455fd

Browse files
committed
refactor: HttpVerb as enum
1 parent d208976 commit 48455fd

File tree

2 files changed

+38
-35
lines changed

2 files changed

+38
-35
lines changed

Diff for: aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py

+26-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import enum
12
import re
23
from typing import Any, Dict, List, Optional
34

@@ -312,7 +313,7 @@ def asdict(self) -> dict:
312313
return response
313314

314315

315-
class HttpVerb:
316+
class HttpVerb(enum.Enum):
316317
GET = "GET"
317318
POST = "POST"
318319
PUT = "PUT"
@@ -386,8 +387,9 @@ def _add_route(self, effect: str, verb: str, resource: str, conditions: List[Dic
386387
"""Adds a route to the internal lists of allowed or denied routes. Each object in
387388
the internal list contains a resource ARN and a condition statement. The condition
388389
statement can be null."""
389-
if verb != "*" and not hasattr(HttpVerb, verb):
390-
raise ValueError(f"Invalid HTTP verb {verb}. Allowed verbs in HttpVerb class")
390+
if verb != "*" and verb not in HttpVerb.__members__:
391+
allowed_values = [verb.value for verb in HttpVerb]
392+
raise ValueError(f"Invalid HTTP verb: '{verb}'. Use either '{allowed_values}'")
391393

392394
resource_pattern = re.compile(self.path_regex)
393395
if not resource_pattern.match(resource):
@@ -433,29 +435,42 @@ def _get_statement_for_effect(self, effect: str, methods: List) -> List:
433435

434436
return statements
435437

436-
def allow_all_routes(self):
437-
"""Adds a '*' allow to the policy to authorize access to all methods of an API"""
438-
self._add_route("Allow", HttpVerb.ALL, "*", [])
438+
def allow_all_routes(self, http_method: str = HttpVerb.ALL.value):
439+
"""Adds a '*' allow to the policy to authorize access to all methods of an API
439440
440-
def deny_all_routes(self):
441-
"""Adds a '*' allow to the policy to deny access to all methods of an API"""
442-
self._add_route("Deny", HttpVerb.ALL, "*", [])
441+
Parameters
442+
----------
443+
http_method: str
444+
"""
445+
self._add_route(effect="Allow", verb=http_method, resource="*", conditions=[])
446+
447+
def deny_all_routes(self, http_method: str = HttpVerb.ALL.value):
448+
"""Adds a '*' allow to the policy to deny access to all methods of an API
449+
450+
Parameters
451+
----------
452+
http_method: str
453+
"""
454+
455+
self._add_route(effect="Deny", verb=http_method, resource="*", conditions=[])
443456

444457
def allow_route(self, http_method: str, resource: str, conditions: Optional[List[Dict]] = None):
445458
"""Adds an API Gateway method (Http verb + Resource path) to the list of allowed
446459
methods for the policy.
447460
448461
Optionally includes a condition for the policy statement. More on AWS policy
449462
conditions here: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition"""
450-
self._add_route("Allow", http_method, resource, conditions or [])
463+
conditions = conditions or []
464+
self._add_route(effect="Allow", verb=http_method, resource=resource, conditions=conditions)
451465

452466
def deny_route(self, http_method: str, resource: str, conditions: Optional[List[Dict]] = None):
453467
"""Adds an API Gateway method (Http verb + Resource path) to the list of denied
454468
methods for the policy.
455469
456470
Optionally includes a condition for the policy statement. More on AWS policy
457471
conditions here: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition"""
458-
self._add_route("Deny", http_method, resource, conditions or [])
472+
conditions = conditions or []
473+
self._add_route(effect="Deny", verb=http_method, resource=resource, conditions=conditions)
459474

460475
def asdict(self) -> Dict[str, Any]:
461476
"""Generates the policy document based on the internal lists of allowed and denied

Diff for: tests/functional/data_classes/test_api_gateway_authorizer.py

+12-24
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,17 @@ def test_authorizer_response_no_statement(builder: APIGatewayAuthorizerResponse)
2222

2323

2424
def test_authorizer_response_invalid_verb(builder: APIGatewayAuthorizerResponse):
25-
with pytest.raises(ValueError) as ex:
25+
with pytest.raises(ValueError, match="Invalid HTTP verb: 'INVALID'"):
2626
# GIVEN a invalid http_method
2727
# WHEN calling deny_method
28-
builder.deny_route("INVALID", "foo")
29-
30-
# THEN raise a name error for invalid http verb
31-
assert str(ex.value) == "Invalid HTTP verb INVALID. Allowed verbs in HttpVerb class"
28+
builder.deny_route(http_method="INVALID", resource="foo")
3229

3330

3431
def test_authorizer_response_invalid_resource(builder: APIGatewayAuthorizerResponse):
35-
with pytest.raises(ValueError) as ex:
32+
with pytest.raises(ValueError, match="Invalid resource path: \$."): # noqa: W605
3633
# GIVEN a invalid resource path "$"
3734
# WHEN calling deny_method
38-
builder.deny_route(HttpVerb.GET, "$")
39-
40-
# THEN raise a name error for invalid resource
41-
assert "Invalid resource path: $" in str(ex.value)
35+
builder.deny_route(http_method=HttpVerb.GET.value, resource="$")
4236

4337

4438
def test_authorizer_response_allow_all_routes_with_context():
@@ -78,7 +72,7 @@ def test_authorizer_response_deny_all_routes(builder: APIGatewayAuthorizerRespon
7872

7973

8074
def test_authorizer_response_allow_route(builder: APIGatewayAuthorizerResponse):
81-
builder.allow_route(HttpVerb.GET, "/foo")
75+
builder.allow_route(http_method=HttpVerb.GET.value, resource="/foo")
8276
assert builder.asdict() == {
8377
"policyDocument": {
8478
"Version": "2012-10-17",
@@ -95,7 +89,7 @@ def test_authorizer_response_allow_route(builder: APIGatewayAuthorizerResponse):
9589

9690

9791
def test_authorizer_response_deny_route(builder: APIGatewayAuthorizerResponse):
98-
builder.deny_route(HttpVerb.PUT, "foo")
92+
builder.deny_route(http_method=HttpVerb.PUT.value, resource="foo")
9993
assert builder.asdict() == {
10094
"principalId": "foo",
10195
"policyDocument": {
@@ -112,12 +106,11 @@ def test_authorizer_response_deny_route(builder: APIGatewayAuthorizerResponse):
112106

113107

114108
def test_authorizer_response_allow_route_with_conditions(builder: APIGatewayAuthorizerResponse):
109+
condition = {"StringEquals": {"method.request.header.Content-Type": "text/html"}}
115110
builder.allow_route(
116-
HttpVerb.POST,
117-
"/foo",
118-
[
119-
{"StringEquals": {"method.request.header.Content-Type": "text/html"}},
120-
],
111+
http_method=HttpVerb.POST.value,
112+
resource="/foo",
113+
conditions=[condition],
121114
)
122115
assert builder.asdict() == {
123116
"principalId": "foo",
@@ -136,13 +129,8 @@ def test_authorizer_response_allow_route_with_conditions(builder: APIGatewayAuth
136129

137130

138131
def test_authorizer_response_deny_route_with_conditions(builder: APIGatewayAuthorizerResponse):
139-
builder.deny_route(
140-
HttpVerb.POST,
141-
"/foo",
142-
[
143-
{"StringEquals": {"method.request.header.Content-Type": "application/json"}},
144-
],
145-
)
132+
condition = {"StringEquals": {"method.request.header.Content-Type": "application/json"}}
133+
builder.deny_route(http_method=HttpVerb.POST.value, resource="/foo", conditions=[condition])
146134
assert builder.asdict() == {
147135
"principalId": "foo",
148136
"policyDocument": {

0 commit comments

Comments
 (0)