Skip to content

Commit

Permalink
Added new okta_rate_limit resource (#803)
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdanprodan-okta authored Nov 15, 2021
1 parent f8cc07d commit 91fe4a5
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 0 deletions.
5 changes: 5 additions & 0 deletions examples/okta_rate_limit/basic.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "okta_rate_limit" "example" {
login = "ENFORCE"
authorize = "ENFORCE"
communications_enabled = true
}
2 changes: 2 additions & 0 deletions okta/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const (
policyRuleSignOn = "okta_policy_rule_signon"
policySignOn = "okta_policy_signon"
profileMapping = "okta_profile_mapping"
rateLimiting = "okta_rate_limiting"
resourceSet = "okta_resource_set"
roleSubscription = "okta_role_subscription"
securityNotificationEmails = "okta_security_notification_emails"
Expand Down Expand Up @@ -288,6 +289,7 @@ func Provider() *schema.Provider {
policyRuleSignOn: resourcePolicySignOnRule(),
policySignOn: resourcePolicySignOn(),
profileMapping: resourceProfileMapping(),
rateLimiting: resourceRateLimiting(),
resourceSet: resourceResourceSet(),
roleSubscription: resourceRoleSubscription(),
securityNotificationEmails: resourceSecurityNotificationEmails(),
Expand Down
101 changes: 101 additions & 0 deletions okta/resource_okta_rate_limiting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package okta

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/okta/terraform-provider-okta/sdk"
)

func resourceRateLimiting() *schema.Resource {
return &schema.Resource{
CreateContext: resourceRateLimitingCreate,
ReadContext: resourceRateLimitingRead,
UpdateContext: resourceRateLimitingUpdate,
DeleteContext: resourceRateLimitingDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"login": {
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: elemInSlice([]string{"ENFORCE", "DISABLE", "PREVIEW"}),
Description: "Called when accessing the Okta hosted login page.",
},
"authorize": {
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: elemInSlice([]string{"ENFORCE", "DISABLE", "PREVIEW"}),
Description: "Called during authentication.",
},
"communications_enabled": {
Type: schema.TypeBool,
Optional: true,
Description: "Enables rate limit warning, violation, notification emails and banners when this org meets rate limits.",
Default: true,
},
},
}
}

func resourceRateLimitingCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
_, _, err := getSupplementFromMetadata(m).SetClientBasedRateLimiting(ctx, buildRateLimiter(d))
if err != nil {
return diag.Errorf("failed to set client-based rate limiting: %v", err)
}
_, _, err = getSupplementFromMetadata(m).SetRateLimitingCommunications(ctx, buildRateLimitingCommunications(d))
if err != nil {
return diag.Errorf("failed to set rate limiting communications: %v", err)
}
d.SetId("rate_limiting")
return nil
}

func resourceRateLimitingRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
rl, _, err := getSupplementFromMetadata(m).GetClientBasedRateLimiting(ctx)
if err != nil {
return diag.Errorf("failed to get client-based rate limiting: %v", err)
}
_ = d.Set("login", rl.GranularModeSettings.LoginPage)
_ = d.Set("authorize", rl.GranularModeSettings.OAuth2Authorize)
comm, _, err := getSupplementFromMetadata(m).GetRateLimitingCommunications(ctx)
if err != nil {
return diag.Errorf("failed to get rate limiting communications: %v", err)
}
_ = d.Set("communications_enabled", *comm.RateLimitNotification)
return nil
}

func resourceRateLimitingUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
_, _, err := getSupplementFromMetadata(m).SetClientBasedRateLimiting(ctx, buildRateLimiter(d))
if err != nil {
return diag.Errorf("failed to set client-based rate limiting: %v", err)
}
_, _, err = getSupplementFromMetadata(m).SetRateLimitingCommunications(ctx, buildRateLimitingCommunications(d))
if err != nil {
return diag.Errorf("failed to set rate limiting communications: %v", err)
}
return nil
}

func resourceRateLimitingDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
return nil
}

func buildRateLimiter(d *schema.ResourceData) sdk.ClientRateLimitMode {
return sdk.ClientRateLimitMode{
Mode: "PREVIEW",
GranularModeSettings: &sdk.RateLimitGranularModeSettings{
OAuth2Authorize: d.Get("authorize").(string),
LoginPage: d.Get("login").(string),
},
}
}

