Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add captcha config to wafv2 #29608

Merged
merged 13 commits into from
Apr 20, 2023
4 changes: 4 additions & 0 deletions .changelog/29608.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:enhancement
resource/aws_wafv2_rule_group: Add `captcha_config` argument
resource/aws_wafv2_web_acl: Add `captcha_config` argument
```
47 changes: 47 additions & 0 deletions internal/service/wafv2/flex.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func expandRule(m map[string]interface{}) *wafv2.Rule {
Action: expandRuleAction(m["action"].([]interface{})),
Statement: expandRuleGroupRootStatement(m["statement"].([]interface{})),
VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})),
CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})),
}

if v, ok := m["rule_label"].(*schema.Set); ok && v.Len() > 0 {
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 @@ -838,6 +865,7 @@ func expandWebACLRule(m map[string]interface{}) *wafv2.Rule {
OverrideAction: expandOverrideAction(m["override_action"].([]interface{})),
Statement: expandWebACLRootStatement(m["statement"].([]interface{})),
VisibilityConfig: expandVisibilityConfig(m["visibility_config"].([]interface{})),
CaptchaConfig: expandCaptchaConfig(m["captcha_config"].([]interface{})),
}

if v, ok := m["rule_label"].(*schema.Set); ok && v.Len() > 0 {
Expand Down Expand Up @@ -1116,6 +1144,7 @@ func flattenRules(r []*wafv2.Rule) interface{} {
m["rule_label"] = flattenRuleLabels(rule.RuleLabels)
m["statement"] = flattenRuleGroupRootStatement(rule.Statement)
m["visibility_config"] = flattenVisibilityConfig(rule.VisibilityConfig)
m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig)
out[i] = m
}

Expand Down Expand Up @@ -1193,6 +1222,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 @@ -1856,6 +1902,7 @@ func flattenWebACLRules(r []*wafv2.Rule) interface{} {
m["rule_label"] = flattenRuleLabels(rule.RuleLabels)
m["statement"] = flattenWebACLRootStatement(rule.Statement)
m["visibility_config"] = flattenVisibilityConfig(rule.VisibilityConfig)
m["captcha_config"] = flattenCaptchaConfig(rule.CaptchaConfig)
out[i] = m
}

Expand Down
2 changes: 2 additions & 0 deletions internal/service/wafv2/rule_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ func ResourceRuleGroup() *schema.Resource {
"rule_label": ruleLabelsSchema(),
"statement": ruleGroupRootStatementSchema(ruleGroupRootStatementSchemaLevel),
"visibility_config": visibilityConfigSchema(),
"captcha_config": outerCaptchaConfigSchema(),
},
},
},
Expand All @@ -122,6 +123,7 @@ func ResourceRuleGroup() *schema.Resource {
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
"visibility_config": visibilityConfigSchema(),
"captcha_config": outerCaptchaConfigSchema(),
},

CustomizeDiff: verify.SetTagsDiff,
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 @@ -131,6 +131,7 @@ func ResourceWebACL() *schema.Resource {
"rule_label": ruleLabelsSchema(),
"statement": webACLRootStatementSchema(webACLRootStatementSchemaLevel),
"visibility_config": visibilityConfigSchema(),
"captcha_config": outerCaptchaConfigSchema(),
},
},
},
Expand All @@ -143,6 +144,7 @@ func ResourceWebACL() *schema.Resource {
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
"visibility_config": visibilityConfigSchema(),
"captcha_config": outerCaptchaConfigSchema(),
},

CustomizeDiff: verify.SetTagsDiff,
Expand All @@ -161,6 +163,7 @@ func resourceWebACLCreate(ctx context.Context, d *schema.ResourceData, meta inte
Rules: expandWebACLRules(d.Get("rule").(*schema.Set).List()),
Scope: aws.String(d.Get("scope").(string)),
VisibilityConfig: expandVisibilityConfig(d.Get("visibility_config").([]interface{})),
CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})),
}

if v, ok := d.GetOk("custom_response_body"); ok && v.(*schema.Set).Len() > 0 {
Expand Down Expand Up @@ -227,6 +230,9 @@ func resourceWebACLRead(ctx context.Context, d *schema.ResourceData, meta interf
if err := d.Set("visibility_config", flattenVisibilityConfig(webACL.VisibilityConfig)); err != nil {
return diag.Errorf("setting visibility_config: %s", err)
}
if err := d.Set("captcha_config", flattenCaptchaConfig(webACL.CaptchaConfig)); err != nil {
return diag.Errorf("setting captcha_config: %s", err)
}

tags, err := ListTagsWithContext(ctx, conn, arn)

Expand Down Expand Up @@ -260,6 +266,7 @@ func resourceWebACLUpdate(ctx context.Context, d *schema.ResourceData, meta inte
Rules: expandWebACLRules(d.Get("rule").(*schema.Set).List()),
Scope: aws.String(d.Get("scope").(string)),
VisibilityConfig: expandVisibilityConfig(d.Get("visibility_config").([]interface{})),
CaptchaConfig: expandCaptchaConfig(d.Get("captcha_config").([]interface{})),
}

if v, ok := d.GetOk("custom_response_body"); ok && v.(*schema.Set).Len() > 0 {
Expand Down
16 changes: 16 additions & 0 deletions internal/service/wafv2/web_acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1543,11 +1543,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 @@ -2401,6 +2405,12 @@ resource "aws_wafv2_web_acl" "test" {
cloudwatch_metrics_enabled = false
metric_name = "friendly-rule-metric-name"
sampled_requests_enabled = false
}

captcha_config {
immunity_time_property {
immunity_time = 240
}
}
}

Expand All @@ -2409,6 +2419,12 @@ resource "aws_wafv2_web_acl" "test" {
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 @@ -654,6 +666,19 @@ 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