Repository: Nerzal/gocloak
Pull request #225 (2020-11-05 13:04:46)

APIs to fetch resource and scopes associated with permission
APIs to fetch following -
1. GetDepdendentPermissions(...,policyID) - fetches permissions dependent on given policy ID
2. GetPermissionResources(...,permissionID) - fetches resources associated with permission ID
3. GetPermissionScopes(...,permissionID) - fetches scopes associated with permission ID



Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index facc51d..cd7ade2 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -19,7 +19,7 @@ jobs:
       - name: WriteGoList
         run: go list -json -m all > go.list
       - name: nancy
-        uses: sonatype-nexus-community/nancy-github-action@master
+        uses: sonatype-nexus-community/nancy-github-action@main
       - name: Run Keycloak
         run: |
           docker pull jboss/keycloak:latest
diff --git a/client.go b/client.go
index 2ea6067..1a2db02 100644
--- a/client.go
+++ b/client.go
@@ -2539,6 +2539,54 @@ func (client *gocloak) GetPermission(ctx context.Context, token, realm, clientID
 	return &result, nil
 }
 
+// GetDependentPermissions returns a client's permission with the given policy id
+func (client *gocloak) GetDependentPermissions(ctx context.Context, token, realm, clientID, policyID string) ([]*PermissionRepresentation, error) {
+	const errMessage = "could not get permission"
+
+	var result []*PermissionRepresentation
+	resp, err := client.getRequestWithBearerAuth(ctx, token).
+		SetResult(&result).
+		Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "policy", policyID, "dependentPolicies"))
+
+	if err := checkForError(resp, err, errMessage); err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
+// GetPermissionResource returns a client's resource attached for the given permission id
+func (client *gocloak) GetPermissionResources(ctx context.Context, token, realm, clientID, permissionID string) ([]*PermissionResource, error) {
+	const errMessage = "could not get permission resource"
+
+	var result []*PermissionResource
+	resp, err := client.getRequestWithBearerAuth(ctx, token).
+		SetResult(&result).
+		Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "permission", permissionID, "resources"))
+
+	if err := checkForError(resp, err, errMessage); err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
+// GetPermissionScopes returns a client's scopes configured for the given permission id
+func (client *gocloak) GetPermissionScopes(ctx context.Context, token, realm, clientID, permissionID string) ([]*PermissionScope, error) {
+	const errMessage = "could not get permission scopes"
+
+	var result []*PermissionScope
+	resp, err := client.getRequestWithBearerAuth(ctx, token).
+		SetResult(&result).
+		Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "permission", permissionID, "scopes"))
+
+	if err := checkForError(resp, err, errMessage); err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
 // GetPermissions returns permissions associated with the client
 func (client *gocloak) GetPermissions(ctx context.Context, token, realm, clientID string, params GetPermissionParams) ([]*PermissionRepresentation, error) {
 	const errMessage = "could not get permissions"
diff --git a/gocloak.go b/gocloak.go
index 3a9dafb..48c5428 100644
--- a/gocloak.go
+++ b/gocloak.go
@@ -359,7 +359,10 @@ type GoCloak interface {
 	UpdatePermission(ctx context.Context, token, realm, clientID string, permission PermissionRepresentation) error
 	// DeletePermission deletes a permission associated with the client
 	DeletePermission(ctx context.Context, token, realm, clientID, permissionID string) error
-
+	// GetDependentPermissions returns client's permissions dependent on the policy with given ID
+	GetDependentPermissions(ctx context.Context, token, realm, clientID, policyID string) ([]*PermissionRepresentation, error)
+	GetPermissionResources(ctx context.Context, token, realm, clientID, permissionID string) ([]*PermissionResource, error)
+	GetPermissionScopes(ctx context.Context, token, realm, clientID, permissionID string) ([]*PermissionScope, error)
 	// ---------------
 	// Credentials API
 	// ---------------
diff --git a/models.go b/models.go
index 4697a43..5829e3c 100644
--- a/models.go
+++ b/models.go
@@ -109,6 +109,18 @@ type ResourcePermission struct {
 	ResourceScopes *[]string `json:"resource_scopes,omitempty"`
 }
 
+// PermissionResource represents a resources asscoiated with a permission
+type PermissionResource struct {
+	ResourceID   *string `json:"_id,omitempty"`
+	ResourceName *string `json:"name,omitempty"`
+}
+
+// PermissionScope represents scopes associated with a permission
+type PermissionScope struct {
+	ScopeID   *string `json:"id,omitempty"`
+	ScopeName *string `json:"name,omitempty"`
+}
+
 // RetrospecTokenResult is returned when a token was checked
 type RetrospecTokenResult struct {
 	Permissions *[]ResourcePermission `json:"permissions,omitempty"`


Test patch:
diff --git a/client_test.go b/client_test.go
index 578db4b..daf27b1 100644
--- a/client_test.go
+++ b/client_test.go
@@ -4536,6 +4536,42 @@ func TestGocloak_CreateListGetUpdateDeletePermission(t *testing.T) {
 	)
 	require.NoError(t, err, "GetPermission failed")
 	require.Equal(t, *(createdPermission.Name), *(updatedPermission.Name))
+
+	dependentPermissions, err := client.GetDependentPermissions(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		policyID,
+	)
+
+	require.NoError(t, err, "GetDependentPermissions failed")
+	require.Len(t, dependentPermissions, 1, "GetDependentPermissions should return exact 1 permission")
+	require.Equal(t, *(createdPermission.Name), *(dependentPermissions[0].Name))
+
+	permissionResources, err := client.GetPermissionResources(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		permissionID,
+	)
+
+	require.NoError(t, err, "GetPermissionResource failed")
+	require.Len(t, permissionResources, 1, "GetPermissionResource should return exact 1 resource")
+	require.Equal(t, resourceID, *permissionResources[0].ResourceID)
+
+	permissionScopes, err := client.GetPermissionScopes(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		permissionID,
+	)
+
+	require.NoError(t, err, "GetPermissionScopes failed")
+	require.Len(t, permissionScopes, 0, "GetPermissionResource should return exact 0 scopes")
+
 }
 
 func TestGoCloak_CheckError(t *testing.T) {