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.

pull_sign.go 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2019 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 models
  5. import (
  6. "code.gitea.io/gitea/modules/git"
  7. "code.gitea.io/gitea/modules/log"
  8. "code.gitea.io/gitea/modules/setting"
  9. )
  10. // SignMerge determines if we should sign a PR merge commit to the base repository
  11. func (pr *PullRequest) SignMerge(u *User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) {
  12. if err := pr.LoadBaseRepo(); err != nil {
  13. log.Error("Unable to get Base Repo for pull request")
  14. return false, "", nil, err
  15. }
  16. repo := pr.BaseRepo
  17. signingKey, signer := SigningKey(repo.RepoPath())
  18. if signingKey == "" {
  19. return false, "", nil, &ErrWontSign{noKey}
  20. }
  21. rules := signingModeFromStrings(setting.Repository.Signing.Merges)
  22. var gitRepo *git.Repository
  23. var err error
  24. Loop:
  25. for _, rule := range rules {
  26. switch rule {
  27. case never:
  28. return false, "", nil, &ErrWontSign{never}
  29. case always:
  30. break Loop
  31. case pubkey:
  32. keys, err := ListGPGKeys(u.ID, ListOptions{})
  33. if err != nil {
  34. return false, "", nil, err
  35. }
  36. if len(keys) == 0 {
  37. return false, "", nil, &ErrWontSign{pubkey}
  38. }
  39. case twofa:
  40. twofaModel, err := GetTwoFactorByUID(u.ID)
  41. if err != nil && !IsErrTwoFactorNotEnrolled(err) {
  42. return false, "", nil, err
  43. }
  44. if twofaModel == nil {
  45. return false, "", nil, &ErrWontSign{twofa}
  46. }
  47. case approved:
  48. protectedBranch, err := GetProtectedBranchBy(repo.ID, pr.BaseBranch)
  49. if err != nil {
  50. return false, "", nil, err
  51. }
  52. if protectedBranch == nil {
  53. return false, "", nil, &ErrWontSign{approved}
  54. }
  55. if protectedBranch.GetGrantedApprovalsCount(pr) < 1 {
  56. return false, "", nil, &ErrWontSign{approved}
  57. }
  58. case baseSigned:
  59. if gitRepo == nil {
  60. gitRepo, err = git.OpenRepository(tmpBasePath)
  61. if err != nil {
  62. return false, "", nil, err
  63. }
  64. defer gitRepo.Close()
  65. }
  66. commit, err := gitRepo.GetCommit(baseCommit)
  67. if err != nil {
  68. return false, "", nil, err
  69. }
  70. verification := ParseCommitWithSignature(commit)
  71. if !verification.Verified {
  72. return false, "", nil, &ErrWontSign{baseSigned}
  73. }
  74. case headSigned:
  75. if gitRepo == nil {
  76. gitRepo, err = git.OpenRepository(tmpBasePath)
  77. if err != nil {
  78. return false, "", nil, err
  79. }
  80. defer gitRepo.Close()
  81. }
  82. commit, err := gitRepo.GetCommit(headCommit)
  83. if err != nil {
  84. return false, "", nil, err
  85. }
  86. verification := ParseCommitWithSignature(commit)
  87. if !verification.Verified {
  88. return false, "", nil, &ErrWontSign{headSigned}
  89. }
  90. case commitsSigned:
  91. if gitRepo == nil {
  92. gitRepo, err = git.OpenRepository(tmpBasePath)
  93. if err != nil {
  94. return false, "", nil, err
  95. }
  96. defer gitRepo.Close()
  97. }
  98. commit, err := gitRepo.GetCommit(headCommit)
  99. if err != nil {
  100. return false, "", nil, err
  101. }
  102. verification := ParseCommitWithSignature(commit)
  103. if !verification.Verified {
  104. return false, "", nil, &ErrWontSign{commitsSigned}
  105. }
  106. // need to work out merge-base
  107. mergeBaseCommit, _, err := gitRepo.GetMergeBase("", baseCommit, headCommit)
  108. if err != nil {
  109. return false, "", nil, err
  110. }
  111. commitList, err := commit.CommitsBeforeUntil(mergeBaseCommit)
  112. if err != nil {
  113. return false, "", nil, err
  114. }
  115. for e := commitList.Front(); e != nil; e = e.Next() {
  116. commit = e.Value.(*git.Commit)
  117. verification := ParseCommitWithSignature(commit)
  118. if !verification.Verified {
  119. return false, "", nil, &ErrWontSign{commitsSigned}
  120. }
  121. }
  122. }
  123. }
  124. return true, signingKey, signer, nil
  125. }