Skip to content

Commit

Permalink
allow extra config for keycloak_custom_user_federation resource (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomrutsaert authored and mrparkers committed Jul 17, 2019
1 parent 2b1794b commit 3e8a3e6
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,32 @@ package com.github.mrparkers.keycloak

import org.keycloak.component.ComponentModel
import org.keycloak.models.KeycloakSession
import org.keycloak.provider.ProviderConfigProperty
import org.keycloak.storage.UserStorageProviderFactory

class CustomUserStorageProviderFactory : UserStorageProviderFactory<CustomUserStorageProvider> {
override fun getId(): String = "custom"
override fun getId(): String = "custom"

override fun init(config: org.keycloak.Config.Scope) {
super.init(config)
}
override fun init(config: org.keycloak.Config.Scope) {
super.init(config)
}

override fun create(session: KeycloakSession, model: ComponentModel): CustomUserStorageProvider =
CustomUserStorageProvider(session, model)
override fun create(session: KeycloakSession, model: ComponentModel): CustomUserStorageProvider =
CustomUserStorageProvider(session, model)

override fun getConfigProperties(): List<ProviderConfigProperty> = configPropertyList

companion object {
private val configPropertyList = ArrayList<ProviderConfigProperty>()

init {
val property = ProviderConfigProperty()
property.setName("dummyConfig")
property.setLabel("Dummy Config")
property.setDefaultValue("")
property.setType(ProviderConfigProperty.STRING_TYPE)
property.setHelpText("Dummy config for testing")
configPropertyList.add(property)
}
}
}
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ services:
environment:
- DB_VENDOR=POSTGRES
- KEYCLOAK_LOGLEVEL=DEBUG
- POSTGRES_USER=keycloak
- POSTGRES_DATABASE=keycloak
- POSTGRES_PASSWORD=password
- DB_USER=keycloak
- DB_DATABASE=keycloak
- DB_PASSWORD=password
- KEYCLOAK_USER=keycloak
- KEYCLOAK_PASSWORD=password
- POSTGRES_PORT_5432_TCP_ADDR=postgres
Expand Down
30 changes: 20 additions & 10 deletions keycloak/custom_user_federation.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,25 @@ type CustomUserFederation struct {
Priority int

CachePolicy string

Config map[string][]string
}

var (
userStorageProviderType = "org.keycloak.storage.UserStorageProvider"
)

func convertFromCustomUserFederationToComponent(custom *CustomUserFederation) *component {
componentConfig := map[string][]string{
"cachePolicy": {
custom.CachePolicy,
},
"enabled": {
strconv.FormatBool(custom.Enabled),
},
"priority": {
strconv.Itoa(custom.Priority),
},
componentConfig := make(map[string][]string)

if custom.Config != nil {
for k, j := range custom.Config {
componentConfig[k] = append(componentConfig[k], j[0])
}
}
componentConfig["cachePolicy"] = append(componentConfig["cachePolicy"], custom.CachePolicy)
componentConfig["enabled"] = append(componentConfig["enabled"], strconv.FormatBool(custom.Enabled))
componentConfig["priority"] = append(componentConfig["priority"], strconv.Itoa(custom.Priority))

return &component{
Id: custom.Id,
Expand All @@ -55,6 +56,13 @@ func convertFromComponentToCustomUserFederation(component *component) (*CustomUs
return nil, err
}

config := make(map[string][]string)
for k := range component.Config {
if k != "enabled" && k != "priority" && k != "cachePolicy" {
config[k] = append(config[k], component.getConfig(k))
}
}

custom := &CustomUserFederation{
Id: component.Id,
Name: component.Name,
Expand All @@ -65,6 +73,8 @@ func convertFromComponentToCustomUserFederation(component *component) (*CustomUs
Priority: priority,

CachePolicy: component.getConfig("cachePolicy"),

Config: config,
}

return custom, nil
Expand Down
15 changes: 15 additions & 0 deletions provider/resource_keycloak_custom_user_federation.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,23 @@ func resourceKeycloakCustomUserFederation() *schema.Resource {
Default: "DEFAULT",
ValidateFunc: validation.StringInSlice(keycloakUserFederationCachePolicies, false),
},

"config": {
Type: schema.TypeMap,
Optional: true,
},
},
}
}

func getCustomUserFederationFromData(data *schema.ResourceData) *keycloak.CustomUserFederation {
config := map[string][]string{}
if v, ok := data.GetOk("config"); ok {
for key, value := range v.(map[string]interface{}) {
config[key] = strings.Split(value.(string), ",")
}
}

return &keycloak.CustomUserFederation{
Id: data.Id(),
Name: data.Get("name").(string),
Expand All @@ -71,6 +83,8 @@ func getCustomUserFederationFromData(data *schema.ResourceData) *keycloak.Custom
Priority: data.Get("priority").(int),

CachePolicy: data.Get("cache_policy").(string),

Config: config,
}
}

Expand All @@ -85,6 +99,7 @@ func setCustomUserFederationData(data *schema.ResourceData, custom *keycloak.Cus
data.Set("priority", custom.Priority)

data.Set("cache_policy", custom.CachePolicy)
data.Set("config", custom.Config)
}

func resourceKeycloakCustomUserFederationCreate(data *schema.ResourceData, meta interface{}) error {
Expand Down
56 changes: 56 additions & 0 deletions provider/resource_keycloak_custom_user_federation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,27 @@ func TestAccKeycloakCustomUserFederation_basic(t *testing.T) {
})
}

func TestAccKeycloakCustomUserFederation_customConfig(t *testing.T) {
skipIfEnvSet(t, "CI") // temporary while I figure out how to load this custom provider in CI

realmName := "terraform-" + acctest.RandString(10)
name := "terraform-" + acctest.RandString(10)
configValue := "value-" + acctest.RandString(10)
providerId := "custom"

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
CheckDestroy: testAccCheckKeycloakCustomUserFederationDestroy(),
Steps: []resource.TestStep{
{
Config: testKeycloakCustomUserFederation_customConfig(realmName, name, providerId, configValue),
Check: testAccCheckKeycloakCustomUserFederationExistsWithCustomConfig("keycloak_custom_user_federation.custom", configValue),
},
},
})
}

