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.

issue_dependency.go 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2018 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package repo
  4. import (
  5. "net/http"
  6. issues_model "code.gitea.io/gitea/models/issues"
  7. access_model "code.gitea.io/gitea/models/perm/access"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/setting"
  10. )
  11. // AddDependency adds new dependencies
  12. func AddDependency(ctx *context.Context) {
  13. issueIndex := ctx.ParamsInt64("index")
  14. issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, issueIndex)
  15. if err != nil {
  16. ctx.ServerError("GetIssueByIndex", err)
  17. return
  18. }
  19. // Check if the Repo is allowed to have dependencies
  20. if !ctx.Repo.CanCreateIssueDependencies(ctx.Doer, issue.IsPull) {
  21. ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
  22. return
  23. }
  24. depID := ctx.FormInt64("newDependency")
  25. if err = issue.LoadRepo(ctx); err != nil {
  26. ctx.ServerError("LoadRepo", err)
  27. return
  28. }
  29. // Redirect
  30. defer ctx.Redirect(issue.Link())
  31. // Dependency
  32. dep, err := issues_model.GetIssueByID(ctx, depID)
  33. if err != nil {
  34. ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_issue_not_exist"))
  35. return
  36. }
  37. // Check if both issues are in the same repo if cross repository dependencies is not enabled
  38. if issue.RepoID != dep.RepoID {
  39. if !setting.Service.AllowCrossRepositoryDependencies {
  40. ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_same_repo"))
  41. return
  42. }
  43. if err := dep.LoadRepo(ctx); err != nil {
  44. ctx.ServerError("loadRepo", err)
  45. return
  46. }
  47. // Can ctx.Doer read issues in the dep repo?
  48. depRepoPerm, err := access_model.GetUserRepoPermission(ctx, dep.Repo, ctx.Doer)
  49. if err != nil {
  50. ctx.ServerError("GetUserRepoPermission", err)
  51. return
  52. }
  53. if !depRepoPerm.CanReadIssuesOrPulls(dep.IsPull) {
  54. // you can't see this dependency
  55. return
  56. }
  57. }
  58. // Check if issue and dependency is the same
  59. if dep.ID == issue.ID {
  60. ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_same_issue"))
  61. return
  62. }
  63. err = issues_model.CreateIssueDependency(ctx.Doer, issue, dep)
  64. if err != nil {
  65. if issues_model.IsErrDependencyExists(err) {
  66. ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_exists"))
  67. return
  68. } else if issues_model.IsErrCircularDependency(err) {
  69. ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_cannot_create_circular"))
  70. return
  71. } else {
  72. ctx.ServerError("CreateOrUpdateIssueDependency", err)
  73. return
  74. }
  75. }
  76. }
  77. // RemoveDependency removes the dependency
  78. func RemoveDependency(ctx *context.Context) {
  79. issueIndex := ctx.ParamsInt64("index")
  80. issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, issueIndex)
  81. if err != nil {
  82. ctx.ServerError("GetIssueByIndex", err)
  83. return
  84. }
  85. // Check if the Repo is allowed to have dependencies
  86. if !ctx.Repo.CanCreateIssueDependencies(ctx.Doer, issue.IsPull) {
  87. ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
  88. return
  89. }
  90. depID := ctx.FormInt64("removeDependencyID")
  91. if err = issue.LoadRepo(ctx); err != nil {
  92. ctx.ServerError("LoadRepo", err)
  93. return
  94. }
  95. // Dependency Type
  96. depTypeStr := ctx.Req.PostForm.Get("dependencyType")
  97. var depType issues_model.DependencyType
  98. switch depTypeStr {
  99. case "blockedBy":
  100. depType = issues_model.DependencyTypeBlockedBy
  101. case "blocking":
  102. depType = issues_model.DependencyTypeBlocking
  103. default:
  104. ctx.Error(http.StatusBadRequest, "GetDependecyType")
  105. return
  106. }
  107. // Dependency
  108. dep, err := issues_model.GetIssueByID(ctx, depID)
  109. if err != nil {
  110. ctx.ServerError("GetIssueByID", err)
  111. return
  112. }
  113. if err = issues_model.RemoveIssueDependency(ctx.Doer, issue, dep, depType); err != nil {
  114. if issues_model.IsErrDependencyNotExists(err) {
  115. ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_exist"))
  116. return
  117. }
  118. ctx.ServerError("RemoveIssueDependency", err)
  119. return
  120. }
  121. // Redirect
  122. ctx.Redirect(issue.Link())
  123. }