func buildRateLimitingCommunications(d *schema.ResourceData) sdk.RateLimitingCommunications {
return sdk.RateLimitingCommunications{
RateLimitNotification: boolPtr(d.Get("communications_enabled").(bool)),
}
}
78 changes: 78 additions & 0 deletions sdk/rate_limit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package sdk

import (
"context"
"net/http"

"github.com/okta/okta-sdk-golang/v2/okta"
)

type ClientRateLimitMode struct {
Mode string `json:"mode"`
GranularModeSettings *RateLimitGranularModeSettings `json:"granularModeSettings"`
}

type RateLimitGranularModeSettings struct {
OAuth2Authorize string `json:"OAUTH2_AUTHORIZE"`
LoginPage string `json:"LOGIN_PAGE"`
}

type RateLimitingCommunications struct {
RateLimitNotification *bool `json:"rateLimitNotification"`
}

func (m *APISupplement) SetClientBasedRateLimiting(ctx context.Context, body ClientRateLimitMode) (*ClientRateLimitMode, *okta.Response, error) {
url := "/api/v1/internal/rateLimits/clientRateLimitMode"
req, err := m.RequestExecutor.WithAccept("application/json").WithContentType("application/json").NewRequest(http.MethodPost, url, body)
if err != nil {
return nil, nil, err
}
var rateLimitMode *ClientRateLimitMode
resp, err := m.RequestExecutor.Do(ctx, req, &rateLimitMode)
if err != nil {
return nil, resp, err
}
return rateLimitMode, resp, nil
}

func (m *APISupplement) GetClientBasedRateLimiting(ctx context.Context) (*ClientRateLimitMode, *okta.Response, error) {
url := "/api/v1/internal/rateLimits/clientRateLimitMode"
req, err := m.RequestExecutor.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, nil, err
}
var rateLimitMode *ClientRateLimitMode
resp, err := m.RequestExecutor.Do(ctx, req, &rateLimitMode)
if err != nil {
return nil, resp, err
}
return rateLimitMode, resp, nil
}

func (m *APISupplement) SetRateLimitingCommunications(ctx context.Context, body RateLimitingCommunications) (*RateLimitingCommunications, *okta.Response, error) {
url := "/api/internal/orgSettings/rateLimitNotificationSetting"
req, err := m.RequestExecutor.WithAccept("application/json").WithContentType("application/json").NewRequest(http.MethodPost, url, body)
if err != nil {
return nil, nil, err
}
var communications *RateLimitingCommunications
resp, err := m.RequestExecutor.Do(ctx, req, &communications)
if err != nil {
return nil, resp, err
}
return communications, resp, nil
}

func (m *APISupplement) GetRateLimitingCommunications(ctx context.Context) (*RateLimitingCommunications, *okta.Response, error) {
url := "/api/internal/orgSettings/rateLimitNotificationSetting"
req, err := m.RequestExecutor.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, nil, err
}
var communications *RateLimitingCommunications
resp, err := m.RequestExecutor.Do(ctx, req, &communications)
if err != nil {
return nil, resp, err
}
return communications, resp, nil
}
41 changes: 41 additions & 0 deletions website/docs/r/rate_limiting.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
layout: 'okta'
page_title: 'Okta: okta_rate_limit'
sidebar_current: 'docs-okta-resource-rate-limit'
description: |-
Manages rate limiting.
---

# okta_rate_limit

This resource allows you to configure the client-based rate limit and rate limiting communications settings.

~> **WARNING:** This resource is available only when using api token in the provider config.

## Example Usage

```hcl
resource "okta_rate_limit" "example" {
login = "ENFORCE"
authorize = "ENFORCE"
communications_enabled = true
}
```

## Argument Reference

- `login` - (Required) Called when accessing the Okta hosted login page. Valid values: `"ENFORCE"` _(Enforce limit and
log per client (recommended))_, `"DISABLE"` _(Do nothing (not recommended))_, `"PREVIEW"` _(Log per client)_.

- `authorize` - (Required) Called during authentication. Valid values: `"ENFORCE"` _(Enforce limit and
log per client (recommended))_, `"DISABLE"` _(Do nothing (not recommended))_, `"PREVIEW"` _(Log per client)_.

- `communications_enabled` - (Optional) Enable or disable rate limiting communications. By default, it is `true`.

## Import

Rate limit settings can be imported without any parameters.

```
$ terraform import okta_rate_limit.example .
```

0 comments on commit 91fe4a5

Please sign in to comment.