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

migrate.go 4.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package repository
  2. import (
  3. "code.gitea.io/gitea/models"
  4. "code.gitea.io/gitea/modules/auth"
  5. "code.gitea.io/gitea/modules/log"
  6. "code.gitea.io/gitea/modules/migrations"
  7. "code.gitea.io/gitea/modules/setting"
  8. api "code.gitea.io/gitea/modules/structs"
  9. "code.gitea.io/gitea/modules/task"
  10. "code.gitea.io/gitea/modules/util"
  11. "code.gitea.io/gitea/routers/response"
  12. "errors"
  13. "fmt"
  14. "net/url"
  15. "strings"
  16. )
  17. func MigrateSubmit(currentUser *models.User, form auth.MigrateRepoForm) *response.BizError {
  18. log.Info("receive MigrateSubmit request")
  19. ctxUser, bizErr := checkMigrateUser(currentUser, form.UID)
  20. if bizErr != nil {
  21. return bizErr
  22. }
  23. remoteAddr, err := form.ParseRemoteAddr(currentUser)
  24. if err != nil {
  25. if models.IsErrInvalidCloneAddr(err) {
  26. addrErr := err.(models.ErrInvalidCloneAddr)
  27. switch {
  28. case addrErr.IsURLError:
  29. return response.PARAM_ERROR
  30. case addrErr.IsPermissionDenied:
  31. return response.INSUFFICIENT_PERMISSION
  32. case addrErr.IsInvalidPath:
  33. return response.PARAM_ERROR
  34. default:
  35. }
  36. }
  37. return response.NewBizError(err)
  38. }
  39. var gitServiceType = api.PlainGitService
  40. u, err := url.Parse(form.CloneAddr)
  41. if err == nil && strings.EqualFold(u.Host, "github.com") {
  42. gitServiceType = api.GithubService
  43. }
  44. var opts = migrations.MigrateOptions{
  45. OriginalURL: form.CloneAddr,
  46. GitServiceType: gitServiceType,
  47. CloneAddr: remoteAddr,
  48. RepoName: form.RepoName,
  49. Alias: form.Alias,
  50. Description: form.Description,
  51. Private: form.Private || setting.Repository.ForcePrivate,
  52. Mirror: form.Mirror,
  53. AuthUsername: form.AuthUsername,
  54. AuthPassword: form.AuthPassword,
  55. Wiki: form.Wiki,
  56. Issues: form.Issues,
  57. Milestones: form.Milestones,
  58. Labels: form.Labels,
  59. Comments: true,
  60. PullRequests: form.PullRequests,
  61. Releases: form.Releases,
  62. }
  63. if opts.Mirror {
  64. opts.Issues = false
  65. opts.Milestones = false
  66. opts.Labels = false
  67. opts.Comments = false
  68. opts.PullRequests = false
  69. opts.Releases = false
  70. }
  71. err = models.CheckCreateRepository(currentUser, ctxUser, opts.RepoName, opts.Alias)
  72. if err != nil {
  73. return handleMigrateError4Api(ctxUser, remoteAddr, err)
  74. }
  75. err = task.MigrateRepository(currentUser, ctxUser, opts)
  76. if err != nil {
  77. return handleMigrateError4Api(ctxUser, remoteAddr, err)
  78. }
  79. return nil
  80. }
  81. func checkMigrateUser(currentUser *models.User, uid int64) (*models.User, *response.BizError) {
  82. if uid == currentUser.ID || uid == 0 {
  83. return currentUser, nil
  84. }
  85. org, err := models.GetUserByID(uid)
  86. if models.IsErrUserNotExist(err) {
  87. return currentUser, nil
  88. }
  89. if err != nil {
  90. return nil, response.SYSTEM_ERROR
  91. }
  92. // Check ownership of organization.
  93. if !org.IsOrganization() {
  94. return nil, nil
  95. }
  96. if !currentUser.IsAdmin {
  97. canCreate, err := org.CanCreateOrgRepo(currentUser.ID)
  98. if err != nil {
  99. return nil, response.NewBizError(err)
  100. } else if !canCreate {
  101. return nil, response.INSUFFICIENT_PERMISSION
  102. }
  103. }
  104. return org, nil
  105. }
  106. func handleMigrateError4Api(repoOwner *models.User, remoteAddr string, err error) *response.BizError {
  107. switch {
  108. case models.IsErrRepoAlreadyExist(err):
  109. return response.BuildBizError(3, "The repository with the same name already exists.")
  110. case migrations.IsRateLimitError(err):
  111. return response.NewBizError(errors.New("Remote visit addressed rate limitation."))
  112. case migrations.IsTwoFactorAuthError(err):
  113. return response.NewBizError(errors.New("Remote visit required two factors authentication."))
  114. case models.IsErrReachLimitOfRepo(err):
  115. return response.NewBizError(errors.New(fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit())))
  116. case models.IsErrNameReserved(err):
  117. return response.NewBizError(errors.New(fmt.Sprintf("The username '%s' is reserved.", err.(models.ErrNameReserved).Name)))
  118. case models.IsErrNameCharsNotAllowed(err):
  119. return response.NewBizError(errors.New(fmt.Sprintf("The username '%s' contains invalid characters.", err.(models.ErrNameCharsNotAllowed).Name)))
  120. case models.IsErrNamePatternNotAllowed(err):
  121. return response.NewBizError(errors.New(fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(models.ErrNamePatternNotAllowed).Pattern)))
  122. default:
  123. err = util.URLSanitizedError(err, remoteAddr)
  124. if strings.Contains(err.Error(), "Authentication failed") ||
  125. strings.Contains(err.Error(), "Bad credentials") ||
  126. strings.Contains(err.Error(), "could not read Username") {
  127. return response.NewBizError(errors.New((fmt.Sprintf("Authentication failed: %v.", err))))
  128. } else if strings.Contains(err.Error(), "fatal:") {
  129. return response.NewBizError(errors.New((fmt.Sprintf("Migration failed: %v.", err))))
  130. }
  131. }
  132. return response.NewBizError(err)
  133. }