Skip to content

Commit

Permalink
r/aws_wafv2_web_acl: Support Challenge in Rule Action
Browse files Browse the repository at this point in the history
  • Loading branch information
Javi López-Nieto committed Dec 12, 2022
1 parent 51aa90b commit 6774a21
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 20 deletions.
41 changes: 41 additions & 0 deletions internal/service/wafv2/flex.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ func expandRuleAction(l []interface{}) *wafv2.RuleAction {
action.Captcha = expandCaptchaAction(v.([]interface{}))
}

if v, ok := m["challenge"]; ok && len(v.([]interface{})) > 0 {
action.Challenge = expandChallengeAction(v.([]interface{}))
}

if v, ok := m["count"]; ok && len(v.([]interface{})) > 0 {
action.Count = expandCountAction(v.([]interface{}))
}
Expand Down Expand Up @@ -148,6 +152,25 @@ func expandCaptchaAction(l []interface{}) *wafv2.CaptchaAction {
return action
}

func expandChallengeAction(l []interface{}) *wafv2.ChallengeAction {
action := &wafv2.ChallengeAction{}

if len(l) == 0 || l[0] == nil {
return action
}

m, ok := l[0].(map[string]interface{})
if !ok {
return action
}

if v, ok := m["custom_request_handling"].([]interface{}); ok && len(v) > 0 {
action.CustomRequestHandling = expandCustomRequestHandling(v)
}

return action
}

func expandCountAction(l []interface{}) *wafv2.CountAction {
action := &wafv2.CountAction{}

Expand Down Expand Up @@ -1118,6 +1141,10 @@ func flattenRuleAction(a *wafv2.RuleAction) interface{} {
m["captcha"] = flattenCaptcha(a.Captcha)
}

if a.Challenge != nil {
m["challenge"] = flattenChallenge(a.Challenge)
}

if a.Count != nil {
m["count"] = flattenCount(a.Count)
}
Expand Down Expand Up @@ -1166,6 +1193,20 @@ func flattenCaptcha(a *wafv2.CaptchaAction) []interface{} {
return []interface{}{m}
}

func flattenChallenge(a *wafv2.ChallengeAction) []interface{} {
if a == nil {
return []interface{}{}
}

m := map[string]interface{}{}

if a.CustomRequestHandling != nil {
m["custom_request_handling"] = flattenCustomRequestHandling(a.CustomRequestHandling)
}

return []interface{}{m}
}

func flattenCount(a *wafv2.CountAction) []interface{} {
if a == nil {
return []interface{}{}
Expand Down
13 changes: 13 additions & 0 deletions internal/service/wafv2/schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,19 @@ func captchaConfigSchema() *schema.Schema {
}
}

func challengeConfigSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"custom_request_handling": customRequestHandlingSchema(),
},
},
}
}

func countConfigSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Expand Down
9 changes: 5 additions & 4 deletions internal/service/wafv2/web_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ func ResourceWebACL() *schema.Resource {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"allow": allowConfigSchema(),
"block": blockConfigSchema(),
"captcha": captchaConfigSchema(),
"count": countConfigSchema(),
"allow": allowConfigSchema(),
"block": blockConfigSchema(),
"captcha": captchaConfigSchema(),
"challenge": challengeConfigSchema(),
"count": countConfigSchema(),
},
},
},
Expand Down
104 changes: 89 additions & 15 deletions internal/service/wafv2/web_acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,14 @@ func TestAccWAFV2WebACL_ManagedRuleGroup_basic(t *testing.T) {
"statement.0.managed_rule_group_statement.0.rule_action_override.0.action_to_use.0.allow.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.0.action_to_use.0.block.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.0.action_to_use.0.captcha.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.0.action_to_use.0.challenge.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.0.action_to_use.0.count.#": "1",
"statement.0.managed_rule_group_statement.0.rule_action_override.0.name": "SizeRestrictions_QUERYSTRING",
"statement.0.managed_rule_group_statement.0.rule_action_override.1.action_to_use.#": "1",
"statement.0.managed_rule_group_statement.0.rule_action_override.1.action_to_use.0.allow.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.1.action_to_use.0.block.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.1.action_to_use.0.captcha.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.1.action_to_use.0.challenge.#": "0",
"statement.0.managed_rule_group_statement.0.rule_action_override.1.action_to_use.0.count.#": "1",
"statement.0.managed_rule_group_statement.0.rule_action_override.1.name": "NoUserAgent_HEADER",
"statement.0.managed_rule_group_statement.0.scope_down_statement.#": "1",
Expand Down Expand Up @@ -1466,10 +1468,11 @@ func TestAccWAFV2WebACL_Custom_requestHandling(t *testing.T) {
"action.0.allow.0.custom_request_handling.0.insert_header.0.value": "test-value-1",
"action.0.allow.0.custom_request_handling.0.insert_header.1.name": "x-hdr2",
"action.0.allow.0.custom_request_handling.0.insert_header.1.value": "test-value-2",
"action.0.block.#": "0",
"action.0.captcha.#": "0",
"action.0.count.#": "0",
"priority": "1",
"action.0.block.#": "0",
"action.0.captcha.#": "0",
"action.0.challenge.#": "0",
"action.0.count.#": "0",
"priority": "1",
}),
resource.TestCheckResourceAttr(resourceName, "visibility_config.#", "1"),
resource.TestCheckResourceAttr(resourceName, "visibility_config.0.cloudwatch_metrics_enabled", "false"),
Expand All @@ -1495,12 +1498,13 @@ func TestAccWAFV2WebACL_Custom_requestHandling(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "scope", "REGIONAL"),
resource.TestCheckResourceAttr(resourceName, "rule.#", "1"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"name": "rule-1",
"action.#": "1",
"action.0.allow.#": "0",
"action.0.block.#": "0",
"action.0.captcha.#": "0",
"action.0.count.#": "1",
"name": "rule-1",
"action.#": "1",
"action.0.allow.#": "0",
"action.0.block.#": "0",
"action.0.captcha.#": "0",
"action.0.challenge.#": "0",
"action.0.count.#": "1",
"action.0.count.0.custom_request_handling.#": "1",
"action.0.count.0.custom_request_handling.0.insert_header.#": "2",
"action.0.count.0.custom_request_handling.0.insert_header.0.name": "x-hdr1",
Expand All @@ -1527,11 +1531,12 @@ func TestAccWAFV2WebACL_Custom_requestHandling(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "scope", "REGIONAL"),
resource.TestCheckResourceAttr(resourceName, "rule.#", "1"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"name": "rule-1",
"action.#": "1",
"action.0.allow.#": "0",
"action.0.block.#": "0",
"action.0.captcha.#": "1",
"name": "rule-1",
"action.#": "1",
"action.0.allow.#": "0",
"action.0.block.#": "0",
"action.0.captcha.#": "1",
"action.0.challenge.#": "0",
"action.0.captcha.0.custom_request_handling.#": "1",
"action.0.captcha.0.custom_request_handling.0.insert_header.#": "2",
"action.0.captcha.0.custom_request_handling.0.insert_header.0.name": "x-hdr1",
Expand All @@ -1547,6 +1552,33 @@ func TestAccWAFV2WebACL_Custom_requestHandling(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "visibility_config.0.sampled_requests_enabled", "false"),
),
},
{
Config: testAccWebACLConfig_customRequestHandlingChallenge(webACLName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWebACLExists(resourceName, &v),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/webacl/.+$`)),
resource.TestCheckResourceAttr(resourceName, "name", webACLName),
resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"),
resource.TestCheckResourceAttr(resourceName, "default_action.0.allow.#", "1"),
resource.TestCheckResourceAttr(resourceName, "default_action.0.block.#", "0"),
resource.TestCheckResourceAttr(resourceName, "scope", "REGIONAL"),
resource.TestCheckResourceAttr(resourceName, "rule.#", "1"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"name": "rule-1",
"action.#": "1",
"action.0.allow.#": "0",
"action.0.block.#": "0",
"action.0.captcha.#": "0",
"action.0.challenge.#": "1",
"action.0.count.#": "0",
"priority": "1",
}),
resource.TestCheckResourceAttr(resourceName, "visibility_config.#", "1"),
resource.TestCheckResourceAttr(resourceName, "visibility_config.0.cloudwatch_metrics_enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "visibility_config.0.metric_name", "friendly-metric-name"),
resource.TestCheckResourceAttr(resourceName, "visibility_config.0.sampled_requests_enabled", "false"),
),
},
},
})
}
Expand Down Expand Up @@ -2383,6 +2415,48 @@ resource "aws_wafv2_web_acl" "test" {
`, name, firstHeader, secondHeader)
}

func testAccWebACLConfig_customRequestHandlingChallenge(name string) string {
return fmt.Sprintf(`
resource "aws_wafv2_web_acl" "test" {
name = %[1]q
description = %[1]q
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "rule-1"
priority = 1
action {
challenge {}
}
}
statement {
geo_match_statement {
country_codes = ["US", "CA"]
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "friendly-rule-metric-name"
sampled_requests_enabled = false
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "friendly-metric-name"
sampled_requests_enabled = false
}
}
`, name)
}

func testAccWebACLConfig_customRequestHandlingCount(name, firstHeader string, secondHeader string) string {
return fmt.Sprintf(`
resource "aws_wafv2_web_acl" "test" {
Expand Down
10 changes: 9 additions & 1 deletion website/docs/r/wafv2_web_acl.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ subcategory: "WAF"
layout: "aws"
page_title: "AWS: aws_wafv2_web_acl"
description: |-
Creates a WAFv2 Web ACL resource.
Creates a WAFv2 Web ACL resource.
---

# Resource: aws_wafv2_web_acl
Expand Down Expand Up @@ -318,6 +318,7 @@ The `action` block supports the following arguments:
* `allow` - (Optional) Instructs AWS WAF to allow the web request. See [Allow](#action) below for details.
* `block` - (Optional) Instructs AWS WAF to block the web request. See [Block](#block) below for details.
* `captcha` - (Optional) Instructs AWS WAF to run a Captcha check against the web request. See [Captcha](#captcha) below for details.
* `challenge` - (Optional) Instructs AWS WAF to run a check against the request to verify that the request is coming from a legitimate client session. See [Challenge](#challenge) below for details.
* `count` - (Optional) Instructs AWS WAF to count the web request and allow it. See [Count](#count) below for details.

### Override Action
Expand Down Expand Up @@ -347,6 +348,13 @@ The `captcha` block supports the following arguments:

* `custom_request_handling` - (Optional) Defines custom handling for the web request. See [Custom Request Handling](#custom-request-handling) below for details.

### Challenge

The `challenge` block supports the following arguments:

* `custom_request_handling` - (Optional) Defines custom handling for the web request. See [Custom Request Handling](#custom-request-handling) below for details.


### Count

The `count` block supports the following arguments:
Expand Down

0 comments on commit 6774a21

Please sign in to comment.