Skip to content

Commit c3de504

Browse files
add api routes and functions to get a repository group's subgroups and repos
1 parent 4b6bb0a commit c3de504

File tree

4 files changed

+168
-7
lines changed

4 files changed

+168
-7
lines changed

models/shared/group/org_group.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package group
22

33
import (
4+
repo_model "code.gitea.io/gitea/models/repo"
45
"context"
56

67
"code.gitea.io/gitea/models/db"
@@ -55,3 +56,13 @@ func IsGroupMember(ctx context.Context, groupID int64, user *user_model.User) (b
5556
Table("team_user").
5657
Exist()
5758
}
59+
60+
func GetGroupRepos(ctx context.Context, groupID int64, doer *user_model.User) ([]*repo_model.Repository, error) {
61+
sess := db.GetEngine(ctx)
62+
repos := make([]*repo_model.Repository, 0)
63+
return repos, sess.Table("repository").
64+
Where("group_id = ?", groupID).
65+
And(builder.In("id", repo_model.AccessibleRepoIDsQuery(doer))).
66+
OrderBy("group_sort_order").
67+
Find(&repos)
68+
}

routers/api/v1/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,8 @@ func Routes() *web.Router {
18331833
Delete(reqToken(), reqGroupMembership(perm.AccessModeAdmin, false), group.DeleteGroup)
18341834
m.Post("/move", reqToken(), reqGroupMembership(perm.AccessModeWrite, false), bind(api.MoveGroupOption{}), group.MoveGroup)
18351835
m.Post("/new", reqToken(), reqGroupMembership(perm.AccessModeWrite, true), bind(api.NewGroupOption{}), group.NewSubGroup)
1836+
m.Get("/subgroups", reqGroupMembership(perm.AccessModeRead, false), group.GetGroupSubGroups)
1837+
m.Get("/repos", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository), reqGroupMembership(perm.AccessModeRead, false), group.GetGroupRepos)
18361838
}, checkTokenPublicOnly())
18371839
})
18381840
return m

routers/api/v1/group/group.go

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package group
22

33
import (
4+
access_model "code.gitea.io/gitea/models/perm/access"
5+
shared_group_model "code.gitea.io/gitea/models/shared/group"
46
"fmt"
57
"net/http"
68
"strings"
@@ -265,8 +267,6 @@ func GetGroup(ctx *context.APIContext) {
265267
// "$ref": "#/responses/Group"
266268
// "404":
267269
// "$ref": "#/responses/notFound"
268-
// "422":
269-
// "$ref": "#/responses/validationError"
270270
var (
271271
err error
272272
group *group_model.Group
@@ -318,3 +318,94 @@ func DeleteGroup(ctx *context.APIContext) {
318318
}
319319
ctx.Status(http.StatusNoContent)
320320
}
321+
322+
func GetGroupRepos(ctx *context.APIContext) {
323+
// swagger:operation GET /groups/{group_id}/repos repository-group groupGetRepos
324+
// ---
325+
// summary: gets the repos contained within a group
326+
// produces:
327+
// - application/json
328+
// parameters:
329+
// - name: group_id
330+
// in: path
331+
// description: id of the group containing the repositories
332+
// type: integer
333+
// format: int64
334+
// required: true
335+
// responses:
336+
// "200":
337+
// "$ref": "#/responses/RepositoryList"
338+
// "404":
339+
// "$ref": "#/responses/notFound"
340+
gid := ctx.PathParamInt64("group_id")
341+
_, err := group_model.GetGroupByID(ctx, gid)
342+
if err != nil {
343+
if group_model.IsErrGroupNotExist(err) {
344+
ctx.APIErrorNotFound()
345+
} else {
346+
ctx.APIErrorInternal(err)
347+
}
348+
return
349+
}
350+
351+
groupRepos, err := shared_group_model.GetGroupRepos(ctx, gid, ctx.Doer)
352+
if err != nil {
353+
ctx.APIErrorInternal(err)
354+
return
355+
}
356+
repos := make([]*api.Repository, len(groupRepos))
357+
for i, repo := range groupRepos {
358+
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
359+
if err != nil {
360+
ctx.APIErrorInternal(err)
361+
return
362+
}
363+
repos[i] = convert.ToRepo(ctx, repo, permission)
364+
}
365+
ctx.SetTotalCountHeader(int64(len(repos)))
366+
ctx.JSON(http.StatusOK, repos)
367+
}
368+
369+
func GetGroupSubGroups(ctx *context.APIContext) {
370+
// swagger:operation GET /groups/{group_id}/subgroups repository-group groupGetSubGroups
371+
// ---
372+
// summary: gets the subgroups contained within a group
373+
// produces:
374+
// - application/json
375+
// parameters:
376+
// - name: group_id
377+
// in: path
378+
// description: id of the parent group
379+
// type: integer
380+
// format: int64
381+
// required: true
382+
// responses:
383+
// "200":
384+
// "$ref": "#/responses/GroupList"
385+
// "404":
386+
// "$ref": "#/responses/notFound"
387+
g, err := group_model.GetGroupByID(ctx, ctx.PathParamInt64("group_id"))
388+
if err != nil {
389+
if group_model.IsErrGroupNotExist(err) {
390+
ctx.APIErrorNotFound()
391+
} else {
392+
ctx.APIErrorInternal(err)
393+
}
394+
return
395+
}
396+
err = g.LoadAccessibleSubgroups(ctx, false, ctx.Doer)
397+
if err != nil {
398+
ctx.APIErrorInternal(err)
399+
return
400+
}
401+
groups := make([]*api.Group, len(g.Subgroups))
402+
for i, group := range g.Subgroups {
403+
groups[i], err = convert.ToAPIGroup(ctx, group, ctx.Doer)
404+
if err != nil {
405+
ctx.APIErrorInternal(err)
406+
return
407+
}
408+
}
409+
ctx.SetTotalCountHeader(int64(len(groups)))
410+
ctx.JSON(http.StatusOK, groups)
411+
}

templates/swagger/v1_json.tmpl

Lines changed: 62 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)