summaryrefslogtreecommitdiffstats
path: root/routers/web/repo/issue_dependency.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-10-18 20:33:49 +0200
committerDaniel Baumann <daniel@debian.org>2024-10-18 20:33:49 +0200
commitdd136858f1ea40ad3c94191d647487fa4f31926c (patch)
tree58fec94a7b2a12510c9664b21793f1ed560c6518 /routers/web/repo/issue_dependency.go
parentInitial commit. (diff)
downloadforgejo-debian.tar.xz
forgejo-debian.zip
Adding upstream version 9.0.0.upstream/9.0.0upstreamdebian
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'routers/web/repo/issue_dependency.go')
-rw-r--r--routers/web/repo/issue_dependency.go144
1 files changed, 144 insertions, 0 deletions
diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go
new file mode 100644
index 0000000..66b3868
--- /dev/null
+++ b/routers/web/repo/issue_dependency.go
@@ -0,0 +1,144 @@
+// Copyright 2018 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package repo
+
+import (
+ "net/http"
+
+ issues_model "code.gitea.io/gitea/models/issues"
+ access_model "code.gitea.io/gitea/models/perm/access"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/services/context"
+)
+
+// AddDependency adds new dependencies
+func AddDependency(ctx *context.Context) {
+ issueIndex := ctx.ParamsInt64("index")
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, issueIndex)
+ if err != nil {
+ ctx.ServerError("GetIssueByIndex", err)
+ return
+ }
+
+ // Check if the Repo is allowed to have dependencies
+ if !ctx.Repo.CanCreateIssueDependencies(ctx, ctx.Doer, issue.IsPull) {
+ ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
+ return
+ }
+
+ depID := ctx.FormInt64("newDependency")
+
+ if err = issue.LoadRepo(ctx); err != nil {
+ ctx.ServerError("LoadRepo", err)
+ return
+ }
+
+ // Redirect
+ defer ctx.Redirect(issue.Link())
+
+ // Dependency
+ dep, err := issues_model.GetIssueByID(ctx, depID)
+ if err != nil {
+ ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_issue_not_exist"))
+ return
+ }
+
+ // Check if both issues are in the same repo if cross repository dependencies is not enabled
+ if issue.RepoID != dep.RepoID {
+ if !setting.Service.AllowCrossRepositoryDependencies {
+ ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_same_repo"))
+ return
+ }
+ if err := dep.LoadRepo(ctx); err != nil {
+ ctx.ServerError("loadRepo", err)
+ return
+ }
+ // Can ctx.Doer read issues in the dep repo?
+ depRepoPerm, err := access_model.GetUserRepoPermission(ctx, dep.Repo, ctx.Doer)
+ if err != nil {
+ ctx.ServerError("GetUserRepoPermission", err)
+ return
+ }
+ if !depRepoPerm.CanReadIssuesOrPulls(dep.IsPull) {
+ // you can't see this dependency
+ return
+ }
+ }
+
+ // Check if issue and dependency is the same
+ if dep.ID == issue.ID {
+ ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_same_issue"))
+ return
+ }
+
+ err = issues_model.CreateIssueDependency(ctx, ctx.Doer, issue, dep)
+ if err != nil {
+ if issues_model.IsErrDependencyExists(err) {
+ ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_exists"))
+ return
+ } else if issues_model.IsErrCircularDependency(err) {
+ ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_cannot_create_circular"))
+ return
+ }
+ ctx.ServerError("CreateOrUpdateIssueDependency", err)
+ return
+ }
+}
+
+// RemoveDependency removes the dependency
+func RemoveDependency(ctx *context.Context) {
+ issueIndex := ctx.ParamsInt64("index")
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, issueIndex)
+ if err != nil {
+ ctx.ServerError("GetIssueByIndex", err)
+ return
+ }
+
+ // Check if the Repo is allowed to have dependencies
+ if !ctx.Repo.CanCreateIssueDependencies(ctx, ctx.Doer, issue.IsPull) {
+ ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies")
+ return
+ }
+
+ depID := ctx.FormInt64("removeDependencyID")
+
+ if err = issue.LoadRepo(ctx); err != nil {
+ ctx.ServerError("LoadRepo", err)
+ return
+ }
+
+ // Dependency Type
+ depTypeStr := ctx.Req.PostFormValue("dependencyType")
+
+ var depType issues_model.DependencyType
+
+ switch depTypeStr {
+ case "blockedBy":
+ depType = issues_model.DependencyTypeBlockedBy
+ case "blocking":
+ depType = issues_model.DependencyTypeBlocking
+ default:
+ ctx.Error(http.StatusBadRequest, "GetDependecyType")
+ return
+ }
+
+ // Dependency
+ dep, err := issues_model.GetIssueByID(ctx, depID)
+ if err != nil {
+ ctx.ServerError("GetIssueByID", err)
+ return
+ }
+
+ if err = issues_model.RemoveIssueDependency(ctx, ctx.Doer, issue, dep, depType); err != nil {
+ if issues_model.IsErrDependencyNotExists(err) {
+ ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_exist"))
+ return
+ }
+ ctx.ServerError("RemoveIssueDependency", err)
+ return
+ }
+
+ // Redirect
+ ctx.Redirect(issue.Link())
+}