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