123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815 |
- // Copyright 2016 The Gogs Authors. All rights reserved.
- // Copyright 2019 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 (
- "errors"
- "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/git"
- repo_module "code.gitea.io/gitea/modules/repository"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- pull_service "code.gitea.io/gitea/services/pull"
- repo_service "code.gitea.io/gitea/services/repository"
- )
-
- // GetBranch get a branch of a repository
- func GetBranch(ctx *context.APIContext) {
- // swagger:operation GET /repos/{owner}/{repo}/branches/{branch} repository repoGetBranch
- // ---
- // summary: Retrieve a specific branch from a repository, including its effective branch protection
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: branch
- // in: path
- // description: branch to get
- // type: string
- // required: true
- // responses:
- // "200":
- // "$ref": "#/responses/Branch"
- // "404":
- // "$ref": "#/responses/notFound"
-
- branchName := ctx.Params("*")
-
- branch, err := repo_module.GetBranch(ctx.Repo.Repository, branchName)
- if err != nil {
- if git.IsErrBranchNotExist(err) {
- ctx.NotFound(err)
- } else {
- ctx.Error(http.StatusInternalServerError, "GetBranch", err)
- }
- return
- }
-
- c, err := branch.GetCommit()
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetCommit", err)
- return
- }
-
- branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branchName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err)
- return
- }
-
- br, err := convert.ToBranch(ctx.Repo.Repository, branch, c, branchProtection, ctx.User, ctx.Repo.IsAdmin())
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
- return
- }
-
- ctx.JSON(http.StatusOK, br)
- }
-
- // DeleteBranch get a branch of a repository
- func DeleteBranch(ctx *context.APIContext) {
- // swagger:operation DELETE /repos/{owner}/{repo}/branches/{branch} repository repoDeleteBranch
- // ---
- // summary: Delete a specific branch from a repository
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: branch
- // in: path
- // description: branch to delete
- // type: string
- // required: true
- // responses:
- // "204":
- // "$ref": "#/responses/empty"
- // "403":
- // "$ref": "#/responses/error"
- // "404":
- // "$ref": "#/responses/notFound"
-
- branchName := ctx.Params("*")
-
- if err := repo_service.DeleteBranch(ctx.User, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil {
- switch {
- case git.IsErrBranchNotExist(err):
- ctx.NotFound(err)
- case errors.Is(err, repo_service.ErrBranchIsDefault):
- ctx.Error(http.StatusForbidden, "DefaultBranch", fmt.Errorf("can not delete default branch"))
- case errors.Is(err, repo_service.ErrBranchIsProtected):
- ctx.Error(http.StatusForbidden, "IsProtectedBranch", fmt.Errorf("branch protected"))
- default:
- ctx.Error(http.StatusInternalServerError, "DeleteBranch", err)
- }
- return
- }
-
- ctx.Status(http.StatusNoContent)
- }
-
- // CreateBranch creates a branch for a user's repository
- func CreateBranch(ctx *context.APIContext) {
- // swagger:operation POST /repos/{owner}/{repo}/branches repository repoCreateBranch
- // ---
- // summary: Create a branch
- // consumes:
- // - application/json
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: body
- // in: body
- // schema:
- // "$ref": "#/definitions/CreateBranchRepoOption"
- // responses:
- // "201":
- // "$ref": "#/responses/Branch"
- // "404":
- // description: The old branch does not exist.
- // "409":
- // description: The branch with the same name already exists.
-
- opt := web.GetForm(ctx).(*api.CreateBranchRepoOption)
- if ctx.Repo.Repository.IsEmpty {
- ctx.Error(http.StatusNotFound, "", "Git Repository is empty.")
- return
- }
-
- if len(opt.OldBranchName) == 0 {
- opt.OldBranchName = ctx.Repo.Repository.DefaultBranch
- }
-
- err := repo_module.CreateNewBranch(ctx.User, ctx.Repo.Repository, opt.OldBranchName, opt.BranchName)
-
- if err != nil {
- if models.IsErrBranchDoesNotExist(err) {
- ctx.Error(http.StatusNotFound, "", "The old branch does not exist")
- }
- if models.IsErrTagAlreadyExists(err) {
- ctx.Error(http.StatusConflict, "", "The branch with the same tag already exists.")
-
- } else if models.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
- ctx.Error(http.StatusConflict, "", "The branch already exists.")
-
- } else if models.IsErrBranchNameConflict(err) {
- ctx.Error(http.StatusConflict, "", "The branch with the same name already exists.")
-
- } else {
- ctx.Error(http.StatusInternalServerError, "CreateRepoBranch", err)
-
- }
- return
- }
-
- branch, err := repo_module.GetBranch(ctx.Repo.Repository, opt.BranchName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetBranch", err)
- return
- }
-
- commit, err := branch.GetCommit()
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetCommit", err)
- return
- }
-
- branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branch.Name)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err)
- return
- }
-
- br, err := convert.ToBranch(ctx.Repo.Repository, branch, commit, branchProtection, ctx.User, ctx.Repo.IsAdmin())
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
- return
- }
-
- ctx.JSON(http.StatusCreated, br)
- }
-
- // ListBranches list all the branches of a repository
- func ListBranches(ctx *context.APIContext) {
- // swagger:operation GET /repos/{owner}/{repo}/branches repository repoListBranches
- // ---
- // summary: List a repository's branches
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // 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/BranchList"
-
- listOptions := utils.GetListOptions(ctx)
- skip, _ := listOptions.GetStartEnd()
- branches, totalNumOfBranches, err := repo_module.GetBranches(ctx.Repo.Repository, skip, listOptions.PageSize)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetBranches", err)
- return
- }
-
- apiBranches := make([]*api.Branch, len(branches))
- for i := range branches {
- c, err := branches[i].GetCommit()
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetCommit", err)
- return
- }
- branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branches[i].Name)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err)
- return
- }
- apiBranches[i], err = convert.ToBranch(ctx.Repo.Repository, branches[i], c, branchProtection, ctx.User, ctx.Repo.IsAdmin())
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
- return
- }
- }
-
- ctx.SetLinkHeader(totalNumOfBranches, listOptions.PageSize)
- ctx.SetTotalCountHeader(int64(totalNumOfBranches))
- ctx.JSON(http.StatusOK, &apiBranches)
- }
-
- // GetBranchProtection gets a branch protection
- func GetBranchProtection(ctx *context.APIContext) {
- // swagger:operation GET /repos/{owner}/{repo}/branch_protections/{name} repository repoGetBranchProtection
- // ---
- // summary: Get a specific branch protection for the repository
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of protected branch
- // type: string
- // required: true
- // responses:
- // "200":
- // "$ref": "#/responses/BranchProtection"
- // "404":
- // "$ref": "#/responses/notFound"
-
- repo := ctx.Repo.Repository
- bpName := ctx.Params(":name")
- bp, err := models.GetProtectedBranchBy(repo.ID, bpName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err)
- return
- }
- if bp == nil || bp.RepoID != repo.ID {
- ctx.NotFound()
- return
- }
-
- ctx.JSON(http.StatusOK, convert.ToBranchProtection(bp))
- }
-
- // ListBranchProtections list branch protections for a repo
- func ListBranchProtections(ctx *context.APIContext) {
- // swagger:operation GET /repos/{owner}/{repo}/branch_protections repository repoListBranchProtection
- // ---
- // summary: List branch protections for a repository
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // responses:
- // "200":
- // "$ref": "#/responses/BranchProtectionList"
-
- repo := ctx.Repo.Repository
- bps, err := repo.GetProtectedBranches()
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetProtectedBranches", err)
- return
- }
- apiBps := make([]*api.BranchProtection, len(bps))
- for i := range bps {
- apiBps[i] = convert.ToBranchProtection(bps[i])
- }
-
- ctx.JSON(http.StatusOK, apiBps)
- }
-
- // CreateBranchProtection creates a branch protection for a repo
- func CreateBranchProtection(ctx *context.APIContext) {
- // swagger:operation POST /repos/{owner}/{repo}/branch_protections repository repoCreateBranchProtection
- // ---
- // summary: Create a branch protections for a repository
- // consumes:
- // - application/json
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: body
- // in: body
- // schema:
- // "$ref": "#/definitions/CreateBranchProtectionOption"
- // responses:
- // "201":
- // "$ref": "#/responses/BranchProtection"
- // "403":
- // "$ref": "#/responses/forbidden"
- // "404":
- // "$ref": "#/responses/notFound"
- // "422":
- // "$ref": "#/responses/validationError"
-
- form := web.GetForm(ctx).(*api.CreateBranchProtectionOption)
- repo := ctx.Repo.Repository
-
- // Currently protection must match an actual branch
- if !git.IsBranchExist(ctx.Repo.Repository.RepoPath(), form.BranchName) {
- ctx.NotFound()
- return
- }
-
- protectBranch, err := models.GetProtectedBranchBy(repo.ID, form.BranchName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetProtectBranchOfRepoByName", err)
- return
- } else if protectBranch != nil {
- ctx.Error(http.StatusForbidden, "Create branch protection", "Branch protection already exist")
- return
- }
-
- var requiredApprovals int64
- if form.RequiredApprovals > 0 {
- requiredApprovals = form.RequiredApprovals
- }
-
- whitelistUsers, err := models.GetUserIDsByNames(form.PushWhitelistUsernames, false)
- if err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
- return
- }
- mergeWhitelistUsers, err := models.GetUserIDsByNames(form.MergeWhitelistUsernames, false)
- if err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
- return
- }
- approvalsWhitelistUsers, err := models.GetUserIDsByNames(form.ApprovalsWhitelistUsernames, false)
- if err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
- return
- }
- var whitelistTeams, mergeWhitelistTeams, approvalsWhitelistTeams []int64
- if repo.Owner.IsOrganization() {
- whitelistTeams, err = models.GetTeamIDsByNames(repo.OwnerID, form.PushWhitelistTeams, false)
- if err != nil {
- if models.IsErrTeamNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
- return
- }
- mergeWhitelistTeams, err = models.GetTeamIDsByNames(repo.OwnerID, form.MergeWhitelistTeams, false)
- if err != nil {
- if models.IsErrTeamNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
- return
- }
- approvalsWhitelistTeams, err = models.GetTeamIDsByNames(repo.OwnerID, form.ApprovalsWhitelistTeams, false)
- if err != nil {
- if models.IsErrTeamNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
- return
- }
- }
-
- protectBranch = &models.ProtectedBranch{
- RepoID: ctx.Repo.Repository.ID,
- BranchName: form.BranchName,
- CanPush: form.EnablePush,
- EnableWhitelist: form.EnablePush && form.EnablePushWhitelist,
- EnableMergeWhitelist: form.EnableMergeWhitelist,
- WhitelistDeployKeys: form.EnablePush && form.EnablePushWhitelist && form.PushWhitelistDeployKeys,
- EnableStatusCheck: form.EnableStatusCheck,
- StatusCheckContexts: form.StatusCheckContexts,
- EnableApprovalsWhitelist: form.EnableApprovalsWhitelist,
- RequiredApprovals: requiredApprovals,
- BlockOnRejectedReviews: form.BlockOnRejectedReviews,
- BlockOnOfficialReviewRequests: form.BlockOnOfficialReviewRequests,
- DismissStaleApprovals: form.DismissStaleApprovals,
- RequireSignedCommits: form.RequireSignedCommits,
- ProtectedFilePatterns: form.ProtectedFilePatterns,
- BlockOnOutdatedBranch: form.BlockOnOutdatedBranch,
- }
-
- err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, models.WhitelistOptions{
- UserIDs: whitelistUsers,
- TeamIDs: whitelistTeams,
- MergeUserIDs: mergeWhitelistUsers,
- MergeTeamIDs: mergeWhitelistTeams,
- ApprovalsUserIDs: approvalsWhitelistUsers,
- ApprovalsTeamIDs: approvalsWhitelistTeams,
- })
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "UpdateProtectBranch", err)
- return
- }
-
- if err = pull_service.CheckPrsForBaseBranch(ctx.Repo.Repository, protectBranch.BranchName); err != nil {
- ctx.Error(http.StatusInternalServerError, "CheckPrsForBaseBranch", err)
- return
- }
-
- // Reload from db to get all whitelists
- bp, err := models.GetProtectedBranchBy(ctx.Repo.Repository.ID, form.BranchName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err)
- return
- }
- if bp == nil || bp.RepoID != ctx.Repo.Repository.ID {
- ctx.Error(http.StatusInternalServerError, "New branch protection not found", err)
- return
- }
-
- ctx.JSON(http.StatusCreated, convert.ToBranchProtection(bp))
-
- }
-
- // EditBranchProtection edits a branch protection for a repo
- func EditBranchProtection(ctx *context.APIContext) {
- // swagger:operation PATCH /repos/{owner}/{repo}/branch_protections/{name} repository repoEditBranchProtection
- // ---
- // summary: Edit a branch protections for a repository. Only fields that are set will be changed
- // consumes:
- // - application/json
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of protected branch
- // type: string
- // required: true
- // - name: body
- // in: body
- // schema:
- // "$ref": "#/definitions/EditBranchProtectionOption"
- // responses:
- // "200":
- // "$ref": "#/responses/BranchProtection"
- // "404":
- // "$ref": "#/responses/notFound"
- // "422":
- // "$ref": "#/responses/validationError"
- form := web.GetForm(ctx).(*api.EditBranchProtectionOption)
- repo := ctx.Repo.Repository
- bpName := ctx.Params(":name")
- protectBranch, err := models.GetProtectedBranchBy(repo.ID, bpName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err)
- return
- }
- if protectBranch == nil || protectBranch.RepoID != repo.ID {
- ctx.NotFound()
- return
- }
-
- if form.EnablePush != nil {
- if !*form.EnablePush {
- protectBranch.CanPush = false
- protectBranch.EnableWhitelist = false
- protectBranch.WhitelistDeployKeys = false
- } else {
- protectBranch.CanPush = true
- if form.EnablePushWhitelist != nil {
- if !*form.EnablePushWhitelist {
- protectBranch.EnableWhitelist = false
- protectBranch.WhitelistDeployKeys = false
- } else {
- protectBranch.EnableWhitelist = true
- if form.PushWhitelistDeployKeys != nil {
- protectBranch.WhitelistDeployKeys = *form.PushWhitelistDeployKeys
- }
- }
- }
- }
- }
-
- if form.EnableMergeWhitelist != nil {
- protectBranch.EnableMergeWhitelist = *form.EnableMergeWhitelist
- }
-
- if form.EnableStatusCheck != nil {
- protectBranch.EnableStatusCheck = *form.EnableStatusCheck
- }
- if protectBranch.EnableStatusCheck {
- protectBranch.StatusCheckContexts = form.StatusCheckContexts
- }
-
- if form.RequiredApprovals != nil && *form.RequiredApprovals >= 0 {
- protectBranch.RequiredApprovals = *form.RequiredApprovals
- }
-
- if form.EnableApprovalsWhitelist != nil {
- protectBranch.EnableApprovalsWhitelist = *form.EnableApprovalsWhitelist
- }
-
- if form.BlockOnRejectedReviews != nil {
- protectBranch.BlockOnRejectedReviews = *form.BlockOnRejectedReviews
- }
-
- if form.BlockOnOfficialReviewRequests != nil {
- protectBranch.BlockOnOfficialReviewRequests = *form.BlockOnOfficialReviewRequests
- }
-
- if form.DismissStaleApprovals != nil {
- protectBranch.DismissStaleApprovals = *form.DismissStaleApprovals
- }
-
- if form.RequireSignedCommits != nil {
- protectBranch.RequireSignedCommits = *form.RequireSignedCommits
- }
-
- if form.ProtectedFilePatterns != nil {
- protectBranch.ProtectedFilePatterns = *form.ProtectedFilePatterns
- }
-
- if form.BlockOnOutdatedBranch != nil {
- protectBranch.BlockOnOutdatedBranch = *form.BlockOnOutdatedBranch
- }
-
- var whitelistUsers []int64
- if form.PushWhitelistUsernames != nil {
- whitelistUsers, err = models.GetUserIDsByNames(form.PushWhitelistUsernames, false)
- if err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
- return
- }
- } else {
- whitelistUsers = protectBranch.WhitelistUserIDs
- }
- var mergeWhitelistUsers []int64
- if form.MergeWhitelistUsernames != nil {
- mergeWhitelistUsers, err = models.GetUserIDsByNames(form.MergeWhitelistUsernames, false)
- if err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
- return
- }
- } else {
- mergeWhitelistUsers = protectBranch.MergeWhitelistUserIDs
- }
- var approvalsWhitelistUsers []int64
- if form.ApprovalsWhitelistUsernames != nil {
- approvalsWhitelistUsers, err = models.GetUserIDsByNames(form.ApprovalsWhitelistUsernames, false)
- if err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
- return
- }
- } else {
- approvalsWhitelistUsers = protectBranch.ApprovalsWhitelistUserIDs
- }
-
- var whitelistTeams, mergeWhitelistTeams, approvalsWhitelistTeams []int64
- if repo.Owner.IsOrganization() {
- if form.PushWhitelistTeams != nil {
- whitelistTeams, err = models.GetTeamIDsByNames(repo.OwnerID, form.PushWhitelistTeams, false)
- if err != nil {
- if models.IsErrTeamNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
- return
- }
- } else {
- whitelistTeams = protectBranch.WhitelistTeamIDs
- }
- if form.MergeWhitelistTeams != nil {
- mergeWhitelistTeams, err = models.GetTeamIDsByNames(repo.OwnerID, form.MergeWhitelistTeams, false)
- if err != nil {
- if models.IsErrTeamNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
- return
- }
- } else {
- mergeWhitelistTeams = protectBranch.MergeWhitelistTeamIDs
- }
- if form.ApprovalsWhitelistTeams != nil {
- approvalsWhitelistTeams, err = models.GetTeamIDsByNames(repo.OwnerID, form.ApprovalsWhitelistTeams, false)
- if err != nil {
- if models.IsErrTeamNotExist(err) {
- ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
- return
- }
- ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
- return
- }
- } else {
- approvalsWhitelistTeams = protectBranch.ApprovalsWhitelistTeamIDs
- }
- }
-
- err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, models.WhitelistOptions{
- UserIDs: whitelistUsers,
- TeamIDs: whitelistTeams,
- MergeUserIDs: mergeWhitelistUsers,
- MergeTeamIDs: mergeWhitelistTeams,
- ApprovalsUserIDs: approvalsWhitelistUsers,
- ApprovalsTeamIDs: approvalsWhitelistTeams,
- })
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "UpdateProtectBranch", err)
- return
- }
-
- if err = pull_service.CheckPrsForBaseBranch(ctx.Repo.Repository, protectBranch.BranchName); err != nil {
- ctx.Error(http.StatusInternalServerError, "CheckPrsForBaseBranch", err)
- return
- }
-
- // Reload from db to ensure get all whitelists
- bp, err := models.GetProtectedBranchBy(repo.ID, bpName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetProtectedBranchBy", err)
- return
- }
- if bp == nil || bp.RepoID != ctx.Repo.Repository.ID {
- ctx.Error(http.StatusInternalServerError, "New branch protection not found", err)
- return
- }
-
- ctx.JSON(http.StatusOK, convert.ToBranchProtection(bp))
- }
-
- // DeleteBranchProtection deletes a branch protection for a repo
- func DeleteBranchProtection(ctx *context.APIContext) {
- // swagger:operation DELETE /repos/{owner}/{repo}/branch_protections/{name} repository repoDeleteBranchProtection
- // ---
- // summary: Delete a specific branch protection for the repository
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: name
- // in: path
- // description: name of protected branch
- // type: string
- // required: true
- // responses:
- // "204":
- // "$ref": "#/responses/empty"
- // "404":
- // "$ref": "#/responses/notFound"
-
- repo := ctx.Repo.Repository
- bpName := ctx.Params(":name")
- bp, err := models.GetProtectedBranchBy(repo.ID, bpName)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err)
- return
- }
- if bp == nil || bp.RepoID != repo.ID {
- ctx.NotFound()
- return
- }
-
- if err := ctx.Repo.Repository.DeleteProtectedBranch(bp.ID); err != nil {
- ctx.Error(http.StatusInternalServerError, "DeleteProtectedBranch", err)
- return
- }
-
- ctx.Status(http.StatusNoContent)
- }
|