Skip to content

Commit

Permalink
Merge pull request #692 from okta/app_settings
Browse files Browse the repository at this point in the history
Added new `okta_app_saml_app_settings` resource
  • Loading branch information
monde authored Oct 7, 2021
2 parents e2606f0 + 5053bcc commit ec8eddc
Show file tree
Hide file tree
Showing 22 changed files with 304 additions and 27 deletions.
5 changes: 5 additions & 0 deletions examples/okta_app_saml_app_settings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# okta_app_saml_app_settings

This resource represents App Settings of an Okta SAML Application. For more information see the [API docs](https://developer.okta.com/docs/api/resources/apps#add-custom-saml-application)

- Example [can be found here](./preconfigured.tf)
21 changes: 21 additions & 0 deletions examples/okta_app_saml_app_settings/preconfigured.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "okta_app_saml" "test" {
preconfigured_app = "amazon_aws"
label = "testAcc_replace_with_uuid"
status = "ACTIVE"
}

resource "okta_app_saml_app_settings" "test" {
app_id = okta_app_saml.test.id
settings = jsonencode(
{
"appFilter" : "okta",
"awsEnvironmentType" : "aws.amazon",
"groupFilter" : "aws_(?{{accountid}}\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\-_]+)",
"joinAllRoles" : false,
"loginURL" : "https://console.aws.amazon.com/ec2/home",
"roleValuePattern" : "arn:aws:iam::$${accountid}:saml-provider/OKTA,arn:aws:iam::$${accountid}:role/$${role}",
"sessionDuration" : 7600,
"useGroupMapping" : false
}
)
}
21 changes: 21 additions & 0 deletions examples/okta_app_saml_app_settings/preconfigured_updated.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "okta_app_saml" "test" {
preconfigured_app = "amazon_aws"
label = "testAcc_replace_with_uuid"
status = "ACTIVE"
}

resource "okta_app_saml_app_settings" "test" {
app_id = okta_app_saml.test.id
settings = jsonencode(
{
"appFilter" : "okta",
"awsEnvironmentType" : "aws.amazon",
"groupFilter" : "aws_(?{{accountid}}\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\-_]+)",
"joinAllRoles" : false,
"loginURL" : "https://console.aws.amazon.com/ec2/home",
"roleValuePattern" : "arn:aws:iam::$${accountid}:saml-provider/OKTA,arn:aws:iam::$${accountid}:role/$${role}",
"sessionDuration" : 3200,
"useGroupMapping" : false
}
)
}
2 changes: 1 addition & 1 deletion okta/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ func buildAppSettings(d *schema.ResourceData) *okta.ApplicationSettingsApplicati
if appSettings, ok := d.GetOk("app_settings_json"); ok {
payload := map[string]interface{}{}
_ = json.Unmarshal([]byte(appSettings.(string)), &payload)
settings = okta.ApplicationSettingsApplication(payload)
settings = payload
}
return &settings
}
Expand Down
2 changes: 2 additions & 0 deletions okta/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
appOAuthAPIScope = "okta_app_oauth_api_scope"
appOAuthRedirectURI = "okta_app_oauth_redirect_uri"
appSaml = "okta_app_saml"
appSamlAppSettings = "okta_app_saml_app_settings"
appSecurePasswordStore = "okta_app_secure_password_store"
appSwa = "okta_app_swa"
appSharedCredentials = "okta_app_shared_credentials"
Expand Down Expand Up @@ -199,6 +200,7 @@ func Provider() *schema.Provider {
appOAuthAPIScope: resourceAppOAuthAPIScope(),
appOAuthRedirectURI: resourceAppOAuthRedirectURI(),
appSaml: resourceAppSaml(),
appSamlAppSettings: resourceAppSamlAppSettings(),
appSecurePasswordStore: resourceAppSecurePasswordStore(),
appSwa: resourceAppSwa(),
appSharedCredentials: resourceAppSharedCredentials(),
Expand Down
1 change: 1 addition & 0 deletions okta/provider_sweeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func TestMain(m *testing.M) {
setupSweeper(networkZone, sweepNetworkZones)
setupSweeper(inlineHook, sweepInlineHooks)
setupSweeper(userType, sweepUserTypes)
setupSweeper(behavior, sweepBehaviors)

// add zones sweeper
resource.TestMain(m)
Expand Down
105 changes: 105 additions & 0 deletions okta/resource_okta_app_saml_app_settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package okta

import (
"context"
"encoding/json"
"fmt"

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

func resourceAppSamlAppSettings() *schema.Resource {
return &schema.Resource{
CreateContext: resourceAppSamlSettingsCreate,
ReadContext: resourceAppSamlSettingsRead,
UpdateContext: resourceAppSamlSettingsUpdate,
DeleteContext: resourceAppSamlSettingsDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"app_id": {
Type: schema.TypeString,
Required: true,
Description: "Application ID",
ForceNew: true,
},
"settings": {
Type: schema.TypeString,
Required: true,
Description: "Application settings in JSON format",
ValidateDiagFunc: stringIsJSON,
StateFunc: normalizeDataJSON,
},
},
}
}

func resourceAppSamlSettingsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
id, err := updateOrCreateAppSettings(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
d.SetId(id)
return resourceAppSamlSettingsRead(ctx, d, m)
}

func resourceAppSamlSettingsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
app := okta.NewSamlApplication()
err := fetchApp(ctx, d, m, app)
if err != nil {
return diag.Errorf("failed to get SAML application: %v", err)
}
if app.Id == "" {
d.SetId("")
return nil
}
flatMap := map[string]interface{}{}
for key, val := range *app.Settings.App {
if str, ok := val.(string); ok {
if str != "" {
flatMap[key] = str
}
} else if val != nil {
flatMap[key] = val
}
}
payload, _ := json.Marshal(flatMap)
_ = d.Set("settings", string(payload))
_ = d.Set("app_id", app.Id)
return nil
}

func resourceAppSamlSettingsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
_, err := updateOrCreateAppSettings(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
return resourceAppSamlSettingsRead(ctx, d, m)
}

func updateOrCreateAppSettings(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
app := okta.NewSamlApplication()
appID := d.Get("app_id").(string)
err := fetchAppByID(ctx, appID, m, app)
if err != nil {
return "", fmt.Errorf("failed to get SAML application: %v", err)
}
if app.Id == "" {
return "", fmt.Errorf("application with id %s does not exist", appID)
}
settings := make(okta.ApplicationSettingsApplication)
_ = json.Unmarshal([]byte(d.Get("settings").(string)), &settings)
app.Settings.App = &settings
_, _, err = getOktaClientFromMetadata(m).Application.UpdateApplication(ctx, appID, app)
if err != nil {
return "", fmt.Errorf("failed to update SAML application's settings: %v", err)
}
return app.Id, nil
}

func resourceAppSamlSettingsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
return nil
}
73 changes: 73 additions & 0 deletions okta/resource_okta_app_saml_app_settings_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package okta

