Skip to content

Commit 8af8c77

Browse files
Emyrkjohnstcn
andauthored
test: add unit test to verify group permission behavior (#14223)
* test: add unit test to verify group permission behavior * Update coderd/database/dbauthz/groupsauth_test.go --------- Co-authored-by: Cian Johnston <cian@coder.com>
1 parent 0338250 commit 8af8c77

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package dbauthz_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/google/uuid"
8+
"github.com/prometheus/client_golang/prometheus"
9+
"github.com/stretchr/testify/require"
10+
11+
"cdr.dev/slog/sloggers/slogtest"
12+
"github.com/coder/coder/v2/coderd/coderdtest"
13+
"github.com/coder/coder/v2/coderd/database"
14+
"github.com/coder/coder/v2/coderd/database/dbauthz"
15+
"github.com/coder/coder/v2/coderd/database/dbgen"
16+
"github.com/coder/coder/v2/coderd/database/dbmem"
17+
"github.com/coder/coder/v2/coderd/database/dbtestutil"
18+
"github.com/coder/coder/v2/coderd/rbac"
19+
)
20+
21+
// nolint:tparallel
22+
func TestGroupsAuth(t *testing.T) {
23+
t.Parallel()
24+
25+
if dbtestutil.WillUsePostgres() {
26+
t.Skip("this test would take too long to run on postgres")
27+
}
28+
29+
authz := rbac.NewAuthorizer(prometheus.NewRegistry())
30+
31+
db := dbauthz.New(dbmem.New(), authz, slogtest.Make(t, &slogtest.Options{
32+
IgnoreErrors: true,
33+
}), coderdtest.AccessControlStorePointer())
34+
35+
ownerCtx := dbauthz.As(context.Background(), rbac.Subject{
36+
ID: "owner",
37+
Roles: rbac.Roles(must(rbac.RoleIdentifiers{rbac.RoleOwner()}.Expand())),
38+
Groups: []string{},
39+
Scope: rbac.ExpandableScope(rbac.ScopeAll),
40+
})
41+
42+
org := dbgen.Organization(t, db, database.Organization{})
43+
group := dbgen.Group(t, db, database.Group{
44+
OrganizationID: org.ID,
45+
})
46+
47+
var users []database.User
48+
for i := 0; i < 5; i++ {
49+
user := dbgen.User(t, db, database.User{})
50+
users = append(users, user)
51+
err := db.InsertGroupMember(ownerCtx, database.InsertGroupMemberParams{
52+
UserID: user.ID,
53+
GroupID: group.ID,
54+
})
55+
require.NoError(t, err)
56+
}
57+
58+
totalMembers := len(users)
59+
testCases := []struct {
60+
Name string
61+
Subject rbac.Subject
62+
ReadGroup bool
63+
ReadMembers bool
64+
MembersExpected int
65+
}{
66+
{
67+
Name: "Owner",
68+
Subject: rbac.Subject{
69+
ID: "owner",
70+
Roles: rbac.Roles(must(rbac.RoleIdentifiers{rbac.RoleOwner()}.Expand())),
71+
Groups: []string{},
72+
Scope: rbac.ExpandableScope(rbac.ScopeAll),
73+
},
74+
ReadGroup: true,
75+
ReadMembers: true,
76+
MembersExpected: totalMembers,
77+
},
78+
{
79+
Name: "UserAdmin",
80+
Subject: rbac.Subject{
81+
ID: "useradmin",
82+
Roles: rbac.Roles(must(rbac.RoleIdentifiers{rbac.RoleUserAdmin()}.Expand())),
83+
Groups: []string{},
84+
Scope: rbac.ExpandableScope(rbac.ScopeAll),
85+
},
86+
ReadGroup: true,
87+
ReadMembers: true,
88+
MembersExpected: totalMembers,
89+
},
90+
{
91+
Name: "OrgAdmin",
92+
Subject: rbac.Subject{
93+
ID: "orgadmin",
94+
Roles: rbac.Roles(must(rbac.RoleIdentifiers{rbac.ScopedRoleOrgAdmin(org.ID)}.Expand())),
95+
Groups: []string{},
96+
Scope: rbac.ExpandableScope(rbac.ScopeAll),
97+
},
98+
ReadGroup: true,
99+
ReadMembers: true,
100+
MembersExpected: totalMembers,
101+
},
102+
{
103+
Name: "OrgUserAdmin",
104+
Subject: rbac.Subject{
105+
ID: "orgUserAdmin",
106+
Roles: rbac.Roles(must(rbac.RoleIdentifiers{rbac.ScopedRoleOrgUserAdmin(org.ID)}.Expand())),
107+
Groups: []string{},
108+
Scope: rbac.ExpandableScope(rbac.ScopeAll),
109+
},
110+
ReadGroup: true,
111+
ReadMembers: true,
112+
MembersExpected: totalMembers,
113+
},
114+
{
115+
Name: "GroupMember",
116+
Subject: rbac.Subject{
117+
ID: users[0].ID.String(),
118+
Roles: rbac.Roles(must(rbac.RoleIdentifiers{rbac.ScopedRoleOrgMember(org.ID)}.Expand())),
119+
Groups: []string{
120+
group.Name,
121+
},
122+
Scope: rbac.ExpandableScope(rbac.ScopeAll),
123+
},
124+
// TODO: currently group members cannot see their own groups.
125+
// If this is fixed, these booleans should be flipped to true.
126+
ReadGroup: false,
127+
ReadMembers: false,
128+
// TODO: If fixed, they should only be able to see themselves
129+
// MembersExpected: 1,
130+
},
131+
{
132+
// Org admin in the incorrect organization
133+
Name: "DifferentOrgAdmin",
134+
Subject: rbac.Subject{
135+
ID: "orgadmin",
136+
Roles: rbac.Roles(must(rbac.RoleIdentifiers{rbac.ScopedRoleOrgUserAdmin(uuid.New())}.Expand())),
137+
Groups: []string{},
138+
Scope: rbac.ExpandableScope(rbac.ScopeAll),
139+
},
140+
ReadGroup: false,
141+
ReadMembers: false,
142+
},
143+
}
144+
145+
for _, tc := range testCases {
146+
tc := tc
147+
t.Run(tc.Name, func(t *testing.T) {
148+
t.Parallel()
149+
150+
actorCtx := dbauthz.As(context.Background(), tc.Subject)
151+
_, err := db.GetGroupByID(actorCtx, group.ID)
152+
if tc.ReadGroup {
153+
require.NoError(t, err, "group read")
154+
} else {
155+
require.Error(t, err, "group read")
156+
}
157+
158+
members, err := db.GetGroupMembersByGroupID(actorCtx, group.ID)
159+
if tc.ReadMembers {
160+
require.NoError(t, err, "member read")
161+
require.Len(t, members, tc.MembersExpected, "member count found does not match")
162+
} else {
163+
require.Error(t, err, "member read")
164+
require.True(t, dbauthz.IsNotAuthorizedError(err), "not authorized error")
165+
}
166+
})
167+
}
168+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy