From 843950818eeace58f2140ac29b654a886a22b993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=98=99=E2=97=A6=20The=20Tablet=20=E2=9D=80=20GamerGirla?= =?UTF-8?q?ndCo=20=E2=97=A6=E2=9D=A7?= Date: Wed, 6 May 2026 19:23:02 -0400 Subject: [PATCH] refactor: add `reqOrgAdmin` middleware, update broken `/orgs/{org}/groups/new` endpoint --- routers/api/v1/api.go | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 99a07595a7..2cc695426c 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -467,6 +467,37 @@ func reqAnyRepoReader() func(ctx *context.APIContext) { } } +// reqOrgAdmin user should be an organization or site-wide admin +func reqOrgAdmin() func(ctx *context.APIContext) { + return func(ctx *context.APIContext) { + if ctx.IsUserSiteAdmin() { + return + } + var orgID int64 + if ctx.Org.Organization != nil { + orgID = ctx.Org.Organization.ID + } else if ctx.Org.Team != nil { + orgID = ctx.Org.Team.OrgID + } else { + setting.PanicInDevOrTesting("reqOrgOwnership: unprepared context") + ctx.APIErrorInternal(errors.New("reqOrgOwnership: unprepared context")) + return + } + isAdmin, err := organization.IsOrganizationAdmin(ctx, orgID, ctx.Doer.ID) + if err != nil { + ctx.APIErrorInternal(err) + return + } else if !isAdmin { + if ctx.Org.Organization != nil { + ctx.APIError(http.StatusForbidden, "Must be an organization owner") + } else { + ctx.APIErrorNotFound() + } + return + } + } +} + // reqOrgOwnership user should be an organization owner, or a site admin func reqOrgOwnership() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { @@ -1760,7 +1791,7 @@ func Routes() *web.Router { }, reqToken(), reqOrgOwnership()) m.Group("/groups", func() { m.Get("", org.GetOrgGroups) - m.Post("/new", reqToken(), reqGroupMembership(perm.AccessModeWrite, true), group.NewGroup) + m.Post("/new", reqToken(), reqOrgAdmin(), bind(api.NewGroupOption{}), group.NewGroup) }) }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true), checkTokenPublicOnly()) m.Group("/teams/{teamid}", func() {