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

Features/management permission reference #2

Merged
merged 11 commits into from
Jun 10, 2020
20 changes: 20 additions & 0 deletions keycloak/management_permissions_reference.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package keycloak

//https://www.keycloak.org/docs-api/5.0/rest-api/index.html#_managementpermissionreference
type managementPermissionReference struct {
Enabled bool `json:"enabled"`
Resource string `json:"resource"`
ScopePermissions map[string]string `json:"scopePermissions"`
}

func disableClientManagementPermissionsReference() *managementPermissionReference {
return &managementPermissionReference{
Enabled: false,
}
}

func enableClientManagementPermissionsReference() *managementPermissionReference {
return &managementPermissionReference{
Enabled: true,
}
}
63 changes: 63 additions & 0 deletions keycloak/openid_client_management_permissions_reference.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package keycloak

import (
"fmt"
)

type OpenIdClientManagementPermissionsReference struct {
RealmId string
ClientId string
Enabled bool
Resource string
ScopePermissions map[string]string
}

func (reference *OpenIdClientManagementPermissionsReference) openIdClientManagementPermissionsReferencePath() string {
return openIdClientManagementPermissionsReferencePath(reference.RealmId, reference.ClientId)
}

func openIdClientManagementPermissionsReferencePath(realmId, clientId string) string {
return fmt.Sprintf("/realms/%s/clients/%s/management/permissions", realmId, clientId)
}

func (reference *OpenIdClientManagementPermissionsReference) convertToGenericManagementPermissionsReference() *managementPermissionReference {
return &managementPermissionReference{
Enabled: reference.Enabled,
Resource: reference.Resource,
ScopePermissions: reference.ScopePermissions,
}
}

func (genericReference *managementPermissionReference) convertToOpenIdClientManagementPermissionsReference(realmId, clientId string) *OpenIdClientManagementPermissionsReference {
return &OpenIdClientManagementPermissionsReference{
RealmId: realmId,
ClientId: clientId,
Enabled: genericReference.Enabled,
Resource: genericReference.Resource,
ScopePermissions: genericReference.ScopePermissions,
}
}

func (keycloakClient *KeycloakClient) GetOpenIdClientManagementPermissionsReference(realmId, clientId string) (*OpenIdClientManagementPermissionsReference, error) {
var genericReference *managementPermissionReference

err := keycloakClient.get(openIdClientManagementPermissionsReferencePath(realmId, clientId), &genericReference, nil)

if err != nil {
return nil, err
}

return genericReference.convertToOpenIdClientManagementPermissionsReference(realmId, clientId), nil
}

func (keycloakClient *KeycloakClient) CreateOpenIdClientManagementPermissionsReference(realmId, clientId string) error {
return keycloakClient.put(openIdClientManagementPermissionsReferencePath(realmId, clientId), enableClientManagementPermissionsReference())
}

func (keycloakClient *KeycloakClient) DeleteOpenIdClientManagementPermissionsReference(realmId, clientId string) error {
return keycloakClient.put(openIdClientManagementPermissionsReferencePath(realmId, clientId), disableClientManagementPermissionsReference())
}

func (keycloakClient *KeycloakClient) UpdateOpenIdClientManagementPermissionsReference(reference *OpenIdClientManagementPermissionsReference) error {
return keycloakClient.put(reference.openIdClientManagementPermissionsReferencePath(), reference.convertToGenericManagementPermissionsReference())
}
21 changes: 21 additions & 0 deletions provider/generic_management_permissions_reference_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package provider

