Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c330af0

Browse files
authored
chore: add group_ids filter to /groups endpoint (#14688)
Allow filtering groups by IDs.
1 parent 5ed065d commit c330af0

File tree

10 files changed

+99
-9
lines changed

10 files changed

+99
-9
lines changed

coderd/apidoc/docs.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmem/dbmem.go

+6
Original file line numberDiff line numberDiff line change
@@ -2714,6 +2714,12 @@ func (q *FakeQuerier) GetGroups(_ context.Context, arg database.GetGroupsParams)
27142714
orgDetailsCache := make(map[uuid.UUID]struct{ name, displayName string })
27152715
filtered := make([]database.GetGroupsRow, 0)
27162716
for _, group := range q.groups {
2717+
if len(arg.GroupIds) > 0 {
2718+
if !slices.Contains(arg.GroupIds, group.ID) {
2719+
continue
2720+
}
2721+
}
2722+
27172723
if arg.OrganizationID != uuid.Nil && group.OrganizationID != arg.OrganizationID {
27182724
continue
27192725
}

coderd/database/queries.sql.go

+14-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/groups.sql

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ WHERE
5656
groups.name = ANY(@group_names)
5757
ELSE true
5858
END
59+
AND CASE WHEN array_length(@group_ids :: uuid[], 1) > 0 THEN
60+
groups.id = ANY(@group_ids)
61+
ELSE true
62+
END
5963
;
6064

6165
-- name: InsertGroup :one

codersdk/groups.go

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"net/http"
88
"net/url"
9+
"strings"
910

1011
"github.com/google/uuid"
1112
"golang.org/x/xerrors"
@@ -74,6 +75,9 @@ type GroupArguments struct {
7475
Organization string
7576
// HasMember can be a user uuid or username
7677
HasMember string
78+
// GroupIDs is a list of group UUIDs to filter by.
79+
// If not set, all groups will be returned.
80+
GroupIDs []uuid.UUID
7781
}
7882

7983
func (c *Client) Groups(ctx context.Context, args GroupArguments) ([]Group, error) {
@@ -84,6 +88,13 @@ func (c *Client) Groups(ctx context.Context, args GroupArguments) ([]Group, erro
8488
if args.HasMember != "" {
8589
qp.Set("has_member", args.HasMember)
8690
}
91+
if len(args.GroupIDs) > 0 {
92+
idStrs := make([]string, 0, len(args.GroupIDs))
93+
for _, id := range args.GroupIDs {
94+
idStrs = append(idStrs, id.String())
95+
}
96+
qp.Set("group_ids", strings.Join(idStrs, ","))
97+
}
8798

8899
res, err := c.Request(ctx, http.MethodGet,
89100
fmt.Sprintf("/api/v2/groups?%s", qp.Encode()),

docs/reference/api/enterprise.md

+6-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enterprise/coderd/groups.go

+4
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ func (api *API) groupsByOrganization(rw http.ResponseWriter, r *http.Request) {
430430
// @Tags Enterprise
431431
// @Param organization query string true "Organization ID or name"
432432
// @Param has_member query string true "User ID or name"
433+
// @Param group_ids query string true "Comma separated list of group IDs"
433434
// @Success 200 {array} codersdk.Group
434435
// @Router /groups [get]
435436
func (api *API) groups(rw http.ResponseWriter, r *http.Request) {
@@ -457,6 +458,9 @@ func (api *API) groups(rw http.ResponseWriter, r *http.Request) {
457458
}
458459
return user.ID, nil
459460
})
461+
462+
filter.GroupIds = parser.UUIDs(r.URL.Query(), []uuid.UUID{}, "group_ids")
463+
460464
parser.ErrorExcessParams(r.URL.Query())
461465
if len(parser.Errors) > 0 {
462466
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{

enterprise/coderd/groups_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,45 @@ func TestGroup(t *testing.T) {
779779
require.Contains(t, group.Members, user2.ReducedUser)
780780
})
781781

782+
t.Run("ByIDs", func(t *testing.T) {
783+
t.Parallel()
784+
785+
client, user := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{
786+
Features: license.Features{
787+
codersdk.FeatureTemplateRBAC: 1,
788+
},
789+
}})
790+
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
791+
792+
ctx := testutil.Context(t, testutil.WaitLong)
793+
groupA, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
794+
Name: "group-a",
795+
})
796+
require.NoError(t, err)
797+
798+
groupB, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
799+
Name: "group-b",
800+
})
801+
require.NoError(t, err)
802+
803+
// group-c should be omitted from the filter
804+
_, err = userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
805+
Name: "group-c",
806+
})
807+
require.NoError(t, err)
808+
809+
found, err := userAdminClient.Groups(ctx, codersdk.GroupArguments{
810+
GroupIDs: []uuid.UUID{groupA.ID, groupB.ID},
811+
})
812+
require.NoError(t, err)
813+
814+
foundIDs := db2sdk.List(found, func(g codersdk.Group) uuid.UUID {
815+
return g.ID
816+
})
817+
818+
require.ElementsMatch(t, []uuid.UUID{groupA.ID, groupB.ID}, foundIDs)
819+
})
820+
782821
t.Run("everyoneGroupReturnsEmpty", func(t *testing.T) {
783822
t.Parallel()
784823

site/src/api/typesGenerated.ts

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)