gitea/routers/api/v1/user/repo.go
Philip Peterson c5e78fc7ad Do not mutate incoming options to SearchRepositoryByName (#34553)
Similar to #34544, this PR changes the `opts` argument in
`SearchRepositoryByName()` to be passed by value instead of by pointer,
as its mutations do not escape the function scope and are not used
elsewhere. This simplifies reasoning about the function and avoids
unnecessary pointer usage.

This insight emerged during an initial attempt to refactor
`RenderUserSearch()`, which currently intermixes multiple concerns.

---------

Co-authored-by: Philip Peterson <philip-peterson@users.noreply.github.com>
2025-06-02 17:33:25 +00:00

167 lines
4.3 KiB
Go

// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
import (
"net/http"
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
)
// listUserRepos - List the repositories owned by the given user.
func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
opts := utils.GetListOptions(ctx)
repos, count, err := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{
Actor: u,
Private: private,
ListOptions: opts,
OrderBy: "id ASC",
})
if err != nil {
ctx.APIErrorInternal(err)
return
}
if err := repos.LoadAttributes(ctx); err != nil {
ctx.APIErrorInternal(err)
return
}
apiRepos := make([]*api.Repository, 0, len(repos))
for i := range repos {
permission, err := access_model.GetUserRepoPermission(ctx, repos[i], ctx.Doer)
if err != nil {
ctx.APIErrorInternal(err)
return
}
if ctx.IsSigned && ctx.Doer.IsAdmin || permission.HasAnyUnitAccess() {
apiRepos = append(apiRepos, convert.ToRepo(ctx, repos[i], permission))
}
}
ctx.SetLinkHeader(int(count), opts.PageSize)
ctx.SetTotalCountHeader(count)
ctx.JSON(http.StatusOK, &apiRepos)
}
// ListUserRepos - list the repos owned by the given user.
func ListUserRepos(ctx *context.APIContext) {
// swagger:operation GET /users/{username}/repos user userListRepos
// ---
// summary: List the repos owned by the given user
// produces:
// - application/json
// parameters:
// - name: username
// in: path
// description: username of user
// type: string
// required: true
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
// "404":
// "$ref": "#/responses/notFound"
private := ctx.IsSigned
listUserRepos(ctx, ctx.ContextUser, private)
}
// ListMyRepos - list the repositories you own or have access to.
func ListMyRepos(ctx *context.APIContext) {
// swagger:operation GET /user/repos user userCurrentListRepos
// ---
// summary: List the repos that the authenticated user owns
// produces:
// - application/json
// parameters:
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
opts := repo_model.SearchRepoOptions{
ListOptions: utils.GetListOptions(ctx),
Actor: ctx.Doer,
OwnerID: ctx.Doer.ID,
Private: ctx.IsSigned,
IncludeDescription: true,
}
repos, count, err := repo_model.SearchRepository(ctx, opts)
if err != nil {
ctx.APIErrorInternal(err)
return
}
results := make([]*api.Repository, len(repos))
for i, repo := range repos {
if err = repo.LoadOwner(ctx); err != nil {
ctx.APIErrorInternal(err)
return
}
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
ctx.APIErrorInternal(err)
}
results[i] = convert.ToRepo(ctx, repo, permission)
}
ctx.SetLinkHeader(int(count), opts.ListOptions.PageSize)
ctx.SetTotalCountHeader(count)
ctx.JSON(http.StatusOK, &results)
}
// ListOrgRepos - list the repositories of an organization.
func ListOrgRepos(ctx *context.APIContext) {
// swagger:operation GET /orgs/{org}/repos organization orgListRepos
// ---
// summary: List an organization's repos
// produces:
// - application/json
// parameters:
// - name: org
// in: path
// description: name of the organization
// type: string
// required: true
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
// "404":
// "$ref": "#/responses/notFound"
listUserRepos(ctx, ctx.Org.Organization.AsUser(), ctx.IsSigned)
}