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

Fix identity provider update and service account role management #171

Merged
9 changes: 3 additions & 6 deletions keycloak/openid_client_service_account_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@ type OpenidClientServiceAccountRole struct {
}

func (keycloakClient *KeycloakClient) NewOpenidClientServiceAccountRole(serviceAccountRole *OpenidClientServiceAccountRole) error {
role, err := keycloakClient.GetRoleByName(serviceAccountRole.RealmId, serviceAccountRole.ContainerId, serviceAccountRole.Name)
if err != nil {
return err
}
serviceAccountRole.Id = role.Id
serviceAccountRoles := []OpenidClientServiceAccountRole{*serviceAccountRole}
_, _, err = keycloakClient.post(fmt.Sprintf("/realms/%s/users/%s/role-mappings/clients/%s", serviceAccountRole.RealmId, serviceAccountRole.ServiceAccountUserId, serviceAccountRole.ContainerId), serviceAccountRoles)
_, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/users/%s/role-mappings/clients/%s", serviceAccountRole.RealmId, serviceAccountRole.ServiceAccountUserId, serviceAccountRole.ContainerId), serviceAccountRoles)
if err != nil {
return err
}
Expand Down Expand Up @@ -57,6 +52,8 @@ func (keycloakClient *KeycloakClient) GetOpenidClientServiceAccountRole(realm, s
}
for _, serviceAccountRole := range serviceAccountRoles {
if serviceAccountRole.Id == roleId {
serviceAccountRole.RealmId = realm
serviceAccountRole.ServiceAccountUserId = serviceAccountUserId
return &serviceAccountRole, nil
}
}
Expand Down
13 changes: 5 additions & 8 deletions provider/resource_keycloak_oidc_identity_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ func resourceKeycloakOidcIdentityProvider() *schema.Resource {
func getOidcIdentityProviderFromData(data *schema.ResourceData) (*keycloak.IdentityProvider, error) {
rec, _ := getIdentityProviderFromData(data)
rec.ProviderId = data.Get("provider_id").(string)
_, useJwksUrl := data.GetOk("jwks_url")
_, enableUserInfo := data.GetOk("user_info_url")

extraConfig := map[string]interface{}{}
if v, ok := data.GetOk("extra_config"); ok {
Expand All @@ -107,6 +109,7 @@ func getOidcIdentityProviderFromData(data *schema.ResourceData) (*keycloak.Ident
ValidateSignature: keycloak.KeycloakBoolQuoted(data.Get("validate_signature").(bool)),
AuthorizationUrl: data.Get("authorization_url").(string),
ClientId: data.Get("client_id").(string),
ClientSecret: data.Get("client_secret").(string),
HideOnLoginPage: keycloak.KeycloakBoolQuoted(data.Get("hide_on_login_page").(bool)),
TokenUrl: data.Get("token_url").(string),
LogoutUrl: data.Get("logout_url").(string),
Expand All @@ -115,14 +118,8 @@ func getOidcIdentityProviderFromData(data *schema.ResourceData) (*keycloak.Ident
JwksUrl: data.Get("jwks_url").(string),
UserInfoUrl: data.Get("user_info_url").(string),
ExtraConfig: extraConfig,
}
_, useJwksUrl := data.GetOk("jwks_url")
rec.Config.UseJwksUrl = keycloak.KeycloakBoolQuoted(useJwksUrl)
_, enableUserInfo := data.GetOk("user_info_url")
rec.Config.DisableUserInfo = keycloak.KeycloakBoolQuoted(!enableUserInfo)

if data.HasChange("client_secret") {
rec.Config.ClientSecret = data.Get("client_secret").(string)
UseJwksUrl: keycloak.KeycloakBoolQuoted(useJwksUrl),
DisableUserInfo: keycloak.KeycloakBoolQuoted(!enableUserInfo),
}

return rec, nil
Expand Down
66 changes: 44 additions & 22 deletions provider/resource_keycloak_openid_client_service_account_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,32 @@ func resourceKeycloakOpenidClientServiceAccountRole() *schema.Resource {
}
}

func getOpenidClientServiceAccountRoleFromData(data *schema.ResourceData) *keycloak.OpenidClientServiceAccountRole {
return &keycloak.OpenidClientServiceAccountRole{
Id: data.Id(),
ContainerId: data.Get("client_id").(string),
Name: data.Get("role").(string),
RealmId: data.Get("realm_id").(string),
ServiceAccountUserId: data.Get("service_account_user_id").(string),
func getOpenidClientServiceAccountRoleFromData(data *schema.ResourceData, keycloakClient *keycloak.KeycloakClient) (*keycloak.OpenidClientServiceAccountRole, error) {
containerId := data.Get("client_id").(string)
roleName := data.Get("role").(string)
realmId := data.Get("realm_id").(string)
serviceAccountRoleId := data.Get("service_account_user_id").(string)

role, err := keycloakClient.GetRoleByName(realmId, containerId, roleName)
if err != nil {
if keycloak.ErrorIs404(err) {
role = &keycloak.Role{Id: ""}
} else {
return nil, err
}
}

return &keycloak.OpenidClientServiceAccountRole{
Id: role.Id,
ContainerId: containerId,
Name: roleName,
RealmId: realmId,
ServiceAccountUserId: serviceAccountRoleId,
}, nil
}

func setOpenidClientServiceAccountRoleData(data *schema.ResourceData, serviceAccountRole *keycloak.OpenidClientServiceAccountRole) {
data.SetId(serviceAccountRole.Id)
data.SetId(fmt.Sprintf("%s/%s", serviceAccountRole.ServiceAccountUserId, serviceAccountRole.Id))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a breaking change since the ID for this resource is being changed. Can you verify that these resources aren't being recreated because of this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just new resources will be created. In context of service account roles it'll try to apply existing changes once to add service account roles with ned IDs but POST action to service account roles endpoint always returns 204 even if role was already added

data.Set("realm_id", serviceAccountRole.RealmId)
data.Set("client_id", serviceAccountRole.ContainerId)
data.Set("service_account_user_id", serviceAccountRole.ServiceAccountUserId)
Expand All @@ -60,8 +74,12 @@ func setOpenidClientServiceAccountRoleData(data *schema.ResourceData, serviceAcc

func resourceKeycloakOpenidClientServiceAccountRoleCreate(data *schema.ResourceData, meta interface{}) error {
keycloakClient := meta.(*keycloak.KeycloakClient)
serviceAccountRole := getOpenidClientServiceAccountRoleFromData(data)
err := keycloakClient.NewOpenidClientServiceAccountRole(serviceAccountRole)
serviceAccountRole, err := getOpenidClientServiceAccountRoleFromData(data, keycloakClient)
if err != nil {
return err
}

err = keycloakClient.NewOpenidClientServiceAccountRole(serviceAccountRole)
if err != nil {
return err
}
Expand All @@ -72,12 +90,12 @@ func resourceKeycloakOpenidClientServiceAccountRoleCreate(data *schema.ResourceD
func resourceKeycloakOpenidClientServiceAccountRoleRead(data *schema.ResourceData, meta interface{}) error {
keycloakClient := meta.(*keycloak.KeycloakClient)

realmId := data.Get("realm_id").(string)
serviceAccountUserId := data.Get("service_account_user_id").(string)
clientId := data.Get("client_id").(string)
id := data.Id()
serviceAccountRole, err := getOpenidClientServiceAccountRoleFromData(data, keycloakClient)
if err != nil {
return err
}

serviceAccountRole, err := keycloakClient.GetOpenidClientServiceAccountRole(realmId, serviceAccountUserId, clientId, id)
serviceAccountRole, err = keycloakClient.GetOpenidClientServiceAccountRole(serviceAccountRole.RealmId, serviceAccountRole.ServiceAccountUserId, serviceAccountRole.ContainerId, serviceAccountRole.Id)
if err != nil {
return handleNotFoundError(err, data)
}
Expand All @@ -90,23 +108,27 @@ func resourceKeycloakOpenidClientServiceAccountRoleRead(data *schema.ResourceDat
func resourceKeycloakOpenidClientServiceAccountRoleDelete(data *schema.ResourceData, meta interface{}) error {
keycloakClient := meta.(*keycloak.KeycloakClient)

realmId := data.Get("realm_id").(string)
serviceAccountUserId := data.Get("service_account_user_id").(string)
clientId := data.Get("client_id").(string)
id := data.Id()
serviceAccountRole, err := getOpenidClientServiceAccountRoleFromData(data, keycloakClient)
if err != nil {
return err
}

return keycloakClient.DeleteOpenidClientServiceAccountRole(realmId, serviceAccountUserId, clientId, id)
err = keycloakClient.DeleteOpenidClientServiceAccountRole(serviceAccountRole.RealmId, serviceAccountRole.ServiceAccountUserId, serviceAccountRole.ContainerId, serviceAccountRole.Id)
if err != nil {
return handleNotFoundError(err, data)
}
return nil
}

func resourceKeycloakOpenidClientServiceAccountRoleImport(d *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) {
parts := strings.Split(d.Id(), "/")
if len(parts) != 3 {
return nil, fmt.Errorf("Invalid import. Supported import formats: {{realmId}}/{{serviceAccountUserId}}/{{clientId}}/{{role}}")
return nil, fmt.Errorf("Invalid import. Supported import formats: {{realmId}}/{{serviceAccountUserId}}/{{clientId}}/{{roleId}}")
}
d.Set("realm_id", parts[0])
d.Set("service_account_user_id", parts[1])
d.Set("client_id", parts[2])
d.SetId(parts[3])
d.SetId(fmt.Sprintf("%s/%s", parts[1], parts[3]))

return []*schema.ResourceData{d}, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/mrparkers/terraform-provider-keycloak/keycloak"
"strings"
"testing"
)

Expand Down Expand Up @@ -123,7 +124,7 @@ func testAccCheckKeycloakOpenidClientServiceAccountRoleDestroy() resource.TestCh
realmId := rs.Primary.Attributes["realm_id"]
serviceAccountUserId := rs.Primary.Attributes["service_account_user_id"]
clientId := rs.Primary.Attributes["client_id"]
id := rs.Primary.ID
id := strings.Split(rs.Primary.ID, "/")[1]

keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)

Expand All @@ -148,7 +149,7 @@ func getKeycloakOpenidClientServiceAccountRoleFromState(s *terraform.State, reso
realmId := rs.Primary.Attributes["realm_id"]
serviceAccountUserId := rs.Primary.Attributes["service_account_user_id"]
clientId := rs.Primary.Attributes["client_id"]
id := rs.Primary.ID
id := strings.Split(rs.Primary.ID, "/")[1]

serviceAccountRole, err := keycloakClient.GetOpenidClientServiceAccountRole(realmId, serviceAccountUserId, clientId, id)
if err != nil {
Expand Down