import (
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func genericManagementPermissionsReferenceImport(data *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) {
parts := strings.Split(data.Id(), "/")
if len(parts) != 5 {
return nil, fmt.Errorf("Invalid import. Supported import format: {{realm}}/clients/{{client_id}}/management/permissions.")
}

data.SetId(data.Id())
data.Set("realm_id", parts[0])
data.Set("client_id", parts[2])

return []*schema.ResourceData{data}, nil
}
1 change: 1 addition & 0 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func KeycloakProvider() *schema.Provider {
"keycloak_openid_hardcoded_role_protocol_mapper": resourceKeycloakOpenIdHardcodedRoleProtocolMapper(),
"keycloak_openid_user_realm_role_protocol_mapper": resourceKeycloakOpenIdUserRealmRoleProtocolMapper(),
"keycloak_openid_client_default_scopes": resourceKeycloakOpenidClientDefaultScopes(),
"keycloak_openid_client_management_permissions_reference": resourceKeycloakOpenidClientManagementPermissionsReference(),
"keycloak_openid_client_optional_scopes": resourceKeycloakOpenidClientOptionalScopes(),
"keycloak_saml_client": resourceKeycloakSamlClient(),
"keycloak_generic_client_protocol_mapper": resourceKeycloakGenericClientProtocolMapper(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package provider

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/mrparkers/terraform-provider-keycloak/keycloak"
)

func resourceKeycloakOpenidClientManagementPermissionsReference() *schema.Resource {
return &schema.Resource{
Create: resourceKeycloakOpenIdClientManagementPermissionsReferenceCreate,
Read: resourceKeycloakOpenIdClientManagementPermissionsReferenceRead,
Delete: resourceKeycloakOpenIdClientManagementPermissionsReferenceDelete,
Update: resourceKeycloakOpenIdClientManagementPermissionsReferenceUpdate,
// This resource can be imported using {{realm}}/clients/{{client_id}}/management/permissions. The Client Id is displayed in the URL when editing it from the GUI.
Importer: &schema.ResourceImporter{
State: genericManagementPermissionsReferenceImport,
},
Schema: map[string]*schema.Schema{
"realm_id": {
Type: schema.TypeString,
Required: true,
},
"client_id": {
Type: schema.TypeString,
Required: true,
},
"resource": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"scope_permissions": {
Type: schema.TypeMap,
Optional: true,
Computed: true,
},
},
}
}

func openIdClientManagementReferenceId(realmId, clientId string) string {
return fmt.Sprintf("%s/%s", realmId, clientId)
}

func mapFromOpenIdClientManagementPermissionsReferenceToData(reference *keycloak.OpenIdClientManagementPermissionsReference, data *schema.ResourceData) {
data.Set("realm_id", reference.RealmId)
data.Set("client_id", reference.ClientId)
data.Set("resource", reference.Resource)
data.Set("scope_permissions", reference.ScopePermissions)
}

func resourceKeycloakOpenIdClientManagementPermissionsReferenceCreate(data *schema.ResourceData, meta interface{}) error {
keycloakClient := meta.(*keycloak.KeycloakClient)

realmId := data.Get("realm_id").(string)
clientId := data.Get("client_id").(string)

err := keycloakClient.CreateOpenIdClientManagementPermissionsReference(realmId, clientId)
if err != nil {
return err
}

return resourceKeycloakOpenIdClientManagementPermissionsReferenceRead(data, meta)
}

func resourceKeycloakOpenIdClientManagementPermissionsReferenceRead(data *schema.ResourceData, meta interface{}) error {
keycloakClient := meta.(*keycloak.KeycloakClient)

realmId := data.Get("realm_id").(string)
clientId := data.Get("client_id").(string)

data.SetId(openIdClientManagementReferenceId(realmId, clientId))

reference, err := keycloakClient.GetOpenIdClientManagementPermissionsReference(realmId, clientId)
if err != nil {
return handleNotFoundError(err, data)
}

mapFromOpenIdClientManagementPermissionsReferenceToData(reference, data)

return nil
}

func resourceKeycloakOpenIdClientManagementPermissionsReferenceUpdate(data *schema.ResourceData, meta interface{}) error {
return resourceKeycloakOpenIdClientManagementPermissionsReferenceRead(data, meta)
}

func resourceKeycloakOpenIdClientManagementPermissionsReferenceDelete(data *schema.ResourceData, meta interface{}) error {
keycloakClient := meta.(*keycloak.KeycloakClient)

realmId := data.Get("realm_id").(string)
clientId := data.Get("client_id").(string)

return keycloakClient.DeleteOpenIdClientManagementPermissionsReference(realmId, clientId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package provider

import (
"fmt"
"testing"

"github.com/mrparkers/terraform-provider-keycloak/keycloak"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccKeycloakOpenIdClientManagementPermissionsReference_basic(t *testing.T) {
realmName := "terraform-realm-" + acctest.RandString(10)
clientId := "terraform-client-" + acctest.RandString(10)

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
CheckDestroy: testKeycloakOpenIdClientManagementPermissionReferenceDestroy(),
Steps: []resource.TestStep{
{
Config: testKeycloakOpenIdClientManagementPermissionsReference(realmName, clientId),
Check: testKeycloakOpenIdClientManagementPermissionsReferenceExists("keycloak_openid_client_management_permissions_reference.management_permissions_reference"),
},
},
})
}

func testKeycloakOpenIdClientManagementPermissionsReference(realmId, clientId string) string {
return fmt.Sprintf(`
resource "keycloak_realm" "realm" {
realm = "%s"
}

resource "keycloak_openid_client" "client" {
client_id = "%s"
realm_id = "${keycloak_realm.realm.id}"

access_type = "PUBLIC"
}

resource "keycloak_openid_client_management_permissions_reference" "management_permissions_reference" {
realm_id = "${keycloak_realm.realm.id}"
client_id = "${keycloak_openid_client.client.id}"
}
`, realmId, clientId)
}

func getOpenIdClientManagementPermissionsReferenceUsingState(state *terraform.State, resourceName string) (*keycloak.OpenIdClientManagementPermissionsReference, error) {
rs, ok := state.RootModule().Resources[resourceName]
if !ok {
return nil, fmt.Errorf("resource not found in TF state: %s ", resourceName)
}

realmId := rs.Primary.Attributes["realm_id"]
clientId := rs.Primary.Attributes["client_id"]

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

return keycloakClient.GetOpenIdClientManagementPermissionsReference(realmId, clientId)
}

func testKeycloakOpenIdClientManagementPermissionsReferenceExists(resourceName string) resource.TestCheckFunc {
return func(state *terraform.State) error {
_, err := getOpenIdClientManagementPermissionsReferenceUsingState(state, resourceName)
if err != nil {
return err
}

return nil
}
}

func testKeycloakOpenIdClientManagementPermissionReferenceDestroy() resource.TestCheckFunc {
return func(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "keycloak_openid_client_management_permissions_reference" {
continue
}

id := rs.Primary.ID
realmId := rs.Primary.Attributes["realm_id"]
clientId := rs.Primary.Attributes["client_id"]

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

reference, _ := keycloakClient.GetOpenIdClientManagementPermissionsReference(realmId, clientId)
if reference != nil {
return fmt.Errorf("management permission reference with id %s still exists", id)
}
}

return nil
}
}