func TestAccKeycloakCustomUserFederation_createAfterManualDestroy(t *testing.T) {
skipIfEnvSet(t, "CI") // temporary while I figure out how to load this custom provider in CI

Expand Down Expand Up @@ -99,6 +120,21 @@ func testAccCheckKeycloakCustomUserFederationExists(resourceName string) resourc
}
}

func testAccCheckKeycloakCustomUserFederationExistsWithCustomConfig(resourceName, customConfigValue string) resource.TestCheckFunc {
return func(s *terraform.State) error {
fetchedFederation, err := getCustomUserFederationFromState(s, resourceName)
if err != nil {
return err
}

if len(fetchedFederation.Config["dummyConfig"]) <= 0 || fetchedFederation.Config["dummyConfig"][0] != customConfigValue {
return fmt.Errorf("expected user federation provider to have config with a custom key 'dummyConfig' with a value %s", customConfigValue)
}

return nil
}
}

func testAccCheckKeycloakCustomUserFederationFetch(resourceName string, federation *keycloak.CustomUserFederation) resource.TestCheckFunc {
return func(s *terraform.State) error {
fetchedFederation, err := getCustomUserFederationFromState(s, resourceName)
Expand Down Expand Up @@ -169,3 +205,23 @@ resource "keycloak_custom_user_federation" "custom" {
}
`, realm, name, providerId)
}

func testKeycloakCustomUserFederation_customConfig(realm, name, providerId, customConfigValue string) string {
return fmt.Sprintf(`
resource "keycloak_realm" "realm" {
realm = "%s"
}
resource "keycloak_custom_user_federation" "custom" {
name = "%s"
realm_id = "${keycloak_realm.realm.id}"
provider_id = "%s"
enabled = true
config = {
dummyConfig = "%s"
}
}
`, realm, name, providerId, customConfigValue)
}

0 comments on commit 3e8a3e6

Please sign in to comment.