Skip to content

Commit 2ec9bb3

Browse files
tricktronchmouel
authored andcommitted
fix: nil-guard bug and add group ACL tests for BBC
The 4 Mux permission helpers wrote double responses when input was nil due to missing returns. Extract shared muxPermissions helper and add test coverage for project/repo group-based access.
1 parent cc6aa3b commit 2ec9bb3

File tree

3 files changed

+98
-35
lines changed

3 files changed

+98
-35
lines changed

pkg/provider/bitbucketdatacenter/acl_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func TestIsAllowed(t *testing.T) {
3636
repoMembers []*bbv1test.UserPermission
3737
projGroups []*bbv1test.ProjGroup
3838
repoGroups []*bbv1test.ProjGroup
39+
groupMembers map[string][]bbv1test.GroupMember
3940
activities []*bbv1test.Activity
4041
filescontents map[string]string
4142
defaultBranchLatestCommit string
@@ -138,6 +139,69 @@ func TestIsAllowed(t *testing.T) {
138139
},
139140
isAllowed: false,
140141
},
142+
{
143+
name: "allowed/user is in project group",
144+
event: bbv1test.MakeEvent(&info.Event{Sender: "sender", AccountID: fmt.Sprintf("%d", otherAccountID)}),
145+
fields: fields{
146+
projGroups: []*bbv1test.ProjGroup{
147+
{
148+
Group: bbv1test.Group{Name: "project-devs"},
149+
Permission: "PROJECT_WRITE",
150+
},
151+
},
152+
groupMembers: map[string][]bbv1test.GroupMember{
153+
"project-devs": {
154+
{Name: "sender", Slug: "sender"},
155+
},
156+
},
157+
},
158+
isAllowed: true,
159+
},
160+
{
161+
name: "allowed/user is in repo group",
162+
event: bbv1test.MakeEvent(&info.Event{Sender: "sender", AccountID: fmt.Sprintf("%d", otherAccountID)}),
163+
fields: fields{
164+
repoGroups: []*bbv1test.ProjGroup{
165+
{
166+
Group: bbv1test.Group{Name: "repo-devs"},
167+
Permission: "REPO_WRITE",
168+
},
169+
},
170+
groupMembers: map[string][]bbv1test.GroupMember{
171+
"repo-devs": {
172+
{Name: "sender", Slug: "sender"},
173+
},
174+
},
175+
},
176+
isAllowed: true,
177+
},
178+
{
179+
name: "disallowed/user not in any group members",
180+
event: bbv1test.MakeEvent(&info.Event{Sender: "outsider", AccountID: fmt.Sprintf("%d", otherAccountID)}),
181+
fields: fields{
182+
projGroups: []*bbv1test.ProjGroup{
183+
{
184+
Group: bbv1test.Group{Name: "project-devs"},
185+
Permission: "PROJECT_WRITE",
186+
},
187+
},
188+
repoGroups: []*bbv1test.ProjGroup{
189+
{
190+
Group: bbv1test.Group{Name: "repo-devs"},
191+
Permission: "REPO_WRITE",
192+
},
193+
},
194+
groupMembers: map[string][]bbv1test.GroupMember{
195+
"project-devs": {
196+
{Name: "someone-else", Slug: "someone-else"},
197+
},
198+
"repo-devs": {
199+
{Name: "another-person", Slug: "another-person"},
200+
},
201+
},
202+
},
203+
isAllowed: false,
204+
},
141205
{
142206
name: "disallowed/same nickname different account id",
143207
event: bbv1test.MakeEvent(&info.Event{Sender: "Bouffon", AccountID: "6666"}),
@@ -215,6 +279,7 @@ func TestIsAllowed(t *testing.T) {
215279
bbv1test.MuxRepoMemberShip(t, mux, tt.event, tt.fields.repoMembers)
216280
bbv1test.MuxProjectGroupMembership(t, mux, tt.event, tt.fields.projGroups)
217281
bbv1test.MuxRepoGroupMembership(t, mux, tt.event, tt.fields.repoGroups)
282+
bbv1test.MuxGroupMembers(t, mux, tt.fields.groupMembers)
218283
bbv1test.MuxPullRequestActivities(t, mux, tt.event, tt.fields.pullRequestNumber, tt.fields.activities)
219284
bbv1test.MuxFiles(t, mux, tt.event, tt.fields.defaultBranchLatestCommit, "", tt.fields.filescontents, false)
220285

pkg/provider/bitbucketdatacenter/test/test.go

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -218,62 +218,53 @@ func MuxCreateAndTestCommitStatus(t *testing.T, mux *http.ServeMux, event *info.
218218
})
219219
}
220220

