Skip to content

Commit

Permalink
Merge pull request #1 from embracesbs/features/resource-keycloak-gene…
Browse files Browse the repository at this point in the history
…ric-client-role-mapper-extension

Extension of keycloak_generic_client_role_mapper resource to support realm-level roles association
  • Loading branch information
branislav-vega authored Jun 10, 2020
2 parents 073eca1 + 11c5d74 commit 880fa5d
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 15 deletions.
38 changes: 38 additions & 0 deletions example/roles.tf
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,44 @@ resource "keycloak_generic_client_role_mapper" "pet_app_pet_api_admin_role_mappi
role_id = "${keycloak_role.pet_api_admin.id}"
}

// Realm roles

resource "keycloak_role" "realm_reader" {
realm_id = "${keycloak_realm.roles_example.id}"
name = "realm_reader"
description = "Reader realm role"
}

resource "keycloak_role" "realm_writer" {
realm_id = "${keycloak_realm.roles_example.id}"
name = "realm_writer"
description = "Writer realm role"
}

resource "keycloak_role" "realm_admin" {
realm_id = "${keycloak_realm.roles_example.id}"
name = "realm_admin"
description = "Admin realm composite role"
composite_roles = [
"${keycloak_role.realm_reader.id}",
"${keycloak_role.realm_writer.id}"
]
}

// Client scope for realm roles mapping

resource "keycloak_openid_client_scope" "petstore_api_access_scope" {
realm_id = "${keycloak_realm.roles_example.id}"
name = "petstore-api-access"
description = "Optional scope offering additional information for petstore api access"
}

resource "keycloak_generic_client_role_mapper" "petstore_api_access_scope_admin" {
realm_id = "${keycloak_realm.roles_example.id}"
client_scope_id = "${keycloak_openid_client_scope.petstore_api_access_scope.id}"
role_id = "${keycloak_role.realm_admin.id}"
}

// Users and groups

resource "keycloak_group" "pet_api_base" {
Expand Down
13 changes: 11 additions & 2 deletions keycloak/role_scope_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,19 @@ import (
)

func roleScopeMappingUrl(realmId, clientId string, clientScopeId string, role *Role) string {

if clientId != "" {
return fmt.Sprintf("/realms/%s/clients/%s/scope-mappings/clients/%s", realmId, clientId, role.ClientId)
} else {
if role.ClientRole {
return fmt.Sprintf("/realms/%s/clients/%s/scope-mappings/clients/%s", realmId, clientId, role.ClientId)
} else {
return fmt.Sprintf("/realms/%s/clients/%s/scope-mappings/realm", realmId, clientId)
}
}

if role.ClientRole {
return fmt.Sprintf("/realms/%s/client-scopes/%s/scope-mappings/clients/%s", realmId, clientScopeId, role.ClientId)
} else {
return fmt.Sprintf("/realms/%s/client-scopes/%s/scope-mappings/realm", realmId, clientScopeId)
}
}

Expand Down
103 changes: 90 additions & 13 deletions provider/resource_keycloak_generic_client_role_mapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package provider

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/mrparkers/terraform-provider-keycloak/keycloak"
"testing"
)

func TestGenericRoleMapper_basic(t *testing.T) {
Expand All @@ -27,6 +28,42 @@ func TestGenericRoleMapper_basic(t *testing.T) {
})
}

