| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- // Copyright 2021 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package packages
-
- import (
- "errors"
- "net/http"
-
- "code.gitea.io/gitea/models/packages"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/optional"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- packages_service "code.gitea.io/gitea/services/packages"
- )
-
- // ListPackages gets all packages of an owner
- func ListPackages(ctx *context.APIContext) {
- // swagger:operation GET /packages/{owner} package listPackages
- // ---
- // summary: Gets all packages of an owner
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the packages
- // 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
- // - name: type
- // in: query
- // description: package type filter
- // type: string
- // enum: [alpine, cargo, chef, composer, conan, conda, container, cran, debian, generic, go, helm, maven, npm, nuget, pub, pypi, rpm, rubygems, swift, vagrant]
- // - name: q
- // in: query
- // description: name filter
- // type: string
- // responses:
- // "200":
- // "$ref": "#/responses/PackageList"
- // "404":
- // "$ref": "#/responses/notFound"
-
- listOptions := utils.GetListOptions(ctx)
-
- apiPackages, count, err := searchPackages(ctx, &packages.PackageSearchOptions{
- OwnerID: ctx.Package.Owner.ID,
- Type: packages.Type(ctx.FormTrim("type")),
- Name: packages.SearchValue{Value: ctx.FormTrim("q")},
- IsInternal: optional.Some(false),
- Paginator: &listOptions,
- })
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- ctx.SetLinkHeader(int(count), listOptions.PageSize)
- ctx.SetTotalCountHeader(count)
- ctx.JSON(http.StatusOK, apiPackages)
- }
-
- // GetPackage gets a package
- func GetPackage(ctx *context.APIContext) {
- // swagger:operation GET /packages/{owner}/{type}/{name}/{version} package getPackage
- // ---
- // summary: Gets a package
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the package
- // type: string
- // required: true
- // - name: type
- // in: path
- // description: type of the package
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of the package
- // type: string
- // required: true
- // - name: version
- // in: path
- // description: version of the package
- // type: string
- // required: true
- // responses:
- // "200":
- // "$ref": "#/responses/Package"
- // "404":
- // "$ref": "#/responses/notFound"
-
- apiPackage, err := convert.ToPackage(ctx, ctx.Package.Descriptor, ctx.Doer)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- ctx.JSON(http.StatusOK, apiPackage)
- }
-
- // DeletePackage deletes a package
- func DeletePackage(ctx *context.APIContext) {
- // swagger:operation DELETE /packages/{owner}/{type}/{name}/{version} package deletePackage
- // ---
- // summary: Delete a package
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the package
- // type: string
- // required: true
- // - name: type
- // in: path
- // description: type of the package
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of the package
- // type: string
- // required: true
- // - name: version
- // in: path
- // description: version of the package
- // type: string
- // required: true
- // responses:
- // "204":
- // "$ref": "#/responses/empty"
- // "404":
- // "$ref": "#/responses/notFound"
-
- err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
- ctx.Status(http.StatusNoContent)
- }
-
- // ListPackageFiles gets all files of a package
- func ListPackageFiles(ctx *context.APIContext) {
- // swagger:operation GET /packages/{owner}/{type}/{name}/{version}/files package listPackageFiles
- // ---
- // summary: Gets all files of a package
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the package
- // type: string
- // required: true
- // - name: type
- // in: path
- // description: type of the package
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of the package
- // type: string
- // required: true
- // - name: version
- // in: path
- // description: version of the package
- // type: string
- // required: true
- // responses:
- // "200":
- // "$ref": "#/responses/PackageFileList"
- // "404":
- // "$ref": "#/responses/notFound"
-
- apiPackageFiles := make([]*api.PackageFile, 0, len(ctx.Package.Descriptor.Files))
- for _, pfd := range ctx.Package.Descriptor.Files {
- apiPackageFiles = append(apiPackageFiles, convert.ToPackageFile(pfd))
- }
-
- ctx.JSON(http.StatusOK, apiPackageFiles)
- }
-
- // ListPackageVersions gets all versions of a package
- func ListPackageVersions(ctx *context.APIContext) {
- // swagger:operation GET /packages/{owner}/{type}/{name} package listPackageVersions
- // ---
- // summary: Gets all versions of a package
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the package
- // type: string
- // required: true
- // - name: type
- // in: path
- // description: type of the package
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of the package
- // 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/PackageList"
- // "404":
- // "$ref": "#/responses/notFound"
-
- listOptions := utils.GetListOptions(ctx)
-
- apiPackages, count, err := searchPackages(ctx, &packages.PackageSearchOptions{
- OwnerID: ctx.Package.Owner.ID,
- Type: packages.Type(ctx.PathParam("type")),
- Name: packages.SearchValue{Value: ctx.PathParam("name"), ExactMatch: true},
- IsInternal: optional.Some(false),
- Paginator: &listOptions,
- })
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- ctx.SetLinkHeader(int(count), listOptions.PageSize)
- ctx.SetTotalCountHeader(count)
- ctx.JSON(http.StatusOK, apiPackages)
- }
-
- // GetLatestPackageVersion gets the latest version of a package
- func GetLatestPackageVersion(ctx *context.APIContext) {
- // swagger:operation GET /packages/{owner}/{type}/{name}/-/latest package getLatestPackageVersion
- // ---
- // summary: Gets the latest version of a package
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the package
- // type: string
- // required: true
- // - name: type
- // in: path
- // description: type of the package
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of the package
- // type: string
- // required: true
- // responses:
- // "200":
- // "$ref": "#/responses/Package"
- // "404":
- // "$ref": "#/responses/notFound"
-
- pvs, _, err := packages.SearchLatestVersions(ctx, &packages.PackageSearchOptions{
- OwnerID: ctx.Package.Owner.ID,
- Type: packages.Type(ctx.PathParam("type")),
- Name: packages.SearchValue{Value: ctx.PathParam("name"), ExactMatch: true},
- IsInternal: optional.Some(false),
- })
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
- if len(pvs) == 0 {
- ctx.APIError(http.StatusNotFound, err)
- return
- }
-
- pd, err := packages.GetPackageDescriptor(ctx, pvs[0])
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- apiPackage, err := convert.ToPackage(ctx, pd, ctx.Doer)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- ctx.JSON(http.StatusOK, apiPackage)
- }
-
- // LinkPackage sets a repository link for a package
- func LinkPackage(ctx *context.APIContext) {
- // swagger:operation POST /packages/{owner}/{type}/{name}/-/link/{repo_name} package linkPackage
- // ---
- // summary: Link a package to a repository
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the package
- // type: string
- // required: true
- // - name: type
- // in: path
- // description: type of the package
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of the package
- // type: string
- // required: true
- // - name: repo_name
- // in: path
- // description: name of the repository to link.
- // type: string
- // required: true
- // responses:
- // "201":
- // "$ref": "#/responses/empty"
- // "404":
- // "$ref": "#/responses/notFound"
-
- pkg, err := packages.GetPackageByName(ctx, ctx.ContextUser.ID, packages.Type(ctx.PathParam("type")), ctx.PathParam("name"))
- if err != nil {
- if errors.Is(err, util.ErrNotExist) {
- ctx.APIError(http.StatusNotFound, err)
- } else {
- ctx.APIErrorInternal(err)
- }
- return
- }
-
- repo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, ctx.PathParam("repo_name"))
- if err != nil {
- if errors.Is(err, util.ErrNotExist) {
- ctx.APIError(http.StatusNotFound, err)
- } else {
- ctx.APIErrorInternal(err)
- }
- return
- }
-
- err = packages_service.LinkToRepository(ctx, pkg, repo, ctx.Doer)
- if err != nil {
- switch {
- case errors.Is(err, util.ErrInvalidArgument):
- ctx.APIError(http.StatusBadRequest, err)
- case errors.Is(err, util.ErrPermissionDenied):
- ctx.APIError(http.StatusForbidden, err)
- default:
- ctx.APIErrorInternal(err)
- }
- return
- }
- ctx.Status(http.StatusCreated)
- }
-
- // UnlinkPackage sets a repository link for a package
- func UnlinkPackage(ctx *context.APIContext) {
- // swagger:operation POST /packages/{owner}/{type}/{name}/-/unlink package unlinkPackage
- // ---
- // summary: Unlink a package from a repository
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the package
- // type: string
- // required: true
- // - name: type
- // in: path
- // description: type of the package
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of the package
- // type: string
- // required: true
- // responses:
- // "201":
- // "$ref": "#/responses/empty"
- // "404":
- // "$ref": "#/responses/notFound"
-
- pkg, err := packages.GetPackageByName(ctx, ctx.ContextUser.ID, packages.Type(ctx.PathParam("type")), ctx.PathParam("name"))
- if err != nil {
- if errors.Is(err, util.ErrNotExist) {
- ctx.APIError(http.StatusNotFound, err)
- } else {
- ctx.APIErrorInternal(err)
- }
- return
- }
-
- err = packages_service.UnlinkFromRepository(ctx, pkg, ctx.Doer)
- if err != nil {
- switch {
- case errors.Is(err, util.ErrPermissionDenied):
- ctx.APIError(http.StatusForbidden, err)
- case errors.Is(err, util.ErrInvalidArgument):
- ctx.APIError(http.StatusBadRequest, err)
- default:
- ctx.APIErrorInternal(err)
- }
- return
- }
- ctx.Status(http.StatusNoContent)
- }
-
- func searchPackages(ctx *context.APIContext, opts *packages.PackageSearchOptions) ([]*api.Package, int64, error) {
- pvs, count, err := packages.SearchVersions(ctx, opts)
- if err != nil {
- return nil, 0, err
- }
-
- pds, err := packages.GetPackageDescriptors(ctx, pvs)
- if err != nil {
- return nil, 0, err
- }
-
- apiPackages := make([]*api.Package, 0, len(pds))
- for _, pd := range pds {
- apiPackage, err := convert.ToPackage(ctx, pd, ctx.Doer)
- if err != nil {
- return nil, 0, err
- }
- apiPackages = append(apiPackages, apiPackage)
- }
-
- return apiPackages, count, nil
- }
|