221-
func MuxProjectMemberShip(t *testing.T, mux *http.ServeMux, event *info.Event, userperms []*UserPermission) {
222-
path := fmt.Sprintf("/projects/%s/permissions/users", event.Organization)
221+
func muxPermissions(t *testing.T, mux *http.ServeMux, path string, values any) {
222+
t.Helper()
223223
mux.HandleFunc(path, func(rw http.ResponseWriter, _ *http.Request) {
224-
if userperms == nil {
225-
fmt.Fprintf(rw, "{\"values\": []}")
226-
}
227224
resp := map[string]any{
228-
"values": userperms,
225+
"values": values,
226+
"isLastPage": true,
229227
}
230228
b, err := json.Marshal(resp)
231229
assert.NilError(t, err)
232-
233230
fmt.Fprint(rw, string(b))
234231
})
235232
}
236233

234+
func MuxProjectMemberShip(t *testing.T, mux *http.ServeMux, event *info.Event, userperms []*UserPermission) {
235+
path := fmt.Sprintf("/projects/%s/permissions/users", event.Organization)
236+
muxPermissions(t, mux, path, userperms)
237+
}
238+
237239
func MuxProjectGroupMembership(t *testing.T, mux *http.ServeMux, event *info.Event, groups []*ProjGroup) {
238240
path := fmt.Sprintf("/projects/%s/permissions/groups", event.Organization)
239-
mux.HandleFunc(path, func(rw http.ResponseWriter, _ *http.Request) {
240-
if groups == nil {
241-
fmt.Fprintf(rw, "{\"values\": []}")
242-
}
243-
resp := map[string]any{
244-
"values": groups,
245-
}
246-
b, err := json.Marshal(resp)
247-
assert.NilError(t, err)
248-
249-
fmt.Fprint(rw, string(b))
250-
})
241+
muxPermissions(t, mux, path, groups)
251242
}
252243

253244
func MuxRepoGroupMembership(t *testing.T, mux *http.ServeMux, event *info.Event, groups []*ProjGroup) {
254245
path := fmt.Sprintf("/projects/%s/repos/%s/permissions/groups", event.Organization, event.Repository)
255-
mux.HandleFunc(path, func(rw http.ResponseWriter, _ *http.Request) {
256-
if groups == nil {
257-
fmt.Fprintf(rw, "{\"values\": []}")
258-
}
259-
resp := map[string]any{
260-
"values": groups,
261-
}
262-
b, err := json.Marshal(resp)
263-
assert.NilError(t, err)
264-
265-
fmt.Fprint(rw, string(b))
266-
})
246+
muxPermissions(t, mux, path, groups)
267247
}
268248

269249
func MuxRepoMemberShip(t *testing.T, mux *http.ServeMux, event *info.Event, userperms []*UserPermission) {
270250
path := fmt.Sprintf("/projects/%s/repos/%s/permissions/users", event.Organization, event.Repository)
271-
mux.HandleFunc(path, func(rw http.ResponseWriter, _ *http.Request) {
272-
if userperms == nil {
273-
fmt.Fprintf(rw, "{\"values\": []}")
251+
muxPermissions(t, mux, path, userperms)
252+
}
253+
254+
// MuxGroupMembers mocks the /admin/groups/more-members endpoint used by go-scm
255+
// to resolve group names to individual users. groupMembers maps group name to
256+
// the list of members in that group.
257+
func MuxGroupMembers(t *testing.T, mux *http.ServeMux, groupMembers map[string][]GroupMember) {
258+
t.Helper()
259+
mux.HandleFunc("/admin/groups/more-members", func(rw http.ResponseWriter, r *http.Request) {
260+
groupName := r.URL.Query().Get("context")
261+
members, ok := groupMembers[groupName]
262+
if !ok {
263+
members = []GroupMember{}
274264
}
275265
resp := map[string]any{
276-
"values": userperms,
266+
"values": members,
267+
"isLastPage": true,
277268
}
278269
b, err := json.Marshal(resp)
279270
assert.NilError(t, err)

pkg/provider/bitbucketdatacenter/test/test_types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ type Group struct {
3434
Name string `json:"name"`
3535
}
3636

37+
// GroupMember matches the member struct in go-scm's stash driver,
38+
// returned by the /admin/groups/more-members endpoint.
39+
type GroupMember struct {
40+
Name string `json:"name"`
41+
Slug string `json:"slug"`
42+
}
43+
3744
// kept these structs here because these are only used in tests
3845

3946
type Comment struct {

0 commit comments

Comments
 (0)