Skip to content

Commit

Permalink
Merge pull request #2204 from okta/issue_2173_okta_app_saml_acs_endpo…
Browse files Browse the repository at this point in the history
…ints

Resource `okta_app_saml`'s `acs_endpoints` is a list
  • Loading branch information
monde authored Feb 3, 2025
2 parents 931caaa + 95c1a4b commit 47800db
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 4 deletions.
2 changes: 1 addition & 1 deletion okta/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ func setSamlSettings(d *schema.ResourceData, signOn *sdk.SamlApplicationSettings
for i := range acsEndpointsObj {
acsEndpoints[i] = acsEndpointsObj[i].Url
}
_ = d.Set("acs_endpoints", convertStringSliceToSetNullable(acsEndpoints))
_ = d.Set("acs_endpoints", acsEndpoints)
}
} else {
_ = d.Set("acs_endpoints", nil)
Expand Down
15 changes: 12 additions & 3 deletions okta/resource_okta_app_saml.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ request feature flag 'ADVANCED_SSO' be applied to your org.`,
Description: "Saml Inline Hook setting",
},
"acs_endpoints": {
Type: schema.TypeSet,
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Description: "An array of ACS endpoints. You can configure a maximum of 100 endpoints.",
Expand Down Expand Up @@ -521,6 +521,15 @@ func resourceAppSamlRead(ctx context.Context, d *schema.ResourceData, m interfac
return diag.Errorf("failed to set Application Credential Key Values: %v", err)
}

// acsEndpoints
if app.Settings.SignOn != nil && len(app.Settings.SignOn.AcsEndpoints) > 0 {
acsEndponts := make([]string, len(app.Settings.SignOn.AcsEndpoints))
for _, ae := range app.Settings.SignOn.AcsEndpoints {
acsEndponts[ae.Index] = ae.Url
}
_ = d.Set("acs_endpoints", acsEndponts)
}

appRead(d, app.Name, app.Status, app.SignOnMode, app.Label, app.Accessibility, app.Visibility, app.Settings.Notes)
if app.SignOnMode == "SAML_1_1" {
_ = d.Set("saml_version", saml11)
Expand All @@ -547,7 +556,7 @@ func resourceAppSamlUpdate(ctx context.Context, d *schema.ResourceData, m interf
client := getOktaClientFromMetadata(m)
app, err := buildSamlApp(d)
if err != nil {
return diag.Errorf("failed to create SAML application: %v", err)
return diag.Errorf("failed to build SAML application: %v", err)
}
_, _, err = client.Application.UpdateApplication(ctx, d.Id(), app)
if err != nil {
Expand Down Expand Up @@ -657,7 +666,7 @@ func buildSamlApp(d *schema.ResourceData) (*sdk.SamlApplication, error) {
}

// Assumes that sso url is already part of the acs endpoints as part of the desired state.
acsEndpoints := convertInterfaceToStringSet(d.Get("acs_endpoints"))
acsEndpoints := convertInterfaceToStringArr(d.Get("acs_endpoints"))

// If there are acs endpoints, implies this flag should be true.
allowMultipleAcsEndpoints := false
Expand Down
66 changes: 66 additions & 0 deletions okta/resource_okta_app_saml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,3 +484,69 @@ resource "okta_app_saml" "test" {
},
})
}

func TestAccResourceOktaAppSaml_Issue2171AcsEndpoints(t *testing.T) {
mgr := newFixtureManager("resources", appSaml, t.Name())
resourceName := fmt.Sprintf("%s.test", appSaml)
config := `
resource "okta_app_saml" "test" {
acs_endpoints = [%s]
label = "testAcc_replace_with_uuid"
sso_url = "http://google.com"
recipient = "http://here.com"
destination = "http://its-about-the-journey.com"
audience = "http://audience.com"
subject_name_id_template = "$${source.login}"
subject_name_id_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
response_signed = true
assertion_signed = true
signature_algorithm = "RSA_SHA1"
digest_algorithm = "SHA1"
honor_force_authn = true
authn_context_class_ref = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
}
`
acsEndpoints1 := "\"https://example.com\",\"https://okta.com\""
acsEndpoints2 := "\"https://okta.com\",\"https://example.com\""
acsEndpoints3 := "\"https://okta.com\",\"https://middle.example.com\",\"https://example.com\""

oktaResourceTest(t, resource.TestCase{
PreCheck: testAccPreCheck(t),
ErrorCheck: testAccErrorChecks(t),
ProviderFactories: testAccProvidersFactories,
CheckDestroy: checkResourceDestroy(appSaml, createDoesAppExist(sdk.NewSamlApplication())),
Steps: []resource.TestStep{
{
Config: mgr.ConfigReplace(fmt.Sprintf(config, acsEndpoints1)),
Check: resource.ComposeTestCheckFunc(
ensureResourceExists(resourceName, createDoesAppExist(sdk.NewSamlApplication())),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.#", "2"),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.0", "https://example.com"),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.1", "https://okta.com"),
),
},
{
// demonstrate flipping order is respected
Config: mgr.ConfigReplace(fmt.Sprintf(config, acsEndpoints2)),
Check: resource.ComposeTestCheckFunc(
ensureResourceExists(resourceName, createDoesAppExist(sdk.NewSamlApplication())),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.#", "2"),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.0", "https://okta.com"),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.1", "https://example.com"),
),
},
{
// demonstrate inserting and order is respected
Config: mgr.ConfigReplace(fmt.Sprintf(config, acsEndpoints3)),
Check: resource.ComposeTestCheckFunc(
ensureResourceExists(resourceName, createDoesAppExist(sdk.NewSamlApplication())),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.#", "3"),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.0", "https://okta.com"),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.1", "https://middle.example.com"),
resource.TestCheckResourceAttr(resourceName, "acs_endpoints.2", "https://example.com"),
),
},
},
})
}

0 comments on commit 47800db

Please sign in to comment.