本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

250 lines
7.9KB

  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package repo
  5. import (
  6. "fmt"
  7. "strings"
  8. "time"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/auth"
  11. "code.gitea.io/gitea/modules/base"
  12. "code.gitea.io/gitea/modules/context"
  13. "code.gitea.io/gitea/modules/git"
  14. "code.gitea.io/gitea/modules/log"
  15. "code.gitea.io/gitea/modules/setting"
  16. )
  17. // ProtectedBranch render the page to protect the repository
  18. func ProtectedBranch(ctx *context.Context) {
  19. ctx.Data["Title"] = ctx.Tr("repo.settings")
  20. ctx.Data["PageIsSettingsBranches"] = true
  21. protectedBranches, err := ctx.Repo.Repository.GetProtectedBranches()
  22. if err != nil {
  23. ctx.ServerError("GetProtectedBranches", err)
  24. return
  25. }
  26. ctx.Data["ProtectedBranches"] = protectedBranches
  27. branches := ctx.Data["Branches"].([]string)
  28. leftBranches := make([]string, 0, len(branches)-len(protectedBranches))
  29. for _, b := range branches {
  30. var protected bool
  31. for _, pb := range protectedBranches {
  32. if b == pb.BranchName {
  33. protected = true
  34. break
  35. }
  36. }
  37. if !protected {
  38. leftBranches = append(leftBranches, b)
  39. }
  40. }
  41. ctx.Data["LeftBranches"] = leftBranches
  42. ctx.HTML(200, tplBranches)
  43. }
  44. // ProtectedBranchPost response for protect for a branch of a repository
  45. func ProtectedBranchPost(ctx *context.Context) {
  46. ctx.Data["Title"] = ctx.Tr("repo.settings")
  47. ctx.Data["PageIsSettingsBranches"] = true
  48. repo := ctx.Repo.Repository
  49. switch ctx.Query("action") {
  50. case "default_branch":
  51. if ctx.HasError() {
  52. ctx.HTML(200, tplBranches)
  53. return
  54. }
  55. branch := ctx.Query("branch")
  56. if !ctx.Repo.GitRepo.IsBranchExist(branch) {
  57. ctx.Status(404)
  58. return
  59. } else if repo.DefaultBranch != branch {
  60. repo.DefaultBranch = branch
  61. if err := ctx.Repo.GitRepo.SetDefaultBranch(branch); err != nil {
  62. if !git.IsErrUnsupportedVersion(err) {
  63. ctx.ServerError("SetDefaultBranch", err)
  64. return
  65. }
  66. }
  67. if err := repo.UpdateDefaultBranch(); err != nil {
  68. ctx.ServerError("SetDefaultBranch", err)
  69. return
  70. }
  71. }
  72. log.Trace("Repository basic settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
  73. ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
  74. ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
  75. default:
  76. ctx.NotFound("", nil)
  77. }
  78. }
  79. // SettingsProtectedBranch renders the protected branch setting page
  80. func SettingsProtectedBranch(c *context.Context) {
  81. branch := c.Params("*")
  82. if !c.Repo.GitRepo.IsBranchExist(branch) {
  83. c.NotFound("IsBranchExist", nil)
  84. return
  85. }
  86. c.Data["Title"] = c.Tr("repo.settings.protected_branch") + " - " + branch
  87. c.Data["PageIsSettingsBranches"] = true
  88. protectBranch, err := models.GetProtectedBranchBy(c.Repo.Repository.ID, branch)
  89. if err != nil {
  90. if !git.IsErrBranchNotExist(err) {
  91. c.ServerError("GetProtectBranchOfRepoByName", err)
  92. return
  93. }
  94. }
  95. if protectBranch == nil {
  96. // No options found, create defaults.
  97. protectBranch = &models.ProtectedBranch{
  98. BranchName: branch,
  99. }
  100. }
  101. users, err := c.Repo.Repository.GetReaders()
  102. if err != nil {
  103. c.ServerError("Repo.Repository.GetReaders", err)
  104. return
  105. }
  106. c.Data["Users"] = users
  107. c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistUserIDs), ",")
  108. c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistUserIDs), ",")
  109. c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.ApprovalsWhitelistUserIDs), ",")
  110. contexts, _ := models.FindRepoRecentCommitStatusContexts(c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts
  111. for _, context := range protectBranch.StatusCheckContexts {
  112. var found bool
  113. for _, ctx := range contexts {
  114. if ctx == context {
  115. found = true
  116. break
  117. }
  118. }
  119. if !found {
  120. contexts = append(contexts, context)
  121. }
  122. }
  123. c.Data["branch_status_check_contexts"] = contexts
  124. c.Data["is_context_required"] = func(context string) bool {
  125. for _, c := range protectBranch.StatusCheckContexts {
  126. if c == context {
  127. return true
  128. }
  129. }
  130. return false
  131. }
  132. if c.Repo.Owner.IsOrganization() {
  133. teams, err := c.Repo.Owner.TeamsWithAccessToRepo(c.Repo.Repository.ID, models.AccessModeRead)
  134. if err != nil {
  135. c.ServerError("Repo.Owner.TeamsWithAccessToRepo", err)
  136. return
  137. }
  138. c.Data["Teams"] = teams
  139. c.Data["whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.WhitelistTeamIDs), ",")
  140. c.Data["merge_whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistTeamIDs), ",")
  141. c.Data["approvals_whitelist_teams"] = strings.Join(base.Int64sToStrings(protectBranch.ApprovalsWhitelistTeamIDs), ",")
  142. }
  143. c.Data["Branch"] = protectBranch
  144. c.HTML(200, tplProtectedBranch)
  145. }
  146. // SettingsProtectedBranchPost updates the protected branch settings
  147. func SettingsProtectedBranchPost(ctx *context.Context, f auth.ProtectBranchForm) {
  148. branch := ctx.Params("*")
  149. if !ctx.Repo.GitRepo.IsBranchExist(branch) {
  150. ctx.NotFound("IsBranchExist", nil)
  151. return
  152. }
  153. protectBranch, err := models.GetProtectedBranchBy(ctx.Repo.Repository.ID, branch)
  154. if err != nil {
  155. if !git.IsErrBranchNotExist(err) {
  156. ctx.ServerError("GetProtectBranchOfRepoByName", err)
  157. return
  158. }
  159. }
  160. if f.Protected {
  161. if protectBranch == nil {
  162. // No options found, create defaults.
  163. protectBranch = &models.ProtectedBranch{
  164. RepoID: ctx.Repo.Repository.ID,
  165. BranchName: branch,
  166. }
  167. }
  168. if f.RequiredApprovals < 0 {
  169. ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_required_approvals_min"))
  170. ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, branch))
  171. }
  172. var whitelistUsers, whitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams, approvalsWhitelistUsers, approvalsWhitelistTeams []int64
  173. protectBranch.EnableWhitelist = f.EnableWhitelist
  174. if strings.TrimSpace(f.WhitelistUsers) != "" {
  175. whitelistUsers, _ = base.StringsToInt64s(strings.Split(f.WhitelistUsers, ","))
  176. }
  177. if strings.TrimSpace(f.WhitelistTeams) != "" {
  178. whitelistTeams, _ = base.StringsToInt64s(strings.Split(f.WhitelistTeams, ","))
  179. }
  180. protectBranch.EnableMergeWhitelist = f.EnableMergeWhitelist
  181. if strings.TrimSpace(f.MergeWhitelistUsers) != "" {
  182. mergeWhitelistUsers, _ = base.StringsToInt64s(strings.Split(f.MergeWhitelistUsers, ","))
  183. }
  184. if strings.TrimSpace(f.MergeWhitelistTeams) != "" {
  185. mergeWhitelistTeams, _ = base.StringsToInt64s(strings.Split(f.MergeWhitelistTeams, ","))
  186. }
  187. protectBranch.EnableStatusCheck = f.EnableStatusCheck
  188. protectBranch.StatusCheckContexts = f.StatusCheckContexts
  189. protectBranch.WhitelistDeployKeys = f.WhitelistDeployKeys
  190. protectBranch.RequiredApprovals = f.RequiredApprovals
  191. if strings.TrimSpace(f.ApprovalsWhitelistUsers) != "" {
  192. approvalsWhitelistUsers, _ = base.StringsToInt64s(strings.Split(f.ApprovalsWhitelistUsers, ","))
  193. }
  194. if strings.TrimSpace(f.ApprovalsWhitelistTeams) != "" {
  195. approvalsWhitelistTeams, _ = base.StringsToInt64s(strings.Split(f.ApprovalsWhitelistTeams, ","))
  196. }
  197. err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, models.WhitelistOptions{
  198. UserIDs: whitelistUsers,
  199. TeamIDs: whitelistTeams,
  200. MergeUserIDs: mergeWhitelistUsers,
  201. MergeTeamIDs: mergeWhitelistTeams,
  202. ApprovalsUserIDs: approvalsWhitelistUsers,
  203. ApprovalsTeamIDs: approvalsWhitelistTeams,
  204. })
  205. if err != nil {
  206. ctx.ServerError("UpdateProtectBranch", err)
  207. return
  208. }
  209. ctx.Flash.Success(ctx.Tr("repo.settings.update_protect_branch_success", branch))
  210. ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, branch))
  211. } else {
  212. if protectBranch != nil {
  213. if err := ctx.Repo.Repository.DeleteProtectedBranch(protectBranch.ID); err != nil {
  214. ctx.ServerError("DeleteProtectedBranch", err)
  215. return
  216. }
  217. }
  218. ctx.Flash.Success(ctx.Tr("repo.settings.remove_protected_branch_success", branch))
  219. ctx.Redirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink))
  220. }
  221. }
上海开阖软件有限公司 沪ICP备12045867号-1