Skip to content

Commit

Permalink
Merge pull request #29608 from XciD/f-add-captcha-config
Browse files Browse the repository at this point in the history
Add captcha config to wafv2
  • Loading branch information
ewbankkit authored Apr 20, 2023
2 parents 67807d0 + c217cb5 commit 5149834
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .changelog/29608.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_wafv2_rule_group: Add `rule.captcha_config` argument
```

```release-note:enhancement
resource/aws_wafv2_web_acl: Add `captcha_config` and `rule.captcha_config` arguments
```
53 changes: 50 additions & 3 deletions internal/service/wafv2/flex.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ func expandRule(m map[string]interface{}) *wafv2.Rule {
}

rule := &wafv2.Rule{
Action: expandRuleAction(m["action"].([]interface{})),
CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})),
Name: aws.String(m["name"].(string)),
Priority: aws.Int64(int64(m["priority"].(int))),
Action: expandRuleAction(m["action"].([]interface{})),
Statement: expandRuleGroupRootStatement(m["statement"].([]interface{})),
VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})),
}
Expand All @@ -44,6 +45,32 @@ func expandRule(m map[string]interface{}) *wafv2.Rule {
return rule
}

func expandCaptchaConfig(l []interface{}) *wafv2.CaptchaConfig {
configuration := &wafv2.CaptchaConfig{}

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

m := l[0].(map[string]interface{})
if v, ok := m["immunity_time_property"]; ok {
inner := v.([]interface{})
if len(inner) == 0 || inner[0] == nil {
return configuration
}

m = inner[0].(map[string]interface{})

if v, ok := m["immunity_time"]; ok {
configuration.ImmunityTimeProperty = &wafv2.ImmunityTimeProperty{
ImmunityTime: aws.Int64(int64(v.(int))),
}
}
}

return configuration
}

func expandRuleLabels(l []interface{}) []*wafv2.Label {
if len(l) == 0 || l[0] == nil {
return nil
Expand Down Expand Up @@ -848,10 +875,11 @@ func expandWebACLRule(m map[string]interface{}) *wafv2.Rule {
}

rule := &wafv2.Rule{
Name: aws.String(m["name"].(string)),
Priority: aws.Int64(int64(m["priority"].(int))),
Action: expandRuleAction(m["action"].([]interface{})),
CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})),
Name: aws.String(m["name"].(string)),
OverrideAction: expandOverrideAction(m["override_action"].([]interface{})),
Priority: aws.Int64(int64(m["priority"].(int))),
Statement: expandWebACLRootStatement(m["statement"].([]interface{})),
VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})),
}
Expand Down Expand Up @@ -1323,6 +1351,7 @@ func flattenRules(r []*wafv2.Rule) interface{} {
for i, rule := range r {
m := make(map[string]interface{})
m["action"] = flattenRuleAction(rule.Action)
m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig)
m["name"] = aws.StringValue(rule.Name)
m["priority"] = int(aws.Int64Value(rule.Priority))
m["rule_label"] = flattenRuleLabels(rule.RuleLabels)
Expand Down Expand Up @@ -1405,6 +1434,23 @@ func flattenCaptcha(a *wafv2.CaptchaAction) []interface{} {
return []interface{}{m}
}

func flattenCaptchaConfig(config *wafv2.CaptchaConfig) interface{} {
if config == nil {
return []interface{}{}
}
if config.ImmunityTimeProperty == nil {
return []interface{}{}
}

m := map[string]interface{}{
"immunity_time_property": []interface{}{map[string]interface{}{
"immunity_time": aws.Int64Value(config.ImmunityTimeProperty.ImmunityTime),
}},
}

return []interface{}{m}
}

func flattenChallenge(a *wafv2.ChallengeAction) []interface{} {
if a == nil {
return []interface{}{}
Expand Down Expand Up @@ -2074,6 +2120,7 @@ func flattenWebACLRules(r []*wafv2.Rule) interface{} {
for i, rule := range r {
m := make(map[string]interface{})
m["action"] = flattenRuleAction(rule.Action)
m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig)
m["override_action"] = flattenOverrideAction(rule.OverrideAction)
m["name"] = aws.StringValue(rule.Name)
m["priority"] = int(aws.Int64Value(rule.Priority))
Expand Down
3 changes: 2 additions & 1 deletion internal/service/wafv2/rule_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ func ResourceRuleGroup() *schema.Resource {
Schema: map[string]*schema.Schema{
"allow": allowConfigSchema(),
"block": blockConfigSchema(),
"count": countConfigSchema(),
"captcha": captchaConfigSchema(),
"count": countConfigSchema(),
},
},
},
"captcha_config": outerCaptchaConfigSchema(),
"name": {
Type: schema.TypeString,
Required: true,
Expand Down
25 changes: 25 additions & 0 deletions internal/service/wafv2/schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,31 @@ func captchaConfigSchema() *schema.Schema {
}
}

func outerCaptchaConfigSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"immunity_time_property": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"immunity_time": {
Type: schema.TypeInt,
Optional: true,
},
},
},
},
},
},
}
}

func challengeConfigSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Expand Down
7 changes: 7 additions & 0 deletions internal/service/wafv2/web_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func ResourceWebACL() *schema.Resource {
Type: schema.TypeInt,
Computed: true,
},
"captcha_config": outerCaptchaConfigSchema(),
"custom_response_body": customResponseBodySchema(),
"default_action": {
Type: schema.TypeList,
Expand Down Expand Up @@ -111,6 +112,7 @@ func ResourceWebACL() *schema.Resource {
},
},
},
"captcha_config": outerCaptchaConfigSchema(),
"name": {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -157,6 +159,7 @@ func resourceWebACLCreate(ctx context.Context, d *schema.ResourceData, meta inte

name := d.Get("name").(string)
input := &wafv2.CreateWebACLInput{
CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})),
DefaultAction: expandDefaultAction(d.Get("default_action").([]interface{})),
Name: aws.String(name),
Rules: expandWebACLRules(d.Get("rule").(*schema.Set).List()),
Expand Down Expand Up @@ -207,6 +210,9 @@ func resourceWebACLRead(ctx context.Context, d *schema.ResourceData, meta interf
arn := aws.StringValue(webACL.ARN)
d.Set("arn", arn)
d.Set("capacity", webACL.Capacity)
if err := d.Set("captcha_config", flattenCaptchaConfig(webACL.CaptchaConfig)); err != nil {
return diag.Errorf("setting captcha_config: %s", err)
}
if err := d.Set("custom_response_body", flattenCustomResponseBodies(webACL.CustomResponseBodies)); err != nil {
return diag.Errorf("setting custom_response_body: %s", err)
}
Expand All @@ -232,6 +238,7 @@ func resourceWebACLUpdate(ctx context.Context, d *schema.ResourceData, meta inte

if d.HasChangesExcept("tags", "tags_all") {
input := &wafv2.UpdateWebACLInput{
CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})),
DefaultAction: expandDefaultAction(d.Get("default_action").([]interface{})),
Id: aws.String(d.Id()),
LockToken: aws.String(d.Get("lock_token").(string)),
Expand Down
17 changes: 17 additions & 0 deletions internal/service/wafv2/web_acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func TestAccWAFV2WebACL_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", webACLName),
resource.TestCheckResourceAttr(resourceName, "rule.#", "0"),
resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional),
resource.TestCheckResourceAttr(resourceName, "captcha_config.#", "0"),
resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"),
resource.TestCheckResourceAttr(resourceName, "default_action.0.allow.#", "1"),
resource.TestCheckResourceAttr(resourceName, "default_action.0.block.#", "0"),
Expand Down Expand Up @@ -2035,11 +2036,15 @@ func TestAccWAFV2WebACL_Custom_requestHandling(t *testing.T) {
"action.0.captcha.0.custom_request_handling.0.insert_header.1.value": "test-value-2",
"action.0.count.#": "0",
"priority": "1",
"captcha_config.#": "1",
"captcha_config.0.immunity_time_property.0.immunity_time": "240",
}),
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"),
resource.TestCheckResourceAttr(resourceName, "captcha_config.#", "1"),
resource.TestCheckResourceAttr(resourceName, "captcha_config.0.immunity_time_property.0.immunity_time", "120"),
),
},
{
Expand Down Expand Up @@ -2951,13 +2956,25 @@ resource "aws_wafv2_web_acl" "test" {
metric_name = "friendly-rule-metric-name"
sampled_requests_enabled = false
}
captcha_config {
immunity_time_property {
immunity_time = 240
}
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "friendly-metric-name"
sampled_requests_enabled = false
}
captcha_config {
immunity_time_property {
immunity_time = 120
}
}
}
`, name, firstHeader, secondHeader)
}
Expand Down
25 changes: 25 additions & 0 deletions website/docs/r/wafv2_rule_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@ resource "aws_wafv2_rule_group" "example" {
metric_name = "rule-2"
sampled_requests_enabled = false
}
captcha_config {
immunity_time_property {
immunity_time = 240
}
}
}
rule {
Expand Down Expand Up @@ -293,6 +299,12 @@ resource "aws_wafv2_rule_group" "example" {
sampled_requests_enabled = false
}
captcha_config {
immunity_time_property {
immunity_time = 120
}
}
tags = {
Name = "example-and-statement"
Code = "123456"
Expand Down Expand Up @@ -326,6 +338,7 @@ Each `custom_response_body` block supports the following arguments:
Each `rule` supports the following arguments:

* `action` - (Required) The action that AWS WAF should take on a web request when it matches the rule's statement. Settings at the `aws_wafv2_web_acl` level can override the rule action setting. See [Action](#action) below for details.
* `captcha_config` - (Optional) Specifies how AWS WAF should handle CAPTCHA evaluations. See [Captcha Configuration](#captcha-configuration) below for details.
* `name` - (Required, Forces new resource) A friendly name of the rule.
* `priority` - (Required) If you define more than one Rule in a WebACL, AWS WAF evaluates each request against the `rules` in order based on the value of `priority`. AWS WAF processes rules with lower priority first.
* `rule_label` - (Optional) Labels to apply to web requests that match the rule match statement. See [Rule Label](#rule-label) below for details.
Expand Down Expand Up @@ -654,6 +667,18 @@ The `visibility_config` block supports the following arguments:
* `metric_name` - (Required, Forces new resource) A friendly name of the CloudWatch metric. The name can contain only alphanumeric characters (A-Z, a-z, 0-9) hyphen(-) and underscore (_), with length from one to 128 characters. It can't contain whitespace or metric names reserved for AWS WAF, for example `All` and `Default_Action`.
* `sampled_requests_enabled` - (Required) A boolean indicating whether AWS WAF should store a sampling of the web requests that match the rules. You can view the sampled requests through the AWS WAF console.

### Captcha Configuration

The `captcha_config` block supports the following arguments:

* `immunity_time_property` - (Optional) Defines custom immunity time. See [Immunity Time Property](#immunity-time-property) below for details.

### Immunity Time Property

The `immunity_time_property` block supports the following arguments:

* `immunity_time` - (Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:
Expand Down
13 changes: 13 additions & 0 deletions website/docs/r/wafv2_web_acl.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ The `default_action` block supports the following arguments:
Each `rule` supports the following arguments:

* `action` - (Optional) Action that AWS WAF should take on a web request when it matches the rule's statement. This is used only for rules whose **statements do not reference a rule group**. See [`action`](#action) below for details.
* `captcha_config` - (Optional) Specifies how AWS WAF should handle CAPTCHA evaluations. See [Captcha Configuration](#captcha-configuration) below for details.
* `name` - (Required) Friendly name of the rule. **NOTE:** The provider assumes that rules with names matching this pattern, `^ShieldMitigationRuleGroup_<account-id>_<web-acl-guid>_.*`, are AWS-added for [automatic application layer DDoS mitigation activities](https://docs.aws.amazon.com/waf/latest/developerguide/ddos-automatic-app-layer-response-rg.html). Such rules will be ignored by the provider unless you explicitly include them in your configuration (for example, by using the AWS CLI to discover their properties and creating matching configuration). However, since these rules are owned and managed by AWS, you may get permission errors.
* `override_action` - (Optional) Override action to apply to the rules in a rule group. Used only for rule **statements that reference a rule group**, like `rule_group_reference_statement` and `managed_rule_group_statement`. See [`override_action`](#override_action) below for details.
* `priority` - (Required) If you define more than one Rule in a WebACL, AWS WAF evaluates each request against the `rules` in order based on the value of `priority`. AWS WAF processes rules with lower priority first.
Expand Down Expand Up @@ -835,6 +836,18 @@ The `visibility_config` block supports the following arguments:
* `metric_name` - (Required) A friendly name of the CloudWatch metric. The name can contain only alphanumeric characters (A-Z, a-z, 0-9) hyphen(-) and underscore (\_), with length from one to 128 characters. It can't contain whitespace or metric names reserved for AWS WAF, for example `All` and `Default_Action`.
* `sampled_requests_enabled` - (Required) Whether AWS WAF should store a sampling of the web requests that match the rules. You can view the sampled requests through the AWS WAF console.

### Captcha Configuration

The `captcha_config` block supports the following arguments:

* `immunity_time_property` - (Optional) Defines custom immunity time. See [Immunity Time Property](#immunity-time-property) below for details.

### Immunity Time Property

The `immunity_time_property` block supports the following arguments:

* `immunity_time` - (Optional) The amount of time, in seconds, that a CAPTCHA or challenge timestamp is considered valid by AWS WAF. The default setting is 300.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:
Expand Down

0 comments on commit 5149834

Please sign in to comment.