diff --git a/example/roles.tf b/example/roles.tf index da2295767..c00bb2f04 100644 --- a/example/roles.tf +++ b/example/roles.tf @@ -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" { diff --git a/keycloak/role_scope_mapping.go b/keycloak/role_scope_mapping.go index 4aabd4f33..35506d417 100644 --- a/keycloak/role_scope_mapping.go +++ b/keycloak/role_scope_mapping.go @@ -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) } } diff --git a/provider/resource_keycloak_generic_client_role_mapper_test.go b/provider/resource_keycloak_generic_client_role_mapper_test.go index 7983f5ccb..46f2d2238 100644 --- a/provider/resource_keycloak_generic_client_role_mapper_test.go +++ b/provider/resource_keycloak_generic_client_role_mapper_test.go @@ -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) { @@ -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) @@ -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"), }, }, }) @@ -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]