Skip to content

Commit

Permalink
Add support for the ExcludeIssuerFromAuthResponse option on OpenIdCli…
Browse files Browse the repository at this point in the history
…ent (#934)

Signed-off-by: Sébastien Gahat <[email protected]>
  • Loading branch information
sebght authored Feb 10, 2025
1 parent 2a6926d commit 9ee4f2d
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 5 deletions.
1 change: 1 addition & 0 deletions docs/resources/openid_client.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ is set to `true`.
- `direct_grant_id` - (Optional) Direct grant flow id (flow needs to exist)
- `login_theme` - (Optional) The client login theme. This will override the default theme for the realm.
- `exclude_session_state_from_auth_response` - (Optional) When `true`, the parameter `session_state` will not be included in OpenID Connect Authentication Response.
- `exclude_issuer_from_auth_response` - (Optional) When `true`, the parameter `iss` will not be included in OpenID Connect Authentication Response.
- `use_refresh_tokens` - (Optional) If this is `true`, a refresh_token will be created and added to the token response. If this is `false` then no refresh_token will be generated. Defaults to `true`.
- `use_refresh_tokens_client_credentials` - (Optional) If this is `true`, a refresh_token will be created and added to the token response if the client_credentials grant is used and a user session will be created. If this is `false` then no refresh_token will be generated and the associated user session will be removed, in accordance with OAuth 2.0 RFC6749 Section 4.4.3. Defaults to `false`.
- `oauth2_device_authorization_grant_enabled` - (Optional) Enables support for OAuth 2.0 Device Authorization Grant, which means that client is an application on device that has limited input capabilities or lack a suitable browser.
Expand Down
1 change: 1 addition & 0 deletions keycloak/openid_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type OpenidClient struct {
type OpenidClientAttributes struct {
PkceCodeChallengeMethod string `json:"pkce.code.challenge.method"`
ExcludeSessionStateFromAuthResponse types.KeycloakBoolQuoted `json:"exclude.session.state.from.auth.response"`
ExcludeIssuerFromAuthResponse types.KeycloakBoolQuoted `json:"exclude.issuer.from.auth.response"`
AccessTokenLifespan string `json:"access.token.lifespan"`
LoginTheme string `json:"login_theme"`
ClientOfflineSessionIdleTimeout string `json:"client.offline.session.idle.timeout,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions provider/data_source_keycloak_openid_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ func dataSourceKeycloakOpenidClient() *schema.Resource {
Type: schema.TypeBool,
Computed: true,
},
"exclude_issuer_from_auth_response": {
Type: schema.TypeBool,
Computed: true,
},
"resource_server_id": {
Type: schema.TypeString,
Computed: true,
Expand Down
6 changes: 6 additions & 0 deletions provider/resource_keycloak_openid_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ func resourceKeycloakOpenidClient() *schema.Resource {
Optional: true,
Computed: true,
},
"exclude_issuer_from_auth_response": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"resource_server_id": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -356,6 +361,7 @@ func getOpenidClientFromData(data *schema.ResourceData) (*keycloak.OpenidClient,
Attributes: keycloak.OpenidClientAttributes{
PkceCodeChallengeMethod: data.Get("pkce_code_challenge_method").(string),
ExcludeSessionStateFromAuthResponse: types.KeycloakBoolQuoted(data.Get("exclude_session_state_from_auth_response").(bool)),
ExcludeIssuerFromAuthResponse: types.KeycloakBoolQuoted(data.Get("exclude_issuer_from_auth_response").(bool)),
AccessTokenLifespan: data.Get("access_token_lifespan").(string),
LoginTheme: data.Get("login_theme").(string),
ClientOfflineSessionIdleTimeout: data.Get("client_offline_session_idle_timeout").(string),
Expand Down
102 changes: 97 additions & 5 deletions provider/resource_keycloak_openid_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestAccKeycloakOpenidClient_basic(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: testAccRealm.Realm + "/",
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response"},
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response", "exclude_issuer_from_auth_response"},
},
},
})
Expand All @@ -55,7 +55,7 @@ func TestAccKeycloakOpenidClient_basic_with_consent(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: testAccRealm.Realm + "/",
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response"},
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response", "exclude_issuer_from_auth_response"},
},
},
})
Expand Down Expand Up @@ -331,7 +331,7 @@ func TestAccKeycloakOpenidClient_AccessToken_basic(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: testAccRealm.Realm + "/",
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response"},
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response", "exclude_issuer_from_auth_response"},
},
},
})
Expand Down Expand Up @@ -363,7 +363,7 @@ func TestAccKeycloakOpenidClient_ClientTimeouts_basic(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: testAccRealm.Realm + "/",
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response"},
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response", "exclude_issuer_from_auth_response"},
},
},
})
Expand Down Expand Up @@ -399,7 +399,7 @@ func TestAccKeycloakOpenidClient_Device_basic(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
ImportStateIdPrefix: testAccRealm.Realm + "/",
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response"},
ImportStateVerifyIgnore: []string{"exclude_session_state_from_auth_response", "exclude_issuer_from_auth_response"},
},
},
})
Expand Down Expand Up @@ -519,27 +519,31 @@ func TestAccKeycloakOpenidClient_pkceCodeChallengeMethod(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", ""),
testAccCheckKeycloakOpenidClientHasExcludeSessionStateFromAuthResponse("keycloak_openid_client.client", false),
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", false),
),
},
{
Config: testKeycloakOpenidClient_pkceChallengeMethod(clientId, "plain"),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", "plain"),
testAccCheckKeycloakOpenidClientHasExcludeSessionStateFromAuthResponse("keycloak_openid_client.client", false),
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", false),
),
},
{
Config: testKeycloakOpenidClient_pkceChallengeMethod(clientId, "S256"),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", "S256"),
testAccCheckKeycloakOpenidClientHasExcludeSessionStateFromAuthResponse("keycloak_openid_client.client", false),
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", false),
),
},
{
Config: testKeycloakOpenidClient_pkceChallengeMethod(clientId, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", ""),
testAccCheckKeycloakOpenidClientHasExcludeSessionStateFromAuthResponse("keycloak_openid_client.client", false),
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", false),
),
},
},
Expand Down Expand Up @@ -587,6 +591,47 @@ func TestAccKeycloakOpenidClient_excludeSessionStateFromAuthResponse(t *testing.
})
}

func TestAccKeycloakOpenidClient_excludeIssuerFromAuthResponse(t *testing.T) {
t.Parallel()
clientId := acctest.RandomWithPrefix("tf-acc")

resource.Test(t, resource.TestCase{
ProviderFactories: testAccProviderFactories,
PreCheck: func() { testAccPreCheck(t) },
CheckDestroy: testAccCheckKeycloakOpenidClientDestroy(),
Steps: []resource.TestStep{
{
Config: testKeycloakOpenidClient_omitExcludeIssuerFromAuthResponse(clientId, "plain"),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", false),
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", "plain"),
),
},
{
Config: testKeycloakOpenidClient_excludeIssuerFromAuthResponse(clientId, false),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", false),
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", ""),
),
},
{
Config: testKeycloakOpenidClient_excludeIssuerFromAuthResponse(clientId, true),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", true),
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", ""),
),
},
{
Config: testKeycloakOpenidClient_excludeIssuerFromAuthResponse(clientId, false),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse("keycloak_openid_client.client", false),
testAccCheckKeycloakOpenidClientHasPkceCodeChallengeMethod("keycloak_openid_client.client", ""),
),
},
},
})
}

func TestAccKeycloakOpenidClient_authenticationFlowBindingOverrides(t *testing.T) {
t.Parallel()
clientId := acctest.RandomWithPrefix("tf-acc")
Expand Down Expand Up @@ -1086,6 +1131,21 @@ func testAccCheckKeycloakOpenidClientHasExcludeSessionStateFromAuthResponse(reso
}
}

func testAccCheckKeycloakOpenidClientHasExcludeIssuerFromAuthResponse(resourceName string, excludeIssuerFromAuthResponse types.KeycloakBoolQuoted) resource.TestCheckFunc {
return func(s *terraform.State) error {
client, err := getOpenidClientFromState(s, resourceName)
if err != nil {
return err
}

if client.Attributes.ExcludeIssuerFromAuthResponse != excludeIssuerFromAuthResponse {
return fmt.Errorf("expected openid client %s to have exclude_issuer_from_auth_response value of %t, but got %t", client.ClientId, excludeIssuerFromAuthResponse, client.Attributes.ExcludeIssuerFromAuthResponse)
}

return nil
}
}

func testAccCheckKeycloakOpenidClientAuthenticationFlowBindingOverrides(resourceName, flowResourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client, err := getOpenidClientFromState(s, resourceName)
Expand Down Expand Up @@ -1381,6 +1441,22 @@ resource "keycloak_openid_client" "client" {
`, testAccRealm.Realm, clientId, excludeSessionStateFromAuthResponse)
}

func testKeycloakOpenidClient_excludeIssuerFromAuthResponse(clientId string, excludeIssuerFromAuthResponse bool) string {

return fmt.Sprintf(`
data "keycloak_realm" "realm" {
realm = "%s"
}
resource "keycloak_openid_client" "client" {
client_id = "%s"
realm_id = data.keycloak_realm.realm.id
access_type = "CONFIDENTIAL"
exclude_issuer_from_auth_response = %t
}
`, testAccRealm.Realm, clientId, excludeIssuerFromAuthResponse)
}

func testKeycloakOpenidClient_omitPkceChallengeMethod(clientId string) string {

return fmt.Sprintf(`
Expand Down Expand Up @@ -1412,6 +1488,22 @@ resource "keycloak_openid_client" "client" {
`, testAccRealm.Realm, clientId, pkceChallengeMethod)
}

func testKeycloakOpenidClient_omitExcludeIssuerFromAuthResponse(clientId, pkceChallengeMethod string) string {

return fmt.Sprintf(`
data "keycloak_realm" "realm" {
realm = "%s"
}
resource "keycloak_openid_client" "client" {
client_id = "%s"
realm_id = data.keycloak_realm.realm.id
access_type = "CONFIDENTIAL"
pkce_code_challenge_method = "%s"
}
`, testAccRealm.Realm, clientId, pkceChallengeMethod)
}

func testKeycloakOpenidClient_updateRealmBefore(clientId string) string {
return fmt.Sprintf(`
data "keycloak_realm" "realm_1" {
Expand Down

0 comments on commit 9ee4f2d

Please sign in to comment.