import (
"context"
"encoding/json"
"fmt"
"reflect"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/okta/okta-sdk-golang/v2/okta"
)

func TestAccAppSamlAppSettings_crud(t *testing.T) {
ri := acctest.RandInt()
mgr := newFixtureManager(appSamlAppSettings)
preconfigured := mgr.GetFixtures("preconfigured.tf", ri, t)
updated := mgr.GetFixtures("preconfigured_updated.tf", ri, t)
resourceName := fmt.Sprintf("%s.test", appSamlAppSettings)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProvidersFactories,
CheckDestroy: createCheckResourceDestroy(appSaml, createDoesAppExist(okta.NewSamlApplication())),
Steps: []resource.TestStep{
{
Config: preconfigured,
Check: resource.ComposeTestCheckFunc(
checkAppSamlAppSettingsExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "settings", "{\"appFilter\":\"okta\",\"awsEnvironmentType\":\"aws.amazon\",\"groupFilter\":\"aws_(?{{accountid}}\\\\\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\\\\\-_]+)\",\"joinAllRoles\":false,\"loginURL\":\"https://console.aws.amazon.com/ec2/home\",\"roleValuePattern\":\"arn:aws:iam::${accountid}:saml-provider/OKTA,arn:aws:iam::${accountid}:role/${role}\",\"sessionDuration\":7600,\"useGroupMapping\":false}"),
),
},
{
Config: updated,
Check: resource.ComposeTestCheckFunc(
checkAppSamlAppSettingsExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "settings", "{\"appFilter\":\"okta\",\"awsEnvironmentType\":\"aws.amazon\",\"groupFilter\":\"aws_(?{{accountid}}\\\\\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\\\\\-_]+)\",\"joinAllRoles\":false,\"loginURL\":\"https://console.aws.amazon.com/ec2/home\",\"roleValuePattern\":\"arn:aws:iam::${accountid}:saml-provider/OKTA,arn:aws:iam::${accountid}:role/${role}\",\"sessionDuration\":3200,\"useGroupMapping\":false}"),
),
},
},
})
}

func checkAppSamlAppSettingsExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
missingErr := fmt.Errorf("resource not found: %s", name)
rs, ok := s.RootModule().Resources[name]
if !ok {
return missingErr
}
appID := rs.Primary.Attributes["app_id"]
client := getOktaClientFromMetadata(testAccProvider.Meta())
app := okta.NewSamlApplication()
_, _, err := client.Application.GetApplication(context.Background(), appID, app, nil)
if err != nil {
return err
}
settings := make(okta.ApplicationSettingsApplication)
_ = json.Unmarshal([]byte(rs.Primary.Attributes["settings"]), &settings)
for k, v := range *app.Settings.App {
if v == nil {
delete(*app.Settings.App, k)
}
}
e := reflect.DeepEqual(*app.Settings.App, settings)
if !e {
return fmt.Errorf("settings are not equal: actual: %+v , expected: %+v", *app.Settings.App, settings)
}
return nil
}
}
15 changes: 15 additions & 0 deletions okta/resource_okta_behavior_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,23 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/okta/okta-sdk-golang/v2/okta/query"
)

func sweepBehaviors(client *testClient) error {
var errorList []error
behaviors, _, err := client.apiSupplement.ListBehaviors(context.Background(), &query.Params{Q: testResourcePrefix})
if err != nil {
return err
}
for _, b := range behaviors {
if _, err := client.apiSupplement.DeleteBehavior(context.Background(), b.ID); err != nil {
errorList = append(errorList, err)
}
}
return condenseError(errorList)
}

func TestAccOktaBehavior(t *testing.T) {
ri := acctest.RandInt()
mgr := newFixtureManager(behavior)
Expand Down
2 changes: 1 addition & 1 deletion okta/resource_okta_group_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
func sweepGroupRules(client *testClient) error {
var errorList []error
// Should never need to deal with pagination
rules, _, err := client.oktaClient.Group.ListGroupRules(context.Background(), &query.Params{Limit: 300})
rules, _, err := client.oktaClient.Group.ListGroupRules(context.Background(), &query.Params{Limit: defaultPaginationLimit})
if err != nil {
return err
}
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_auto_login.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_auto_login

Creates an Auto Login Okta Application.

This resource allows you to create and configure an Auto Login Okta Application.

## Example Usage
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_basic_auth.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_basic_auth

Creates a Basic Auth Application.

This resource allows you to create and configure a Basic Auth Application.

## Example Usage
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_bookmark.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_bookmark

Creates a Bookmark Application.

This resource allows you to create and configure a Bookmark Application.

## Example Usage
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_oauth.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_oauth

Creates an OIDC Application.

This resource allows you to create and configure an OIDC Application.

## Example Usage
Expand Down
6 changes: 2 additions & 4 deletions website/docs/r/app_saml.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ layout: 'okta'
page_title: 'Okta: okta_app_saml'
sidebar_current: 'docs-okta-resource-app-saml'
description: |-
Creates an SAML Application.
Creates a SAML Application.
---

# okta_app_saml

Creates an SAML Application.

This resource allows you to create and configure an SAML Application.
This resource allows you to create and configure a SAML Application.

## Example Usage

Expand Down
Loading

0 comments on commit ec8eddc

Please sign in to comment.