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

Add OIDC backchannel initiators #1045

Merged
merged 8 commits into from
Nov 28, 2024
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
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.
developerkunal marked this conversation as resolved.
Show resolved Hide resolved
- `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),
developerkunal marked this conversation as resolved.
Show resolved Hide resolved
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()),
developerkunal marked this conversation as resolved.
Show resolved Hide resolved
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
Loading