Repository: Nerzal/gocloak
Pull request #197 (2020-08-06 21:28:41)

Adding GetAvailableClientRolesByGroupID method




Patch:
diff --git a/README.md b/README.md
index 92a479d..51dd6a3 100644
--- a/README.md
+++ b/README.md
@@ -220,6 +220,7 @@ type GoCloak interface {
 	GetCompositeClientRolesByUserID(ctx context.Context, token, realm, clientID, userID string) ([]*Role, error)
 	GetCompositeClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error)
 	GetAvailableClientRolesByUserID(ctx context.Context, token, realm, clientID, userID string) ([]*Role, error)
+	GetAvailableClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error)
 
 	// *** Realm ***
 
diff --git a/client.go b/client.go
index 3840960..6576bce 100644
--- a/client.go
+++ b/client.go
@@ -1241,6 +1241,22 @@ func (client *gocloak) GetAvailableClientRolesByUserID(ctx context.Context, toke
 	return result, nil
 }
 
+// GetAvailableClientRolesByGroupID returns all available roles to the given group
+func (client *gocloak) GetAvailableClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error) {
+	const errMessage = "could not get available client roles by user id"
+
+	var result []*Role
+	resp, err := client.getRequestWithBearerAuth(ctx, token).
+		SetResult(&result).
+		Get(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "clients", clientID, "available"))
+
+	if err = checkForError(resp, err, errMessage); err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
 // GetCompositeClientRolesByGroupID returns all client roles and composite roles assigned to the given group
 func (client *gocloak) GetCompositeClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error) {
 	const errMessage = "could not get composite client roles by group id"
diff --git a/gocloak.go b/gocloak.go
index 0da5cc9..23a983c 100644
--- a/gocloak.go
+++ b/gocloak.go
@@ -208,6 +208,8 @@ type GoCloak interface {
 	GetCompositeClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error)
 	// GetAvailableClientRolesByUserID returns all available roles to the given user
 	GetAvailableClientRolesByUserID(ctx context.Context, token, realm, clientID, userID string) ([]*Role, error)
+	// GetAvailableClientRolesByGroupID returns all available roles to the given group
+	GetAvailableClientRolesByGroupID(ctx context.Context, token, realm, clientID, groupID string) ([]*Role, error)
 
 	// GetClientRole get a role for the given client in a realm by role name
 	GetClientRole(ctx context.Context, token, realm, clientID, roleName string) (*Role, error)


Test patch:
diff --git a/client_test.go b/client_test.go
index 53c7fb3..96e3f30 100644
--- a/client_test.go
+++ b/client_test.go
@@ -3024,6 +3024,84 @@ func TestGoCloak_GetAvailableClientRolesByUserID(t *testing.T) {
 	require.Fail(t, "The role2 has not been found in the assigned composite roles. Role: %+v", *role2)
 }
 
+func TestGoCloak_GetAvailableClientRolesByGroupID(t *testing.T) {
+	t.Parallel()
+	cfg := GetConfig(t)
+	client := NewClientWithDebug(t)
+	token := GetAdminToken(t, client)
+
+	tearDownGroup, groupID := CreateGroup(t, client)
+	defer tearDownGroup()
+	tearDownRole, roleName1 := CreateClientRole(t, client)
+	defer tearDownRole()
+	tearDownRole2, roleName2 := CreateClientRole(t, client)
+	defer tearDownRole2()
+
+	role1, err := client.GetClientRole(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		roleName1)
+	require.NoError(t, err)
+
+	role2, err := client.GetClientRole(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		roleName2)
+	require.NoError(t, err)
+
+	err = client.AddClientRoleToGroup(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		groupID,
+		[]gocloak.Role{*role1},
+	)
+	require.NoError(t, err)
+
+	roles, err := client.GetClientRolesByGroupID(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		groupID)
+	require.NoError(t, err)
+	t.Logf("Group roles: %+v", roles)
+	var found bool
+	for _, r := range roles {
+		if r.Name == nil {
+			continue
+		}
+		if *r.Name == *role1.Name {
+			found = true
+			break
+		}
+	}
+	require.True(t, found, "The role1 has not been found in the assigned roles. Role: %+v", *role1)
+
+	roles, err = client.GetAvailableClientRolesByGroupID(
+		context.Background(),
+		token.AccessToken,
+		cfg.GoCloak.Realm,
+		gocloakClientID,
+		groupID)
+	require.NoError(t, err)
+	t.Logf("Group roles: %+v", roles)
+	for _, r := range roles {
+		if r.Name == nil {
+			continue
+		}
+		if *r.Name == *role2.Name {
+			return
+		}
+	}
+	require.Fail(t, "The role2 has not been found in the assigned composite roles. Role: %+v", *role2)
+}
+
 func TestGocloak_GetClientRolesByGroupID(t *testing.T) {
 	t.Parallel()
 	cfg := GetConfig(t)