2016-01-28 22:49:05 +03:00
// Copyright 2016 The Gogs Authors. All rights reserved.
2019-04-19 15:17:27 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
2016-01-15 21:24:03 +03:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repo
import (
2020-04-19 05:38:09 +03:00
"fmt"
2019-12-20 20:07:12 +03:00
"net/http"
2020-02-13 02:19:35 +03:00
"code.gitea.io/gitea/models"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/context"
2019-11-10 07:41:51 +03:00
"code.gitea.io/gitea/modules/convert"
2019-04-19 15:17:27 +03:00
"code.gitea.io/gitea/modules/git"
2020-04-19 05:38:09 +03:00
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repofiles"
2020-01-14 06:38:04 +03:00
repo_module "code.gitea.io/gitea/modules/repository"
2019-05-11 13:21:34 +03:00
api "code.gitea.io/gitea/modules/structs"
2016-01-15 21:24:03 +03:00
)
2016-11-24 10:04:31 +03:00
// GetBranch get a branch of a repository
2016-03-14 01:49:16 +03:00
func GetBranch ( ctx * context . APIContext ) {
2017-11-13 10:02:25 +03:00
// swagger:operation GET /repos/{owner}/{repo}/branches/{branch} repository repoGetBranch
// ---
2019-11-16 22:39:18 +03:00
// summary: Retrieve a specific branch from a repository, including its effective branch protection
2017-11-13 10:02:25 +03:00
// 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"
2019-12-20 20:07:12 +03:00
2017-07-02 05:03:57 +03:00
if ctx . Repo . TreePath != "" {
// if TreePath != "", then URL contained extra slashes
// (i.e. "master/subbranch" instead of "master"), so branch does
// not exist
2019-03-19 05:29:43 +03:00
ctx . NotFound ( )
2017-07-02 05:03:57 +03:00
return
}
2020-01-14 06:38:04 +03:00
branch , err := repo_module . GetBranch ( ctx . Repo . Repository , ctx . Repo . BranchName )
2016-01-15 21:24:03 +03:00
if err != nil {
2019-04-19 15:17:27 +03:00
if git . IsErrBranchNotExist ( err ) {
2019-03-19 05:29:43 +03:00
ctx . NotFound ( err )
2017-06-11 05:57:28 +03:00
} else {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetBranch" , err )
2017-06-11 05:57:28 +03:00
}
2016-01-15 21:24:03 +03:00
return
}
2016-02-03 01:07:40 +03:00
2016-01-15 21:24:03 +03:00
c , err := branch . GetCommit ( )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetCommit" , err )
2016-01-15 21:24:03 +03:00
return
}
2016-02-03 01:07:40 +03:00
2019-11-16 22:39:18 +03:00
branchProtection , err := ctx . Repo . Repository . GetBranchProtection ( ctx . Repo . BranchName )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetBranchProtection" , err )
2019-11-16 22:39:18 +03:00
return
}
2020-03-21 06:41:33 +03:00
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 )
2016-01-15 21:24:03 +03:00
}
2020-04-19 05:38:09 +03:00
// 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"
if ctx . Repo . TreePath != "" {
// if TreePath != "", then URL contained extra slashes
// (i.e. "master/subbranch" instead of "master"), so branch does
// not exist
ctx . NotFound ( )
return
}
if ctx . Repo . Repository . DefaultBranch == ctx . Repo . BranchName {
ctx . Error ( http . StatusForbidden , "DefaultBranch" , fmt . Errorf ( "can not delete default branch" ) )
return
}
isProtected , err := ctx . Repo . Repository . IsProtectedBranch ( ctx . Repo . BranchName , ctx . User )
if err != nil {
ctx . InternalServerError ( err )
return
}
if isProtected {
ctx . Error ( http . StatusForbidden , "IsProtectedBranch" , fmt . Errorf ( "branch protected" ) )
return
}
branch , err := repo_module . GetBranch ( ctx . Repo . Repository , ctx . Repo . 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
}
if err := ctx . Repo . GitRepo . DeleteBranch ( ctx . Repo . BranchName , git . DeleteBranchOptions {
Force : true ,
} ) ; err != nil {
ctx . Error ( http . StatusInternalServerError , "DeleteBranch" , err )
return
}
// Don't return error below this
if err := repofiles . PushUpdate (
ctx . Repo . Repository ,
ctx . Repo . BranchName ,
repofiles . PushUpdateOptions {
RefFullName : git . BranchPrefix + ctx . Repo . BranchName ,
OldCommitID : c . ID . String ( ) ,
NewCommitID : git . EmptySHA ,
PusherID : ctx . User . ID ,
PusherName : ctx . User . Name ,
RepoUserName : ctx . Repo . Owner . Name ,
RepoName : ctx . Repo . Repository . Name ,
} ) ; err != nil {
log . Error ( "Update: %v" , err )
}
if err := ctx . Repo . Repository . AddDeletedBranch ( ctx . Repo . BranchName , c . ID . String ( ) , ctx . User . ID ) ; err != nil {
log . Warn ( "AddDeletedBranch: %v" , err )
}
ctx . Status ( http . StatusNoContent )
}
2020-05-29 21:16:20 +03:00
// CreateBranch creates a branch for a user's repository
func CreateBranch ( ctx * context . APIContext , opt api . CreateBranchRepoOption ) {
// 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.
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 )
}
2016-11-24 10:04:31 +03:00
// ListBranches list all the branches of a repository
2016-03-14 01:49:16 +03:00
func ListBranches ( ctx * context . APIContext ) {
2017-11-13 10:02:25 +03:00
// 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
// responses:
// "200":
// "$ref": "#/responses/BranchList"
2019-12-20 20:07:12 +03:00
2020-01-14 06:38:04 +03:00
branches , err := repo_module . GetBranches ( ctx . Repo . Repository )
2016-01-15 21:24:03 +03:00
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetBranches" , err )
2016-01-15 21:24:03 +03:00
return
}
2016-02-03 01:07:40 +03:00
apiBranches := make ( [ ] * api . Branch , len ( branches ) )
for i := range branches {
c , err := branches [ i ] . GetCommit ( )
2016-01-15 21:24:03 +03:00
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetCommit" , err )
2016-01-16 12:36:16 +03:00
return
2016-01-15 21:24:03 +03:00
}
2019-11-16 22:39:18 +03:00
branchProtection , err := ctx . Repo . Repository . GetBranchProtection ( branches [ i ] . Name )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetBranchProtection" , err )
2019-11-16 22:39:18 +03:00
return
}
2020-03-21 06:41:33 +03:00
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
}
2016-01-15 21:24:03 +03:00
}
2016-02-03 01:07:40 +03:00
2019-12-20 20:07:12 +03:00
ctx . JSON ( http . StatusOK , & apiBranches )
2016-01-15 21:24:03 +03:00
}
2020-02-13 02:19:35 +03:00
// 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 , form api . CreateBranchProtectionOption ) {
// 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"
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 ,
DismissStaleApprovals : form . DismissStaleApprovals ,
RequireSignedCommits : form . RequireSignedCommits ,
2020-03-27 01:26:34 +03:00
ProtectedFilePatterns : form . ProtectedFilePatterns ,
2020-04-17 04:00:36 +03:00
BlockOnOutdatedBranch : form . BlockOnOutdatedBranch ,
2020-02-13 02:19:35 +03:00
}
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
}
// 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 , form api . EditBranchProtectionOption ) {
// 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"
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 . DismissStaleApprovals != nil {
protectBranch . DismissStaleApprovals = * form . DismissStaleApprovals
}
if form . RequireSignedCommits != nil {
protectBranch . RequireSignedCommits = * form . RequireSignedCommits
}
2020-03-27 01:26:34 +03:00
if form . ProtectedFilePatterns != nil {
protectBranch . ProtectedFilePatterns = * form . ProtectedFilePatterns
}
2020-04-17 04:00:36 +03:00
if form . BlockOnOutdatedBranch != nil {
protectBranch . BlockOnOutdatedBranch = * form . BlockOnOutdatedBranch
}
2020-02-13 02:19:35 +03:00
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
}
// 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 )
}