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.

124 lines
3.7 KiB

  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 private
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "net/http"
  9. "net/url"
  10. "time"
  11. "code.gitea.io/gitea/modules/setting"
  12. )
  13. // Git environment variables
  14. const (
  15. GitAlternativeObjectDirectories = "GIT_ALTERNATE_OBJECT_DIRECTORIES"
  16. GitObjectDirectory = "GIT_OBJECT_DIRECTORY"
  17. GitQuarantinePath = "GIT_QUARANTINE_PATH"
  18. )
  19. // HookOptions represents the options for the Hook calls
  20. type HookOptions struct {
  21. OldCommitIDs []string
  22. NewCommitIDs []string
  23. RefFullNames []string
  24. UserID int64
  25. UserName string
  26. GitObjectDirectory string
  27. GitAlternativeObjectDirectories string
  28. GitQuarantinePath string
  29. ProtectedBranchID int64
  30. IsDeployKey bool
  31. }
  32. // HookPostReceiveResult represents an individual result from PostReceive
  33. type HookPostReceiveResult struct {
  34. Results []HookPostReceiveBranchResult
  35. RepoWasEmpty bool
  36. Err string
  37. }
  38. // HookPostReceiveBranchResult represents an individual branch result from PostReceive
  39. type HookPostReceiveBranchResult struct {
  40. Message bool
  41. Create bool
  42. Branch string
  43. URL string
  44. }
  45. // HookPreReceive check whether the provided commits are allowed
  46. func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string) {
  47. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s",
  48. url.PathEscape(ownerName),
  49. url.PathEscape(repoName),
  50. )
  51. req := newInternalRequest(reqURL, "POST")
  52. req = req.Header("Content-Type", "application/json")
  53. jsonBytes, _ := json.Marshal(opts)
  54. req.Body(jsonBytes)
  55. req.SetTimeout(60*time.Second, time.Duration(60+len(opts.OldCommitIDs))*time.Second)
  56. resp, err := req.Response()
  57. if err != nil {
  58. return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
  59. }
  60. defer resp.Body.Close()
  61. if resp.StatusCode != http.StatusOK {
  62. return resp.StatusCode, decodeJSONError(resp).Err
  63. }
  64. return http.StatusOK, ""
  65. }
  66. // HookPostReceive updates services and users
  67. func HookPostReceive(ownerName, repoName string, opts HookOptions) (*HookPostReceiveResult, string) {
  68. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/post-receive/%s/%s",
  69. url.PathEscape(ownerName),
  70. url.PathEscape(repoName),
  71. )
  72. req := newInternalRequest(reqURL, "POST")
  73. req = req.Header("Content-Type", "application/json")
  74. req.SetTimeout(60*time.Second, time.Duration(60+len(opts.OldCommitIDs))*time.Second)
  75. jsonBytes, _ := json.Marshal(opts)
  76. req.Body(jsonBytes)
  77. resp, err := req.Response()
  78. if err != nil {
  79. return nil, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
  80. }
  81. defer resp.Body.Close()
  82. if resp.StatusCode != http.StatusOK {
  83. return nil, decodeJSONError(resp).Err
  84. }
  85. res := &HookPostReceiveResult{}
  86. _ = json.NewDecoder(resp.Body).Decode(res)
  87. return res, ""
  88. }
  89. // SetDefaultBranch will set the default branch to the provided branch for the provided repository
  90. func SetDefaultBranch(ownerName, repoName, branch string) error {
  91. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/set-default-branch/%s/%s/%s",
  92. url.PathEscape(ownerName),
  93. url.PathEscape(repoName),
  94. url.PathEscape(branch),
  95. )
  96. req := newInternalRequest(reqURL, "POST")
  97. req = req.Header("Content-Type", "application/json")
  98. req.SetTimeout(60*time.Second, 60*time.Second)
  99. resp, err := req.Response()
  100. if err != nil {
  101. return fmt.Errorf("Unable to contact gitea: %v", err)
  102. }
  103. defer resp.Body.Close()
  104. if resp.StatusCode != http.StatusOK {
  105. return fmt.Errorf("Error returned from gitea: %v", decodeJSONError(resp).Err)
  106. }
  107. return nil
  108. }