Skip to content

Commit

Permalink
Add OIDC backchannel initiators (#1045)
Browse files Browse the repository at this point in the history
* Added support to set the oidc backchannel initiators mode and selected initiators

* Regenerated docs to add new properties

* Changed to use oidc_logout block

* Fixed And Added Test Cases

* Updated Docs

* Updated TestAccDataClients to avoid noisy plan (#1087)

Updated the test to avoid noisy plan

* fix: update messages in Forms using terraform. (#1088)

fix: update error messages in Forms using terraform.

Co-authored-by: Rajat Bajaj <[email protected]>

---------

Co-authored-by: Kunal Dawar <[email protected]>
Co-authored-by: Rajat Bajaj <[email protected]>
Co-authored-by: Kushal <[email protected]>
Co-authored-by: KunalOfficial <[email protected]>
  • Loading branch information
5 people authored Nov 28, 2024
1 parent 720d7a0 commit c9492ab
Show file tree
Hide file tree
Showing 8 changed files with 684 additions and 2 deletions.
19 changes: 19 additions & 0 deletions docs/data-sources/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ data "auth0_client" "some-client-by-id" {
- `native_social_login` (List of Object) Configuration settings to toggle native social login for mobile native applications. Once this is set it must stay set, with both resources set to `false` in order to change the `app_type`. (see [below for nested schema](#nestedatt--native_social_login))
- `oidc_backchannel_logout_urls` (Set of String) Set of URLs that are valid to call back from Auth0 for OIDC backchannel logout. Currently only one URL is allowed.
- `oidc_conformant` (Boolean) Indicates whether this client will conform to strict OIDC specifications.
- `oidc_logout` (List of Object) Configure OIDC logout for the Client (see [below for nested schema](#nestedatt--oidc_logout))
- `organization_require_behavior` (String) Defines how to proceed during an authentication transaction when `organization_usage = "require"`. Can be `no_prompt` (default), `pre_login_prompt` or `post_login_prompt`.
- `organization_usage` (String) Defines how to proceed during an authentication transaction with regards to an organization. Can be `deny` (default), `allow` or `require`.
- `refresh_token` (List of Object) Configuration settings for the refresh tokens issued for this client. (see [below for nested schema](#nestedatt--refresh_token))
Expand Down Expand Up @@ -554,6 +555,24 @@ Read-Only:



<a id="nestedatt--oidc_logout"></a>
### Nested Schema for `oidc_logout`

Read-Only:

- `backchannel_logout_initiators` (List of Object) (see [below for nested schema](#nestedobjatt--oidc_logout--backchannel_logout_initiators))
- `backchannel_logout_urls` (Set of String)

<a id="nestedobjatt--oidc_logout--backchannel_logout_initiators"></a>
### Nested Schema for `oidc_logout.backchannel_logout_initiators`

Read-Only:

- `mode` (String)
- `selected_initiators` (Set of String)



<a id="nestedatt--refresh_token"></a>
### Nested Schema for `refresh_token`

Expand Down
17 changes: 17 additions & 0 deletions docs/data-sources/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ Read-Only:
- `is_first_party` (Boolean)
- `is_token_endpoint_ip_header_trusted` (Boolean)
- `name` (String)
- `oidc_logout` (List of Object) (see [below for nested schema](#nestedobjatt--clients--oidc_logout))
- `web_origins` (List of String)

<a id="nestedobjatt--clients--oidc_logout"></a>
### Nested Schema for `clients.oidc_logout`

Read-Only:

- `backchannel_logout_initiators` (List of Object) (see [below for nested schema](#nestedobjatt--clients--oidc_logout--backchannel_logout_initiators))
- `backchannel_logout_urls` (Set of String)

<a id="nestedobjatt--clients--oidc_logout--backchannel_logout_initiators"></a>
### Nested Schema for `clients.oidc_logout.backchannel_logout_initiators`

Read-Only:

- `mode` (String)
- `selected_initiators` (Set of String)


27 changes: 26 additions & 1 deletion docs/resources/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ resource "auth0_client" "my_client" {
- `logo_uri` (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.
- `mobile` (Block List, Max: 1) Additional configuration for native mobile apps. (see [below for nested schema](#nestedblock--mobile))
- `native_social_login` (Block List, Max: 1) Configuration settings to toggle native social login for mobile native applications. Once this is set it must stay set, with both resources set to `false` in order to change the `app_type`. (see [below for nested schema](#nestedblock--native_social_login))
- `oidc_backchannel_logout_urls` (Set of String) Set of URLs that are valid to call back from Auth0 for OIDC backchannel logout. Currently only one URL is allowed.
- `oidc_backchannel_logout_urls` (Set of String, Deprecated) Set of URLs that are valid to call back from Auth0 for OIDC backchannel logout. Currently only one URL is allowed.
- `oidc_conformant` (Boolean) Indicates whether this client will conform to strict OIDC specifications.
- `oidc_logout` (Block List, Max: 1) Configure OIDC logout for the Client (see [below for nested schema](#nestedblock--oidc_logout))
- `organization_require_behavior` (String) Defines how to proceed during an authentication transaction when `organization_usage = "require"`. Can be `no_prompt` (default), `pre_login_prompt` or `post_login_prompt`.
- `organization_usage` (String) Defines how to proceed during an authentication transaction with regards to an organization. Can be `deny` (default), `allow` or `require`.
- `refresh_token` (Block List, Max: 1) Configuration settings for the refresh tokens issued for this client. (see [below for nested schema](#nestedblock--refresh_token))
Expand Down Expand Up @@ -527,6 +528,30 @@ Optional:



<a id="nestedblock--oidc_logout"></a>
### Nested Schema for `oidc_logout`

Required:

- `backchannel_logout_urls` (Set of String) Set of URLs that are valid to call back from Auth0 for OIDC backchannel logout. Currently only one URL is allowed.

Optional:

- `backchannel_logout_initiators` (Block List, Max: 1) Configure OIDC logout initiators for the Client (see [below for nested schema](#nestedblock--oidc_logout--backchannel_logout_initiators))

<a id="nestedblock--oidc_logout--backchannel_logout_initiators"></a>
### Nested Schema for `oidc_logout.backchannel_logout_initiators`

Required:

- `mode` (String) Determines the configuration method for enabling initiators. `custom` enables only the initiators listed in the backchannel_logout_selected_initiators set, `all` enables all current and future initiators.

Optional:

- `selected_initiators` (Set of String) Contains the list of initiators to be enabled for the given client.



<a id="nestedblock--refresh_token"></a>
### Nested Schema for `refresh_token`

Expand Down
38 changes: 38 additions & 0 deletions internal/auth0/client/expand.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func expandClient(data *schema.ResourceData) (*management.Client, error) {
EncryptionKey: value.MapOfStrings(config.GetAttr("encryption_key")),
IsTokenEndpointIPHeaderTrusted: value.Bool(config.GetAttr("is_token_endpoint_ip_header_trusted")),
OIDCBackchannelLogout: expandOIDCBackchannelLogout(data),
OIDCLogout: expandOIDCLogout(data),
ClientMetadata: expandClientMetadata(data),
RefreshToken: expandClientRefreshToken(data),
JWTConfiguration: expandClientJWTConfiguration(data),
Expand Down Expand Up @@ -149,6 +150,43 @@ func expandOIDCBackchannelLogout(data *schema.ResourceData) *management.OIDCBack
}
}

func expandOIDCLogout(data *schema.ResourceData) *management.OIDCLogout {
oidcLogoutConfig := data.GetRawConfig().GetAttr("oidc_logout")
if oidcLogoutConfig.IsNull() {
return nil
}

var oidcLogout management.OIDCLogout

oidcLogoutConfig.ForEachElement(func(_ cty.Value, config cty.Value) (stop bool) {
oidcLogout.BackChannelLogoutURLs = value.Strings(config.GetAttr("backchannel_logout_urls"))
oidcLogout.BackChannelLogoutInitiators = expandBackChannelLogoutInitiators(config.GetAttr("backchannel_logout_initiators"))
return stop
})

return &oidcLogout
}

func expandBackChannelLogoutInitiators(config cty.Value) *management.BackChannelLogoutInitiators {
if config.IsNull() {
return nil
}

var initiators management.BackChannelLogoutInitiators

config.ForEachElement(func(_ cty.Value, config cty.Value) (stop bool) {
initiators.Mode = value.String(config.GetAttr("mode"))
initiators.SelectedInitiators = value.Strings(config.GetAttr("selected_initiators"))
return stop
})

if initiators == (management.BackChannelLogoutInitiators{}) {
return nil
}

return &initiators
}

func expandClientRefreshToken(data *schema.ResourceData) *management.ClientRefreshToken {
refreshTokenConfig := data.GetRawConfig().GetAttr("refresh_token")
if refreshTokenConfig.IsNull() {
Expand Down
39 changes: 38 additions & 1 deletion internal/auth0/client/flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,42 @@ func flattenClientRefreshTokenConfiguration(refreshToken *management.ClientRefre
}
}

func flattenOIDCBackchannelURLs(backchannelLogout *management.OIDCBackchannelLogout, logout *management.OIDCLogout) []string {
if logout != nil {
return nil
}
return backchannelLogout.GetBackChannelLogoutURLs()
}

func flattenOIDCLogout(oidcLogout *management.OIDCLogout) []interface{} {
if oidcLogout == nil {
return nil
}

flattened := map[string]interface{}{
"backchannel_logout_urls": oidcLogout.GetBackChannelLogoutURLs(),
"backchannel_logout_initiators": flattenBackChannelLogoutInitiators(
oidcLogout.GetBackChannelLogoutInitiators(),
),
}

return []interface{}{
flattened,
}
}
func flattenBackChannelLogoutInitiators(initiators *management.BackChannelLogoutInitiators) []interface{} {
if initiators == nil {
return nil
}

return []interface{}{
map[string]interface{}{
"mode": initiators.GetMode(),
"selected_initiators": initiators.GetSelectedInitiators(),
},
}
}

func flattenClientMobile(mobile *management.ClientMobile) []interface{} {
if mobile == nil {
return nil
Expand Down Expand Up @@ -557,7 +593,8 @@ func flattenClient(data *schema.ResourceData, client *management.Client) error {
data.Set("initiate_login_uri", client.GetInitiateLoginURI()),
data.Set("signing_keys", client.SigningKeys),
data.Set("client_metadata", client.GetClientMetadata()),
data.Set("oidc_backchannel_logout_urls", client.GetOIDCBackchannelLogout().GetBackChannelLogoutURLs()),
data.Set("oidc_backchannel_logout_urls", flattenOIDCBackchannelURLs(client.GetOIDCBackchannelLogout(), client.GetOIDCLogout())),
data.Set("oidc_logout", flattenOIDCLogout(client.GetOIDCLogout())),
data.Set("require_pushed_authorization_requests", client.GetRequirePushedAuthorizationRequests()),
data.Set("default_organization", flattenDefaultOrganization(client.GetDefaultOrganization())),
data.Set("require_proof_of_possession", client.GetRequireProofOfPossession()),
Expand Down
44 changes: 44 additions & 0 deletions internal/auth0/client/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ func NewResource() *schema.Resource {
},
Optional: true,
Description: "Set of URLs that are valid to call back from Auth0 for OIDC backchannel logout. Currently only one URL is allowed.",
Deprecated: "This resource is deprecated and will be removed in the next major version. " +
"Please use `oidc_logout` for managing OIDC backchannel logout URLs.",
},
"grant_types": {
Type: schema.TypeList,
Expand Down Expand Up @@ -1325,6 +1327,48 @@ func NewResource() *schema.Resource {
Optional: true,
Description: "Makes the use of Proof-of-Possession mandatory for this client.",
},
"oidc_logout": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Configure OIDC logout for the Client",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"backchannel_logout_urls": {
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Required: true,
Description: "Set of URLs that are valid to call back from Auth0 for OIDC backchannel logout. Currently only one URL is allowed.",
},
"backchannel_logout_initiators": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Configure OIDC logout initiators for the Client",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"all", "custom"}, false),
Description: "Determines the configuration method for enabling initiators. `custom` enables only the initiators listed in the backchannel_logout_selected_initiators set, `all` enables all current and future initiators.",
},
"selected_initiators": {
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Description: "Contains the list of initiators to be enabled for the given client.",
},
},
},
},
},
},
},
},
}
}
Expand Down
76 changes: 76 additions & 0 deletions internal/auth0/client/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2427,3 +2427,79 @@ func TestAccClientWithDefaultOrganization(t *testing.T) {
},
})
}

const testAccCreateClientWithOIDCLogout = `
resource "auth0_client" "my_client" {
name = "Acceptance Test - OIDC Logout - {{.testName}}"
app_type = "spa"
oidc_logout {
backchannel_logout_urls = ["https://auth0.test/all/logout"]
backchannel_logout_initiators {
mode = "all"
}
}
}
`

const testAccUpdateClientWithOIDCLogout = `
resource "auth0_client" "my_client" {
name = "Acceptance Test - OIDC Logout - {{.testName}}"
app_type = "spa"
oidc_logout {
backchannel_logout_urls = ["https://auth0.test/custom/logout"]
backchannel_logout_initiators {
mode = "custom"
selected_initiators = ["rp-logout", "idp-logout", "password-changed", "session-expired"]
}
}
}
`
const testAccUpdateClientWithOIDCLogoutWhenRemovedFromConfig = `
resource "auth0_client" "my_client" {
name = "Acceptance Test - OIDC Logout - {{.testName}}"
app_type = "spa"
}
`

func TestAccClientOIDCLogout(t *testing.T) {
acctest.Test(t, resource.TestCase{
Steps: []resource.TestStep{
{
Config: acctest.ParseTestName(testAccCreateClientWithOIDCLogout, t.Name()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_client.my_client", "name", fmt.Sprintf("Acceptance Test - OIDC Logout - %s", t.Name())),
resource.TestCheckResourceAttr("auth0_client.my_client", "app_type", "spa"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.#", "1"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_urls.#", "1"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_urls.0", "https://auth0.test/all/logout"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_initiators.#", "1"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_initiators.0.mode", "all"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_initiators.0.selected_initiators.#", "0"),
),
},
{
Config: acctest.ParseTestName(testAccUpdateClientWithOIDCLogout, t.Name()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_client.my_client", "name", fmt.Sprintf("Acceptance Test - OIDC Logout - %s", t.Name())),
resource.TestCheckResourceAttr("auth0_client.my_client", "app_type", "spa"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.#", "1"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_urls.#", "1"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_urls.0", "https://auth0.test/custom/logout"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_initiators.#", "1"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_initiators.0.mode", "custom"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.0.backchannel_logout_initiators.0.selected_initiators.#", "4"),
),
},
{
Config: acctest.ParseTestName(testAccUpdateClientWithOIDCLogoutWhenRemovedFromConfig, t.Name()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_client.my_client", "name", fmt.Sprintf("Acceptance Test - OIDC Logout - %s", t.Name())),
resource.TestCheckResourceAttr("auth0_client.my_client", "app_type", "spa"),
resource.TestCheckResourceAttr("auth0_client.my_client", "oidc_logout.#", "0"),
),
},
},
})
}
Loading

0 comments on commit c9492ab

Please sign in to comment.