diff options
author | 6543 <6543@obermui.de> | 2020-01-31 16:49:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-31 15:49:04 +0000 |
commit | 13bc82009c2def4e729f11340e74a14d6c6b32e8 (patch) | |
tree | b545d0af8fdebbddb79fee55b8e643c9f392ff49 /routers/api/v1/repo/transfer.go | |
parent | d816f7018b0726f868fa0cddf02ffae184601395 (diff) | |
download | gitea-13bc82009c2def4e729f11340e74a14d6c6b32e8.tar.gz gitea-13bc82009c2def4e729f11340e74a14d6c6b32e8.zip |
API endpoint for repo transfer (#9947)
* squash
* optimize
* fail before make any changes
* fix-header
Diffstat (limited to 'routers/api/v1/repo/transfer.go')
-rw-r--r-- | routers/api/v1/repo/transfer.go | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go new file mode 100644 index 0000000000..847028d106 --- /dev/null +++ b/routers/api/v1/repo/transfer.go @@ -0,0 +1,100 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repo + +import ( + "fmt" + "net/http" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/convert" + "code.gitea.io/gitea/modules/log" + api "code.gitea.io/gitea/modules/structs" + repo_service "code.gitea.io/gitea/services/repository" +) + +// Transfer transfers the ownership of a repository +func Transfer(ctx *context.APIContext, opts api.TransferRepoOption) { + // swagger:operation POST /repos/{owner}/{repo}/transfer repository repoTransfer + // --- + // summary: Transfer a repo ownership + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo to transfer + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo to transfer + // type: string + // required: true + // - name: body + // in: body + // description: "Transfer Options" + // required: true + // schema: + // "$ref": "#/definitions/TransferRepoOption" + // responses: + // "202": + // "$ref": "#/responses/Repository" + // "403": + // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" + // "422": + // "$ref": "#/responses/validationError" + + newOwner, err := models.GetUserByName(opts.NewOwner) + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.Error(http.StatusNotFound, "GetUserByName", err) + return + } + ctx.InternalServerError(err) + return + } + + var teams []*models.Team + if opts.TeamIDs != nil { + if !newOwner.IsOrganization() { + ctx.Error(http.StatusUnprocessableEntity, "repoTransfer", "Teams can only be added to organization-owned repositories") + return + } + + org := convert.ToOrganization(newOwner) + for _, tID := range *opts.TeamIDs { + team, err := models.GetTeamByID(tID) + if err != nil { + ctx.Error(http.StatusUnprocessableEntity, "team", fmt.Errorf("team %d not found", tID)) + return + } + + if team.OrgID != org.ID { + ctx.Error(http.StatusForbidden, "team", fmt.Errorf("team %d belongs not to org %d", tID, org.ID)) + return + } + + teams = append(teams, team) + } + } + + if err = repo_service.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository, teams); err != nil { + ctx.InternalServerError(err) + return + } + + newRepo, err := models.GetRepositoryByName(newOwner.ID, ctx.Repo.Repository.Name) + if err != nil { + ctx.InternalServerError(err) + return + } + + log.Trace("Repository transferred: %s -> %s", ctx.Repo.Repository.FullName(), newOwner.Name) + ctx.JSON(http.StatusAccepted, newRepo.APIFormat(models.AccessModeAdmin)) +} |