func TestGenericRoleMapper_createAfterManualDestroy(t *testing.T) {
var role = &keycloak.Role{}
var childClient = &keycloak.GenericClient{}

realmName := "terraform-" + acctest.RandString(10)
parentClientName := "client1-" + acctest.RandString(10)
parentRoleName := "role-" + acctest.RandString(10)
childClientName := "client2-" + acctest.RandString(10)

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Steps: []resource.TestStep{
{
Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"),
testAccCheckKeycloakRoleFetch("keycloak_role.parent-role", role),
testAccCheckKeycloakGenericClientFetch("keycloak_openid_client.child-client", childClient),
),
},
{
PreConfig: func() {
keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)

err := keycloakClient.DeleteRoleScopeMapping(childClient.RealmId, childClient.Id, "", role)
if err != nil {
t.Fatal(err)
}
},
Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName),
Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"),
},
},
})
}
func TestGenericRoleMapperClientScope_basic(t *testing.T) {
realmName := "terraform-" + acctest.RandString(10)
clientName := "client-" + acctest.RandString(10)
Expand All @@ -45,38 +82,54 @@ func TestGenericRoleMapperClientScope_basic(t *testing.T) {
})
}

func TestGenericRoleMapper_createAfterManualDestroy(t *testing.T) {
func TestGenericRealmLevelRoleMapperClientScope_basic(t *testing.T) {
realmName := "terraform-" + acctest.RandString(10)
roleName := "role-" + acctest.RandString(10)
clientScopeName := "clientscope-" + acctest.RandString(10)

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Steps: []resource.TestStep{
{
Config: testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName),
Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.clientscope-with-realm-role"),
},
},
})
}

func TestGenericRealmLevelRoleMapperClientScope_createAfterManualDestroy(t *testing.T) {
var role = &keycloak.Role{}
var childClient = &keycloak.GenericClient{}
var clientScope = &keycloak.OpenidClientScope{}

realmName := "terraform-" + acctest.RandString(10)
parentClientName := "client1-" + acctest.RandString(10)
parentRoleName := "role-" + acctest.RandString(10)
childClientName := "client2-" + acctest.RandString(10)
roleName := "role-" + acctest.RandString(10)
clientScopeName := "clientscope-" + acctest.RandString(10)

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Steps: []resource.TestStep{
{
Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName),
Config: testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName),
Check: resource.ComposeTestCheckFunc(
testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"),
testAccCheckKeycloakRoleFetch("keycloak_role.parent-role", role),
testAccCheckKeycloakGenericClientFetch("keycloak_openid_client.child-client", childClient),
testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.clientscope-with-realm-role"),
testAccCheckKeycloakRoleFetch("keycloak_role.role", role),
testAccCheckKeycloakOpenidClientScopeFetch("keycloak_openid_client_scope.clientscope", clientScope),
),
},
{
PreConfig: func() {
keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)

err := keycloakClient.DeleteRoleScopeMapping(childClient.RealmId, childClient.Id, "", role)
err := keycloakClient.DeleteRoleScopeMapping(clientScope.RealmId, "", clientScope.Id, role)
if err != nil {
t.Fatal(err)
}
},
Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName),
Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"),
Config: testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName),
Check: testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.clientscope-with-realm-role"),
},
},
})
Expand Down Expand Up @@ -182,6 +235,30 @@ resource "keycloak_generic_client_role_mapper" "clientscope-with-client-role" {
`, realmName, clientName, roleName, clientScopeName)
}

func testKeycloakGenericRealmLevelRoleMappingClientScope_basic(realmName, roleName, clientScopeName string) string {
return fmt.Sprintf(`
resource "keycloak_realm" "realm" {
realm = "%s"
}
resource "keycloak_role" "role" {
realm_id = "${keycloak_realm.realm.id}"
name = "%s"
}
resource "keycloak_openid_client_scope" "clientscope" {
realm_id = "${keycloak_realm.realm.id}"
name = "%s"
}
resource "keycloak_generic_client_role_mapper" "clientscope-with-realm-role" {
realm_id = "${keycloak_realm.realm.id}"
client_scope_id = "${keycloak_openid_client_scope.clientscope.id}"
role_id = "${keycloak_role.role.id}"
}
`, realmName, roleName, clientScopeName)
}

func testAccCheckKeycloakScopeMappingExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
_, ok := s.RootModule().Resources[resourceName]
Expand Down

0 comments on commit 880fa5d

Please sign in to comment.