0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-04-04 05:45:23 +02:00

add api routes and functions to get a repository group's subgroups and repos

This commit is contained in:
☙◦ The Tablet ❀ GamerGirlandCo ◦❧ 2025-08-14 17:13:40 -04:00
parent 243ff36900
commit ab817e4251
No known key found for this signature in database
GPG Key ID: 924A5F6AF051E87C
4 changed files with 168 additions and 7 deletions

View File

@ -1,6 +1,7 @@
package group
import (
repo_model "code.gitea.io/gitea/models/repo"
"context"
"code.gitea.io/gitea/models/db"
@ -55,3 +56,13 @@ func IsGroupMember(ctx context.Context, groupID int64, user *user_model.User) (b
Table("team_user").
Exist()
}
func GetGroupRepos(ctx context.Context, groupID int64, doer *user_model.User) ([]*repo_model.Repository, error) {
sess := db.GetEngine(ctx)
repos := make([]*repo_model.Repository, 0)
return repos, sess.Table("repository").
Where("group_id = ?", groupID).
And(builder.In("id", repo_model.AccessibleRepoIDsQuery(doer))).
OrderBy("group_sort_order").
Find(&repos)
}

View File

@ -1806,6 +1806,8 @@ func Routes() *web.Router {
Delete(reqToken(), reqGroupMembership(perm.AccessModeAdmin, false), group.DeleteGroup)
m.Post("/move", reqToken(), reqGroupMembership(perm.AccessModeWrite, false), bind(api.MoveGroupOption{}), group.MoveGroup)
m.Post("/new", reqToken(), reqGroupMembership(perm.AccessModeWrite, true), bind(api.NewGroupOption{}), group.NewSubGroup)
m.Get("/subgroups", reqGroupMembership(perm.AccessModeRead, false), group.GetGroupSubGroups)
m.Get("/repos", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository), reqGroupMembership(perm.AccessModeRead, false), group.GetGroupRepos)
}, checkTokenPublicOnly())
})
return m

View File

@ -1,6 +1,8 @@
package group
import (
access_model "code.gitea.io/gitea/models/perm/access"
shared_group_model "code.gitea.io/gitea/models/shared/group"
"fmt"
"net/http"
"strings"
@ -265,8 +267,6 @@ func GetGroup(ctx *context.APIContext) {
// "$ref": "#/responses/Group"
// "404":
// "$ref": "#/responses/notFound"
// "422":
// "$ref": "#/responses/validationError"
var (
err error
group *group_model.Group
@ -318,3 +318,94 @@ func DeleteGroup(ctx *context.APIContext) {
}
ctx.Status(http.StatusNoContent)
}
func GetGroupRepos(ctx *context.APIContext) {
// swagger:operation GET /groups/{group_id}/repos repository-group groupGetRepos
// ---
// summary: gets the repos contained within a group
// produces:
// - application/json
// parameters:
// - name: group_id
// in: path
// description: id of the group containing the repositories
// type: integer
// format: int64
// required: true
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
// "404":
// "$ref": "#/responses/notFound"
gid := ctx.PathParamInt64("group_id")
_, err := group_model.GetGroupByID(ctx, gid)
if err != nil {
if group_model.IsErrGroupNotExist(err) {
ctx.APIErrorNotFound()
} else {
ctx.APIErrorInternal(err)
}
return
}
groupRepos, err := shared_group_model.GetGroupRepos(ctx, gid, ctx.Doer)
if err != nil {
ctx.APIErrorInternal(err)
return
}
repos := make([]*api.Repository, len(groupRepos))
for i, repo := range groupRepos {
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
ctx.APIErrorInternal(err)
return
}
repos[i] = convert.ToRepo(ctx, repo, permission)
}
ctx.SetTotalCountHeader(int64(len(repos)))
ctx.JSON(http.StatusOK, repos)
}
func GetGroupSubGroups(ctx *context.APIContext) {
// swagger:operation GET /groups/{group_id}/subgroups repository-group groupGetSubGroups
// ---
// summary: gets the subgroups contained within a group
// produces:
// - application/json
// parameters:
// - name: group_id
// in: path
// description: id of the parent group
// type: integer
// format: int64
// required: true
// responses:
// "200":
// "$ref": "#/responses/GroupList"
// "404":
// "$ref": "#/responses/notFound"
g, err := group_model.GetGroupByID(ctx, ctx.PathParamInt64("group_id"))
if err != nil {
if group_model.IsErrGroupNotExist(err) {
ctx.APIErrorNotFound()
} else {
ctx.APIErrorInternal(err)
}
return
}
err = g.LoadAccessibleSubgroups(ctx, false, ctx.Doer)
if err != nil {
ctx.APIErrorInternal(err)
return
}
groups := make([]*api.Group, len(g.Subgroups))
for i, group := range g.Subgroups {
groups[i], err = convert.ToAPIGroup(ctx, group, ctx.Doer)
if err != nil {
ctx.APIErrorInternal(err)
return
}
}
ctx.SetTotalCountHeader(int64(len(groups)))
ctx.JSON(http.StatusOK, groups)
}

View File

@ -1324,8 +1324,8 @@
"tags": [
"repository-group"
],
"summary": "gets the repos contained within a group",
"operationId": "groupRepos",
"summary": "gets a group in an organization",
"operationId": "groupGet",
"parameters": [
{
"type": "integer",
@ -1342,9 +1342,6 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"422": {
"$ref": "#/responses/validationError"
}
}
},
@ -1509,6 +1506,66 @@
}
}
},
"/groups/{group_id}/repos": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository-group"
],
"summary": "gets the repos contained within a group",
"operationId": "groupGetRepos",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "id of the group containing the repositories",
"name": "group_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/RepositoryList"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/groups/{group_id}/subgroups": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository-group"
],
"summary": "gets the subgroups contained within a group",
"operationId": "groupGetSubGroups",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "id of the parent group",
"name": "group_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/GroupList"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/label/templates": {
"get": {
"produces": [