diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index a76563496cd..50135c0d7a6 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1719,7 +1719,7 @@ func Routes() *web.Router { m.Get("", reqToken(), org.ListMembers) m.Combo("/{username}").Get(reqToken(), org.IsMember). Delete(reqToken(), reqOrgOwnership(), org.DeleteMember) - }) + }, reqOrgVisible()) addActionsRoutes( m, reqOrgMembership(), @@ -1731,7 +1731,7 @@ func Routes() *web.Router { m.Combo("/{username}").Get(org.IsPublicMember). Put(reqToken(), reqOrgMembership(), org.PublicizeMember). Delete(reqToken(), reqOrgMembership(), org.ConcealMember) - }) + }, reqOrgVisible()) m.Group("/teams", func() { m.Get("", org.ListTeams) m.Post("", reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam) diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go index ce7f227af6f..11b46a05c1c 100644 --- a/routers/api/v1/org/member.go +++ b/routers/api/v1/org/member.go @@ -119,12 +119,6 @@ func ListPublicMembers(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - // don't disclose membership of organizations the doer cannot see - if !organization.HasOrgOrUserVisible(ctx, ctx.Org.Organization.AsUser(), ctx.Doer) { - ctx.APIErrorNotFound() - return - } - listMembers(ctx, false) } @@ -207,11 +201,6 @@ func IsPublicMember(ctx *context.APIContext) { if ctx.Written() { return } - // don't disclose membership of organizations the doer cannot see - if !organization.HasOrgOrUserVisible(ctx, ctx.Org.Organization.AsUser(), ctx.Doer) { - ctx.APIErrorNotFound() - return - } is, err := organization.IsPublicMembership(ctx, ctx.Org.Organization.ID, userToCheck.ID) if err != nil { ctx.APIErrorInternal(err) diff --git a/tests/integration/api_org_test.go b/tests/integration/api_org_test.go index 1702eb116e5..f0250c5d5a5 100644 --- a/tests/integration/api_org_test.go +++ b/tests/integration/api_org_test.go @@ -284,10 +284,16 @@ func TestAPIOrgPrivateMembersNotLeaked(t *testing.T) { MakeRequest(t, req, http.StatusNotFound) req = NewRequest(t, "GET", "/api/v1/orgs/"+orgName+"/public_members").AddTokenAuth(outsiderToken) MakeRequest(t, req, http.StatusNotFound) + // the full member list of a private org must not be enumerable by an outsider either + req = NewRequest(t, "GET", "/api/v1/orgs/"+orgName+"/members").AddTokenAuth(outsiderToken) + MakeRequest(t, req, http.StatusNotFound) // the member can still see the public membership of their own org req = NewRequest(t, "GET", "/api/v1/orgs/"+orgName+"/public_members/"+memberName).AddTokenAuth(memberToken) MakeRequest(t, req, http.StatusNoContent) + // and the member can still list the org's members + req = NewRequest(t, "GET", "/api/v1/orgs/"+orgName+"/members").AddTokenAuth(memberToken) + MakeRequest(t, req, http.StatusOK) } func testAPIDeleteOrgRepos(t *testing.T) {