Skip to content

Commit f96ce80

Browse files
authored
feat: add owner groups to workspace data (#12841)
1 parent c4b26f3 commit f96ce80

File tree

16 files changed

+323
-130
lines changed

16 files changed

+323
-130
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ var (
174174
// When org scoped provisioner credentials are implemented,
175175
// this can be reduced to read a specific org.
176176
rbac.ResourceOrganization.Type: {rbac.ActionRead},
177+
rbac.ResourceGroup.Type: {rbac.ActionRead},
177178
}),
178179
Org: map[string][]rbac.Permission{},
179180
User: []rbac.Permission{},
@@ -1141,6 +1142,10 @@ func (q *querier) GetGroupMembers(ctx context.Context, id uuid.UUID) ([]database
11411142
return q.db.GetGroupMembers(ctx, id)
11421143
}
11431144

1145+
func (q *querier) GetGroupsByOrganizationAndUserID(ctx context.Context, arg database.GetGroupsByOrganizationAndUserIDParams) ([]database.Group, error) {
1146+
return fetchWithPostFilter(q.auth, q.db.GetGroupsByOrganizationAndUserID)(ctx, arg)
1147+
}
1148+
11441149
func (q *querier) GetGroupsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]database.Group, error) {
11451150
return fetchWithPostFilter(q.auth, q.db.GetGroupsByOrganizationID)(ctx, organizationID)
11461151
}

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,14 @@ func (s *MethodTestSuite) TestGroup() {
314314
_ = dbgen.GroupMember(s.T(), db, database.GroupMember{})
315315
check.Args(g.ID).Asserts(g, rbac.ActionRead)
316316
}))
317+
s.Run("GetGroupsByOrganizationAndUserID", s.Subtest(func(db database.Store, check *expects) {
318+
g := dbgen.Group(s.T(), db, database.Group{})
319+
gm := dbgen.GroupMember(s.T(), db, database.GroupMember{GroupID: g.ID})
320+
check.Args(database.GetGroupsByOrganizationAndUserIDParams{
321+
OrganizationID: g.OrganizationID,
322+
UserID: gm.UserID,
323+
}).Asserts(g, rbac.ActionRead)
324+
}))
317325
s.Run("InsertAllUsersGroup", s.Subtest(func(db database.Store, check *expects) {
318326
o := dbgen.Organization(s.T(), db, database.Organization{})
319327
check.Args(o.ID).Asserts(rbac.ResourceGroup.InOrg(o.ID), rbac.ActionCreate)

coderd/database/dbmem/dbmem.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,30 @@ func (q *FakeQuerier) GetGroupMembers(_ context.Context, id uuid.UUID) ([]databa
22502250
return users, nil
22512251
}
22522252

2253+
func (q *FakeQuerier) GetGroupsByOrganizationAndUserID(_ context.Context, arg database.GetGroupsByOrganizationAndUserIDParams) ([]database.Group, error) {
2254+
err := validateDatabaseType(arg)
2255+
if err != nil {
2256+
return nil, err
2257+
}
2258+
2259+
q.mutex.RLock()
2260+
defer q.mutex.RUnlock()
2261+
var groupIds []uuid.UUID
2262+
for _, member := range q.groupMembers {
2263+
if member.UserID == arg.UserID {
2264+
groupIds = append(groupIds, member.GroupID)
2265+
}
2266+
}
2267+
groups := []database.Group{}
2268+
for _, group := range q.groups {
2269+
if slices.Contains(groupIds, group.ID) && group.OrganizationID == arg.OrganizationID {
2270+
groups = append(groups, group)
2271+
}
2272+
}
2273+
2274+
return groups, nil
2275+
}
2276+
22532277
func (q *FakeQuerier) GetGroupsByOrganizationID(_ context.Context, id uuid.UUID) ([]database.Group, error) {
22542278
q.mutex.RLock()
22552279
defer q.mutex.RUnlock()

coderd/database/dbmetrics/dbmetrics.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/groups.sql

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,31 @@ FROM
2828
WHERE
2929
organization_id = $1;
3030

31+
-- name: GetGroupsByOrganizationAndUserID :many
32+
SELECT
33+
groups.*
34+
FROM
35+
groups
36+
-- If the group is a user made group, then we need to check the group_members table.
37+
LEFT JOIN
38+
group_members
39+
ON
40+
group_members.group_id = groups.id AND
41+
group_members.user_id = @user_id
42+
-- If it is the "Everyone" group, then we need to check the organization_members table.
43+
LEFT JOIN
44+
organization_members
45+
ON
46+
organization_members.organization_id = groups.id AND
47+
organization_members.user_id = @user_id
48+
WHERE
49+
-- In either case, the group_id will only match an org or a group.
50+
(group_members.user_id = @user_id OR organization_members.user_id = @user_id)
51+
AND
52+
-- Ensure the group or organization is the specified organization.
53+
groups.organization_id = @organization_id;
54+
55+
3156
-- name: InsertGroup :one
3257
INSERT INTO groups (
3358
id,

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,17 @@ func (s *server) acquireProtoJob(ctx context.Context, job database.ProvisionerJo
467467
if err != nil {
468468
return nil, failJob(fmt.Sprintf("get owner: %s", err))
469469
}
470+
ownerGroups, err := s.Database.GetGroupsByOrganizationAndUserID(ctx, database.GetGroupsByOrganizationAndUserIDParams{
471+
UserID: owner.ID,
472+
OrganizationID: s.OrganizationID,
473+
})
474+
if err != nil {
475+
return nil, failJob(fmt.Sprintf("get owner group names: %s", err))
476+
}
477+
ownerGroupNames := []string{}
478+
for _, group := range ownerGroups {
479+
ownerGroupNames = append(ownerGroupNames, group.Name)
480+
}
470481
err = s.Pubsub.Publish(codersdk.WorkspaceNotifyChannel(workspace.ID), []byte{})
471482
if err != nil {
472483
return nil, failJob(fmt.Sprintf("publish workspace update: %s", err))
@@ -567,6 +578,7 @@ func (s *server) acquireProtoJob(ctx context.Context, job database.ProvisionerJo
567578
WorkspaceOwner: owner.Username,
568579
WorkspaceOwnerEmail: owner.Email,
569580
WorkspaceOwnerName: owner.Name,
581+
WorkspaceOwnerGroups: ownerGroupNames,
570582
WorkspaceOwnerOidcAccessToken: workspaceOwnerOIDCAccessToken,
571583
WorkspaceId: workspace.ID.String(),
572584
WorkspaceOwnerId: owner.ID.String(),

coderd/provisionerdserver/provisionerdserver_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,15 @@ func TestAcquireJob(t *testing.T) {
182182
defer cancel()
183183

184184
user := dbgen.User(t, db, database.User{})
185+
group1 := dbgen.Group(t, db, database.Group{
186+
Name: "group1",
187+
OrganizationID: pd.OrganizationID,
188+
})
189+
err := db.InsertGroupMember(ctx, database.InsertGroupMemberParams{
190+
UserID: user.ID,
191+
GroupID: group1.ID,
192+
})
193+
require.NoError(t, err)
185194
link := dbgen.UserLink(t, db, database.UserLink{
186195
LoginType: database.LoginTypeOIDC,
187196
UserID: user.ID,
@@ -340,6 +349,7 @@ func TestAcquireJob(t *testing.T) {
340349
WorkspaceOwnerEmail: user.Email,
341350
WorkspaceOwnerName: user.Name,
342351
WorkspaceOwnerOidcAccessToken: link.OAuthAccessToken,
352+
WorkspaceOwnerGroups: []string{group1.Name},
343353
WorkspaceId: workspace.ID.String(),
344354
WorkspaceOwnerId: user.ID.String(),
345355
TemplateId: template.ID.String(),

0 commit comments

Comments
 (0)