From 03e1ca8510722b02b535a9a22aa4463772de7622 Mon Sep 17 00:00:00 2001 From: Jerry Chen Date: Mon, 10 May 2021 13:01:14 +1000 Subject: [PATCH 1/3] AWS::WAFv2::WebACL.CustomResponseBodies and AWS::WAFv2::RuleGroup.CustomResponseBodies --- tests/test_validators.py | 16 ++++++++++++++++ troposphere/validators.py | 19 +++++++++++++++++++ troposphere/wafv2.py | 25 ++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/tests/test_validators.py b/tests/test_validators.py index 3e8749d83..5c60c0dcd 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -27,6 +27,8 @@ task_type, tg_healthcheck_port, waf_action_type, + wafv2_custom_body_response_content, + wafv2_custom_body_response_content_type ) @@ -273,6 +275,20 @@ def test_waf_action_type(self): with self.assertRaises(ValueError): waf_action_type(s) + def test_wafv2_custom_body_response_content(self): + for s in ["{'hello': 'world'}", "Test

Test

Test.

", "Health"]: + wafv2_custom_body_response_content(s) + for s in ["", "a"*10241]: + with self.assertRaises(ValueError): + wafv2_custom_body_response_content(s) + + def test_wafv2_custom_body_response_content_type(self): + for s in ["APPLICATION_JSON", "TEXT_HTML", "TEXT_PLAIN"]: + wafv2_custom_body_response_content_type(s) + for s in ["", "APPLICATION", "HTML", "TEXT"]: + with self.assertRaises(ValueError): + wafv2_custom_body_response_content_type(s) + if __name__ == "__main__": unittest.main() diff --git a/troposphere/validators.py b/troposphere/validators.py index a9365a73f..122bd3596 100644 --- a/troposphere/validators.py +++ b/troposphere/validators.py @@ -658,3 +658,22 @@ def ecs_efs_encryption_status(status): % (", ".join(valid_status)) ) return status + +def wafv2_custom_body_response_content(content): + """validate wafv2 custom body response content. Any character between 1 to 10240 + """ + if not content: + raise ValueError("Content must not be empty") + + if len(content) > 10240: + raise ValueError("Content maximum length must not exceed 10240") + + return content + +def wafv2_custom_body_response_content_type(content_type): + """validate wafv2 custom response content type + """ + valid_types = ["APPLICATION_JSON", "TEXT_HTML", "TEXT_PLAIN"] + if content_type not in valid_types: + raise ValueError('ContentType must be one of: "%s"' % (", ".join(valid_types))) + return content_type diff --git a/troposphere/wafv2.py b/troposphere/wafv2.py index bd612e37a..743775745 100644 --- a/troposphere/wafv2.py +++ b/troposphere/wafv2.py @@ -4,7 +4,7 @@ # See LICENSE file for full license. from . import AWSObject, AWSProperty, Tags -from .validators import boolean, integer +from .validators import boolean, integer, wafv2_custom_body_response_content, wafv2_custom_body_response_content_type VALID_TRANSFORMATION_TYPES = ( "CMD_LINE", @@ -67,6 +67,21 @@ def validate_positional_constraint(positional_constraint): ) return positional_constraint +def validate_custom_response_bodies(custom_response_bodies): + """validate custom response bodies + """ + if not isinstance(custom_response_bodies, dict): + raise ValueError("CustomResponseBodies must be dict") + + for k, v in custom_response_bodies.items(): + if not isinstance(v, CustomResponseBody): + raise ValueError( + "value of %s must be type of CustomResponseBody" + % (key) + ) + + return custom_response_bodies + class ExcludedRule(AWSProperty): props = {"Name": (str, False)} @@ -354,6 +369,7 @@ class WebACL(AWSObject): resource_type = "AWS::WAFv2::WebACL" props = { + "CustomResponseBodies": (validate_custom_response_bodies, False), "DefaultAction": (DefaultAction, False), "Description": (str, False), "Name": (str, False), @@ -404,6 +420,7 @@ class RuleGroup(AWSObject): props = { "Capacity": (integer, False), + "CustomResponseBodies": (validate_custom_response_bodies, False), "Description": (str, False), "Name": (str, False), "Rules": ([RuleGroupRule], False), @@ -420,3 +437,9 @@ class WebACLAssociation(AWSObject): "ResourceArn": (str, True), "WebACLArn": (str, True), } + +class CustomResponseBody(AWSObject): + props = { + "Content": (wafv2_custom_body_response_content, True), + "ContentType": (wafv2_custom_body_response_content_type, True) + } From 9995bfa931419f2e7d142bf518ffc41569bab27b Mon Sep 17 00:00:00 2001 From: Jerry Chen Date: Mon, 10 May 2021 13:51:15 +1000 Subject: [PATCH 2/3] fix formats --- troposphere/validators.py | 2 ++ troposphere/wafv2.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/troposphere/validators.py b/troposphere/validators.py index 122bd3596..88c1f1308 100644 --- a/troposphere/validators.py +++ b/troposphere/validators.py @@ -659,6 +659,7 @@ def ecs_efs_encryption_status(status): ) return status + def wafv2_custom_body_response_content(content): """validate wafv2 custom body response content. Any character between 1 to 10240 """ @@ -670,6 +671,7 @@ def wafv2_custom_body_response_content(content): return content + def wafv2_custom_body_response_content_type(content_type): """validate wafv2 custom response content type """ diff --git a/troposphere/wafv2.py b/troposphere/wafv2.py index 743775745..526cde1ac 100644 --- a/troposphere/wafv2.py +++ b/troposphere/wafv2.py @@ -67,6 +67,7 @@ def validate_positional_constraint(positional_constraint): ) return positional_constraint + def validate_custom_response_bodies(custom_response_bodies): """validate custom response bodies """ @@ -77,7 +78,7 @@ def validate_custom_response_bodies(custom_response_bodies): if not isinstance(v, CustomResponseBody): raise ValueError( "value of %s must be type of CustomResponseBody" - % (key) + % (k) ) return custom_response_bodies @@ -438,6 +439,7 @@ class WebACLAssociation(AWSObject): "WebACLArn": (str, True), } + class CustomResponseBody(AWSObject): props = { "Content": (wafv2_custom_body_response_content, True), From 6f5c32979ab4a557845f1df83d15182e631ac309 Mon Sep 17 00:00:00 2001 From: Jerry Chen Date: Mon, 10 May 2021 13:55:19 +1000 Subject: [PATCH 3/3] remove white space --- troposphere/validators.py | 1 - 1 file changed, 1 deletion(-) diff --git a/troposphere/validators.py b/troposphere/validators.py index 88c1f1308..c5dd9f293 100644 --- a/troposphere/validators.py +++ b/troposphere/validators.py @@ -665,7 +665,6 @@ def wafv2_custom_body_response_content(content): """ if not content: raise ValueError("Content must not be empty") - if len(content) > 10240: raise ValueError("Content maximum length must not exceed 10240")