Skip to content

Commit a42e77c

Browse files
committed
test: add unit test to verify group permission behavior
1 parent aaa5174 commit a42e77c

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package dbauthz_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/prometheus/client_golang/prometheus"
8+
"github.com/stretchr/testify/require"
9+
10+
"cdr.dev/slog/sloggers/slogtest"
11+
"github.com/coder/coder/v2/coderd/coderdtest"
12+
"github.com/coder/coder/v2/coderd/database"
13+
"github.com/coder/coder/v2/coderd/database/dbauthz"
14+
"github.com/coder/coder/v2/coderd/database/dbgen"
15+
"github.com/coder/coder/v2/coderd/database/dbmem"
16+
"github.com/coder/coder/v2/coderd/database/dbtestutil"
17+
"github.com/coder/coder/v2/coderd/rbac"
18+
)
19+
20+
// nolint:tparallel
21+
func TestGroupsAuth(t *testing.T) {
22+
t.Parallel()
23+
24+
if dbtestutil.WillUsePostgres() {
25+
t.Skip("this test would take too long to run on postgres")
26+
}
27+
28+
authz := rbac.NewAuthorizer(prometheus.NewRegistry())
29+
30+
db := dbmem.New()
31+
db = dbauthz.New(db, 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{}.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+
}
165+
})
166+
}
167+
}

0 commit comments

Comments
 (0)