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

[DXCDT-77] Fix attack protection resource for psaas tenants #86

Merged
merged 1 commit into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 117 additions & 98 deletions auth0/resource_auth0_attack_protection.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package auth0

import (
"fmt"
"net/http"

"github.com/auth0/go-auth0/management"
Expand Down Expand Up @@ -208,6 +207,11 @@ func newAttackProtection() *schema.Resource {
}
}

func createAttackProtection(d *schema.ResourceData, m interface{}) error {
d.SetId(resource.UniqueId())
return updateAttackProtection(d, m)
}

func readAttackProtection(d *schema.ResourceData, m interface{}) error {
api := m.(*management.Management)

Expand Down Expand Up @@ -259,24 +263,61 @@ func readAttackProtection(d *schema.ResourceData, m interface{}) error {
return nil
}

func updateAttackProtection(d *schema.ResourceData, m interface{}) error {
api := m.(*management.Management)

if ipt := expandSuspiciousIPThrottling(d); ipt != nil {
if err := api.AttackProtection.UpdateSuspiciousIPThrottling(ipt); err != nil {
return err
}
}

if bfp := expandBruteForceProtection(d); bfp != nil {
if err := api.AttackProtection.UpdateBruteForceProtection(bfp); err != nil {
return err
}
}

if bpd := expandBreachedPasswordDetection(d); bpd != nil {
if err := api.AttackProtection.UpdateBreachedPasswordDetection(bpd); err != nil {
return err
}
}

return readAttackProtection(d, m)
}

func deleteAttackProtection(d *schema.ResourceData, m interface{}) error {
d.SetId("")
return nil
}

sergiught marked this conversation as resolved.
Show resolved Hide resolved
func flattenSuspiciousIPThrottling(ipt *management.SuspiciousIPThrottling) []interface{} {
m := make(map[string]interface{})
if ipt != nil {
m["enabled"] = ipt.Enabled
m["allowlist"] = ipt.AllowList
m["shields"] = ipt.Shields
m["pre_login"] = []interface{}{
map[string]int{
"max_attempts": ipt.Stage.PreLogin.GetMaxAttempts(),
"rate": ipt.Stage.PreLogin.GetRate(),
},
}
m["pre_user_registration"] = []interface{}{
map[string]int{
"max_attempts": ipt.Stage.PreUserRegistration.GetMaxAttempts(),
"rate": ipt.Stage.PreUserRegistration.GetRate(),
},

if ipt.Stage != nil {
if ipt.Stage.PreLogin != nil {
m["pre_login"] = []interface{}{
map[string]int{
"max_attempts": ipt.Stage.PreLogin.GetMaxAttempts(),
"rate": ipt.Stage.PreLogin.GetRate(),
},
}
}
if ipt.Stage.PreUserRegistration != nil {
m["pre_user_registration"] = []interface{}{
map[string]int{
"max_attempts": ipt.Stage.PreUserRegistration.GetMaxAttempts(),
"rate": ipt.Stage.PreUserRegistration.GetRate(),
},
}
}
sergiught marked this conversation as resolved.
Show resolved Hide resolved
}

}
return []interface{}{m}
}
Expand Down Expand Up @@ -304,125 +345,103 @@ func flattenBreachedPasswordProtection(bpd *management.BreachedPasswordDetection
return []interface{}{m}
}

func updateAttackProtection(d *schema.ResourceData, m interface{}) error {
api := m.(*management.Management)

ipt := expandSuspiciousIPThrottling(d)
err := api.AttackProtection.UpdateSuspiciousIPThrottling(ipt)
if err != nil {
return err
}

bfp := expandBruteForceProtection(d)
err = api.AttackProtection.UpdateBruteForceProtection(bfp)
if err != nil {
return err
}

bpd := expandBreachedPasswordDetection(d)
err = api.AttackProtection.UpdateBreachedPasswordDetection(bpd)
if err != nil {
return err
}

return readAttackProtection(d, m)
}

func expandSuspiciousIPThrottling(d *schema.ResourceData) *management.SuspiciousIPThrottling {
ipt := &management.SuspiciousIPThrottling{}
var ipt management.SuspiciousIPThrottling

List(d, "suspicious_ip_throttling", IsNewResource(), HasChange()).Elem(func(d ResourceData) {
shields := []string{}
for _, s := range d.Get("shields").([]interface{}) {
shields = append(shields, fmt.Sprintf("%s", s))
}
ipt.Enabled = Bool(d, "enabled")

allowlist := []string{}
for _, a := range d.Get("allowlist").([]interface{}) {
allowlist = append(allowlist, fmt.Sprintf("%s", a))
stateShields := d.Get("shields").([]interface{})
shields := make([]string, len(stateShields))
for index, value := range stateShields {
shields[index] = value.(string)
}
ipt.Shields = &shields

ipt = &management.SuspiciousIPThrottling{
Enabled: Bool(d, "enabled"),
Shields: &shields,
AllowList: &allowlist,
Stage: &management.Stage{
PreLogin: &management.PreLogin{},
PreUserRegistration: &management.PreUserRegistration{},
},
stateAllowList := d.Get("allowlist").([]interface{})
allowlist := make([]string, len(stateAllowList))
for index, value := range stateAllowList {
allowlist[index] = value.(string)
}
ipt.AllowList = &allowlist

List(d, "pre_login").Elem(func(d ResourceData) {
ipt.Stage.PreLogin.MaxAttempts = Int(d, "max_attempts")
ipt.Stage.PreLogin.Rate = Int(d, "rate")
List(d, "pre_login", IsNewResource(), HasChange()).Elem(func(d ResourceData) {
ipt.Stage = &management.Stage{
PreLogin: &management.PreLogin{
MaxAttempts: Int(d, "max_attempts"),
Rate: Int(d, "rate"),
},
}
})

List(d, "pre_user_registration").Elem(func(d ResourceData) {
ipt.Stage.PreUserRegistration.MaxAttempts = Int(d, "max_attempts")
ipt.Stage.PreUserRegistration.Rate = Int(d, "rate")
List(d, "pre_user_registration", IsNewResource(), HasChange()).Elem(func(d ResourceData) {
preUserRegistration := &management.PreUserRegistration{
MaxAttempts: Int(d, "max_attempts"),
Rate: Int(d, "rate"),
}

if ipt.Stage != nil {
ipt.Stage.PreUserRegistration = preUserRegistration
} else {
ipt.Stage = &management.Stage{
PreUserRegistration: preUserRegistration,
}
}
})
})

return ipt
return &ipt
}

func expandBruteForceProtection(d *schema.ResourceData) *management.BruteForceProtection {
bfp := &management.BruteForceProtection{}
var bfp management.BruteForceProtection

List(d, "brute_force_protection", IsNewResource(), HasChange()).Elem(func(d ResourceData) {
shields := []string{}
for _, s := range d.Get("shields").([]interface{}) {
shields = append(shields, fmt.Sprintf("%s", s))
}
bfp.Enabled = Bool(d, "enabled")

allowlist := []string{}
for _, a := range d.Get("allowlist").([]interface{}) {
allowlist = append(allowlist, fmt.Sprintf("%s", a))
stateShields := d.Get("shields").([]interface{})
shields := make([]string, len(stateShields))
for index, value := range stateShields {
shields[index] = value.(string)
}
bfp.Shields = &shields

bfp = &management.BruteForceProtection{
Enabled: Bool(d, "enabled"),
Shields: &shields,
AllowList: &allowlist,
Mode: String(d, "mode"),
MaxAttempts: Int(d, "max_attempts"),
stateAllowList := d.Get("allowlist").([]interface{})
allowlist := make([]string, len(stateAllowList))
for index, value := range stateAllowList {
allowlist[index] = value.(string)
}
bfp.AllowList = &allowlist

bfp.Mode = String(d, "mode")
bfp.MaxAttempts = Int(d, "max_attempts")
})

return bfp
return &bfp
}

func expandBreachedPasswordDetection(d *schema.ResourceData) *management.BreachedPasswordDetection {
bpd := &management.BreachedPasswordDetection{}
var bpd management.BreachedPasswordDetection

List(d, "breached_password_detection", IsNewResource(), HasChange()).Elem(func(d ResourceData) {
shields := []string{}
for _, s := range d.Get("shields").([]interface{}) {
shields = append(shields, fmt.Sprintf("%s", s))
}
bpd.Enabled = Bool(d, "enabled")

notificationFreq := []string{}
for _, a := range d.Get("admin_notification_frequency").([]interface{}) {
notificationFreq = append(notificationFreq, fmt.Sprintf("%s", a))
stateShields := d.Get("shields").([]interface{})
shields := make([]string, len(stateShields))
for index, value := range stateShields {
shields[index] = value.(string)
}
bpd.Shields = &shields

bpd = &management.BreachedPasswordDetection{
Enabled: Bool(d, "enabled"),
Shields: &shields,
Method: String(d, "method"),
AdminNotificationFrequency: &notificationFreq,
stateAdminNotificationFrequency := d.Get("admin_notification_frequency").([]interface{})
adminNotificationFrequency := make([]string, len(stateAdminNotificationFrequency))
for index, value := range stateAdminNotificationFrequency {
adminNotificationFrequency[index] = value.(string)
}
})

return bpd
}
bpd.AdminNotificationFrequency = &adminNotificationFrequency

func createAttackProtection(d *schema.ResourceData, m interface{}) error {
d.SetId(resource.UniqueId())
return updateAttackProtection(d, m)
}
bpd.Method = String(d, "method")
})

func deleteAttackProtection(d *schema.ResourceData, m interface{}) error {
d.SetId("")
return nil
return &bpd
}
1 change: 0 additions & 1 deletion auth0/resource_auth0_attack_protection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
)

func TestAccAttackProtection(t *testing.T) {

resource.Test(t, resource.TestCase{
Providers: map[string]terraform.ResourceProvider{
"auth0": Provider(),
Expand Down
8 changes: 4 additions & 4 deletions docs/resources/attack_protection.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ The following arguments are supported for `brute_force_protection`:
* `shields` - (Optional) Action to take when a brute force protection threshold is violated. Possible values: `block`, `user_notification`.
* `allowlist` - (Optional) List of trusted IP addresses that will not have attack protection enforced against them.
* `mode` - (Optional) Determines whether or not IP address is used when counting failed attempts. Possible values: `count_per_identifier_and_ip` or `count_per_identifier`.
* `max_attempts` - (Optional) Maximum number of unsuccessful attempts.
* `max_attempts` - (Optional) Maximum number of unsuccessful attempts. Only available on public tenants.

### suspicious_ip_throttling

Expand All @@ -67,8 +67,8 @@ The following arguments are supported for `suspicious_ip_throttling`:
* `enabled` - (Optional) Whether or not suspicious IP throttling attack protections are active.
* `shields` - (Optional) Action to take when a suspicious IP throttling threshold is violated. Possible values: `block`, `admin_notification`.
* `allowlist` - (Optional) List of trusted IP addresses that will not have attack protection enforced against them.
* `pre_login` - (Optional) Configuration options that apply before every login attempt.
* `pre_user_registration` - (Optional) Configuration options that apply before every user registration attempt.
* `pre_login` - (Optional) Configuration options that apply before every login attempt. Only available on public tenants.
* `pre_user_registration` - (Optional) Configuration options that apply before every user registration attempt. Only available on public tenants.

### breached_password_protection

Expand All @@ -85,4 +85,4 @@ string. We recommend [Version 4 UUID](https://www.uuidgenerator.net/version4) e.

```shell
$ terraform import auth0_guardian.default 24940d4b-4bd4-44e7-894e-f92e4de36a40
```
```
6 changes: 5 additions & 1 deletion docs/resources/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ resource "auth0_client" "my_client" {
app_bundle_identifier = "com.my.bundle.id"
}
}
client_secret_rotation_trigger = {
triggered_at = "2018-01-02T23:12:01Z"
triggered_by = "auth0"
}
}
```

Expand All @@ -89,7 +93,7 @@ Arguments accepted by this resource include:

* `name` - (Required) String. Name of the client.
* `description` - (Optional) String, (Max length = 140 characters). Description of the purpose of the client.
* `client_secret_rotation_trigger` - (Optional) Map.
* `client_secret_rotation_trigger` - (Optional) Map. Custom metadata for the rotation. For more info: [rotate-client-secret](https://auth0.com/docs/get-started/applications/rotate-client-secret).
* `app_type` - (Optional) String. Type of application the client represents. Options include `native`, `spa`, `regular_web`, `non_interactive`, `rms`, `box`, `cloudbees`, `concur`, `dropbox`, `mscrm`, `echosign`, `egnyte`, `newrelic`, `office365`, `salesforce`, `sentry`, `sharepoint`, `slack`, `springcm`, `zendesk`, `zoom`.
* `logo_uri` - (Optional) String. URL of the logo for the client. Recommended size is 150px x 150px. If none is set, the default badge for the application type will be shown.
* `is_first_party` - (Optional) Boolean. Indicates whether or not this client is a first-party client.
Expand Down