Forgejo/routers/api/v1/user/star_list.go
2024-05-03 13:45:04 +02:00

595 lines
16 KiB
Go

// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
import (
"net/http"
"code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
)
func listUserStarListsInternal(ctx *context.APIContext, user *user_model.User) {
starLists, err := repo_model.GetStarListsByUserID(ctx, user.ID, user.IsSameUser(ctx.Doer))
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUserStarListsByUserID", err)
return
}
err = starLists.LoadUser(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadUser", err)
return
}
err = starLists.LoadRepositoryCount(ctx, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadRepositoryCount", err)
return
}
ctx.JSON(http.StatusOK, convert.ToStarLists(ctx, starLists, ctx.Doer))
}
// ListUserStarLists list the given user's star lists
func ListUserStarLists(ctx *context.APIContext) {
// swagger:operation GET /users/{username}/starlists user userGetUserStarLists
// ---
// summary: List the given user's star lists
// produces:
// - application/json
// parameters:
// - name: username
// in: path
// description: username of user
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/StarListSlice"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
listUserStarListsInternal(ctx, ctx.ContextUser)
}
// ListOwnStarLists list the authenticated user's star lists
func ListOwnStarLists(ctx *context.APIContext) {
// swagger:operation GET /user/starlists user userGetOwnStarLists
// ---
// summary: List the authenticated user's star lists
// produces:
// - application/json
// responses:
// "200":
// "$ref": "#/responses/StarListSlice"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "501":
// "$ref": "#/responses/featureDisabled"
listUserStarListsInternal(ctx, ctx.Doer)
}
// GetStarListRepoInfo gets all star lists of the user together with the information, if the given repo is in the list
func GetStarListRepoInfo(ctx *context.APIContext) {
// swagger:operation GET /user/starlists/repoinfo/{owner}/{repo} user userGetStarListRepoInfo
// ---
// summary: Gets all star lists of the user together with the information, if the given repo is in the list
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo to star
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo to star
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/StarListRepoInfo"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "501":
// "$ref": "#/responses/featureDisabled"
starLists, err := repo_model.GetStarListsByUserID(ctx, ctx.Doer.ID, true)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetStarListsByUserID", err)
return
}
err = starLists.LoadUser(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadUser", err)
return
}
err = starLists.LoadRepositoryCount(ctx, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadRepositoryCount", err)
return
}
err = starLists.LoadRepoIDs(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadRepoIDs", err)
return
}
repoInfo := make([]api.StarListRepoInfo, len(starLists))
for i, list := range starLists {
repoInfo[i] = api.StarListRepoInfo{StarList: convert.ToStarList(ctx, list, ctx.Doer), Contains: list.ContainsRepoID(ctx.Repo.Repository.ID)}
}
ctx.JSON(http.StatusOK, repoInfo)
}
// CreateStarList creates a star list
func CreateStarList(ctx *context.APIContext) {
// swagger:operation POST /user/starlists user userCreateStarList
// ---
// summary: Creates a star list
// parameters:
// - name: body
// in: body
// required: true
// schema:
// "$ref": "#/definitions/CreateEditStarListOptions"
// produces:
// - application/json
// responses:
// "201":
// "$ref": "#/responses/StarList"
// "400":
// "$ref": "#/responses/error"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "501":
// "$ref": "#/responses/featureDisabled"
opts := web.GetForm(ctx).(*api.CreateEditStarListOptions)
starList, err := repo_model.CreateStarList(ctx, ctx.Doer.ID, opts.Name, opts.Description, opts.IsPrivate)
if err != nil {
if repo_model.IsErrStarListExists(err) {
ctx.Error(http.StatusBadRequest, "CreateStarList", err)
} else {
ctx.Error(http.StatusInternalServerError, "CreateStarList", err)
}
return
}
err = starList.LoadUser(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadUser", err)
return
}
ctx.JSON(http.StatusCreated, starList)
}
func getStarListByNameInternal(ctx *context.APIContext) {
err := ctx.Starlist.LoadUser(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadUser", err)
return
}
err = ctx.Starlist.LoadRepositoryCount(ctx, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadRepositoryCount", err)
return
}
ctx.JSON(http.StatusOK, convert.ToStarList(ctx, ctx.Starlist, ctx.Doer))
}
// GetUserStarListByName get the star list of the given user with the given name
func GetUserStarListByName(ctx *context.APIContext) {
// swagger:operation GET /users/{username}/starlist/{name} user userGetUserStarListByName
// ---
// summary: Get the star list of the given user with the given name
// produces:
// - application/json
// parameters:
// - name: username
// in: path
// description: username of user
// type: string
// required: true
// - name: name
// in: path
// description: name of the star list
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/StarList"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
getStarListByNameInternal(ctx)
}
// GetOwnStarListByName get the star list of the authenticated user with the given name
func GetOwnStarListByName(ctx *context.APIContext) {
// swagger:operation GET /user/starlist/{name} user userGetOwnStarListByName
// ---
// summary: Get the star list of the authenticated user with the given name
// produces:
// - application/json
// parameters:
// - name: name
// in: path
// description: name of the star list
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/StarList"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
getStarListByNameInternal(ctx)
}
// EditStarList edits a star list
func EditStarList(ctx *context.APIContext) {
// swagger:operation PATCH /user/starlist/{name} user userEditStarList
// ---
// summary: Edits a star list
// parameters:
// - name: name
// in: path
// description: name of the star list
// type: string
// required: true
// - name: body
// in: body
// required: true
// schema:
// "$ref": "#/definitions/CreateEditStarListOptions"
// produces:
// - application/json
// responses:
// "200":
// "$ref": "#/responses/StarList"
// "400":
// "$ref": "#/responses/error"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
opts := web.GetForm(ctx).(*api.CreateEditStarListOptions)
err := ctx.Starlist.EditData(ctx, opts.Name, opts.Description, opts.IsPrivate)
if err != nil {
if repo_model.IsErrStarListExists(err) {
ctx.Error(http.StatusBadRequest, "EditData", err)
} else {
ctx.Error(http.StatusInternalServerError, "EditData", err)
}
return
}
err = ctx.Starlist.LoadUser(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadUser", err)
return
}
err = ctx.Starlist.LoadRepositoryCount(ctx, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadRepositoryCount", err)
return
}
ctx.JSON(http.StatusOK, convert.ToStarList(ctx, ctx.Starlist, ctx.Doer))
}
// DeleteStarList deletes a star list
func DeleteStarList(ctx *context.APIContext) {
// swagger:operation DELETE /user/starlist/{name} user userDeleteStarList
// ---
// summary: Deletes a star list
// parameters:
// - name: name
// in: path
// description: name of the star list
// type: string
// required: true
// produces:
// - application/json
// responses:
// "204":
// "$ref": "#/responses/empty"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
err := repo_model.DeleteStarListByID(ctx, ctx.Starlist.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadRepositoryCount", err)
return
}
ctx.Status(http.StatusNoContent)
}
func getStarListReposInternal(ctx *context.APIContext) {
opts := utils.GetListOptions(ctx)
repos, count, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{Actor: ctx.Doer, StarListID: ctx.Starlist.ID})
if err != nil {
ctx.Error(http.StatusInternalServerError, "SearchRepository", err)
return
}
err = repos.LoadAttributes(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadAttributes", 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.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
return
}
if ctx.IsSigned && ctx.Doer.IsAdmin || permission.UnitAccessMode(unit_model.TypeCode) >= perm.AccessModeRead {
apiRepos = append(apiRepos, convert.ToRepo(ctx, repos[i], permission))
}
}
ctx.SetLinkHeader(int(count), opts.PageSize)
ctx.SetTotalCountHeader(count)
ctx.JSON(http.StatusOK, &apiRepos)
}
// GetUserStarListRepos get the repos of the star list of the given user with the given name
func GetUserStarListRepos(ctx *context.APIContext) {
// swagger:operation GET /users/{username}/starlist/{name}/repos user userGetUserStarListRepos
// ---
// summary: Get the repos of the star list of the given user with the given name
// produces:
// - application/json
// parameters:
// - name: username
// in: path
// description: username of user
// type: string
// required: true
// - name: name
// in: path
// description: name of the star list
// 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"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
getStarListReposInternal(ctx)
}
// GetOwnStarListRepos get the repos of the star list of the authenticated user with the given name
func GetOwnStarListRepos(ctx *context.APIContext) {
// swagger:operation GET /user/starlist/{name}/repos user userGetOwnStarListRepos
// ---
// summary: Get the repos of the star list of the authenticated user with the given name
// produces:
// - application/json
// parameters:
// - name: name
// in: path
// description: name of the star list
// 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"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
getStarListReposInternal(ctx)
}
// AddRepoToStarList adds a Repo to a Star List
func AddRepoToStarList(ctx *context.APIContext) {
// swagger:operation PUT /user/starlist/{name}/{owner}/{repo} user userAddRepoToStarList
// ---
// summary: Adds a Repo to a Star List
// parameters:
// - name: name
// in: path
// description: name of the star list
// type: string
// required: true
// - name: owner
// in: path
// description: owner of the repo to star
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo to star
// type: string
// required: true
// produces:
// - application/json
// responses:
// "201":
// "$ref": "#/responses/empty"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
err := ctx.Starlist.AddRepo(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "AddRepo", err)
return
}
ctx.Status(http.StatusCreated)
}
// RemoveReoFromStarList removes a Repo from a Star List
func RemoveRepoFromStarList(ctx *context.APIContext) {
// swagger:operation DELETE /user/starlist/{name}/{owner}/{repo} user userRemoveRepoFromStarList
// ---
// summary: Removes a Repo from a Star List
// parameters:
// - name: name
// in: path
// description: name of the star list
// type: string
// required: true
// - name: owner
// in: path
// description: owner of the repo to star
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo to star
// type: string
// required: true
// produces:
// - application/json
// responses:
// "204":
// "$ref": "#/responses/empty"
// "401":
// "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
err := ctx.Starlist.RemoveRepo(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "RemoveRepo", err)
return
}
ctx.Status(http.StatusNoContent)
}
// GetStarListByID get a star list by id
func GetStarListByID(ctx *context.APIContext) {
// swagger:operation GET /starlist/{id} user userGetStarListByID
// ---
// summary: Get a star list by id
// parameters:
// - name: id
// in: path
// description: id of the star list to get
// type: integer
// format: int64
// required: true
// produces:
// - application/json
// responses:
// "200":
// "$ref": "#/responses/StarList"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "501":
// "$ref": "#/responses/featureDisabled"
starList, err := repo_model.GetStarListByID(ctx, ctx.ParamsInt64(":id"))
if err != nil {
if repo_model.IsErrStarListNotFound(err) {
ctx.NotFound("GetStarListByID", err)
} else {
ctx.Error(http.StatusInternalServerError, "GetStarListByID", err)
}
return
}
if !starList.HasAccess(ctx.Doer) {
ctx.NotFound("GetStarListByID", repo_model.ErrStarListNotFound{ID: ctx.ParamsInt64(":id")})
return
}
err = starList.LoadUser(ctx)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadUser", err)
return
}
err = starList.LoadRepositoryCount(ctx, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "LoadRepositoryCount", err)
return
}
ctx.JSON(http.StatusOK, convert.ToStarList(ctx, starList, ctx.Doer))
}