diff --git a/modules/context/repo.go b/modules/context/repo.go index 4c32e846eb..af2b3902ad 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -95,8 +95,8 @@ func (r *Repository) CanUseTimetracker(issue *models.Issue, user *models.User) b } // CanCreateIssueDependencies returns whether or not a user can create dependencies. -func (r *Repository) CanCreateIssueDependencies(user *models.User) bool { - return r.Permission.CanWrite(models.UnitTypeIssues) && r.Repository.IsDependenciesEnabled() +func (r *Repository) CanCreateIssueDependencies(user *models.User, isPull bool) bool { + return r.Repository.IsDependenciesEnabled() && r.Permission.CanWriteIssuesOrPulls(isPull) } // GetCommitsCount returns cached commit count for current view diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 69b8a36995..7440f65bee 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -51,6 +51,10 @@ func SearchIssues(ctx *context.APIContext) { // description: repository to prioritize in the results // type: integer // format: int64 + // - name: type + // in: query + // description: filter by type (issues / pulls) if set + // type: string // responses: // "200": // "$ref": "#/responses/IssueList" @@ -129,6 +133,16 @@ func SearchIssues(ctx *context.APIContext) { } } + var isPull util.OptionalBool + switch ctx.Query("type") { + case "pulls": + isPull = util.OptionalBoolTrue + case "issues": + isPull = util.OptionalBoolFalse + default: + isPull = util.OptionalBoolNone + } + // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { @@ -141,6 +155,7 @@ func SearchIssues(ctx *context.APIContext) { LabelIDs: labelIDs, SortType: "priorityrepo", PriorityRepoID: ctx.QueryInt64("priority_repo_id"), + IsPull: isPull, }) } diff --git a/routers/repo/compare.go b/routers/repo/compare.go index 54bae464b2..3fa86a8d9f 100644 --- a/routers/repo/compare.go +++ b/routers/repo/compare.go @@ -415,7 +415,7 @@ func CompareDiff(ctx *context.Context) { if !nothingToCompare { // Setup information for new form. - RetrieveRepoMetas(ctx, ctx.Repo.Repository) + RetrieveRepoMetas(ctx, ctx.Repo.Repository, true) if ctx.Written() { return } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 0a78e06b41..52f21b16ab 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -348,7 +348,7 @@ func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *models.Repos } // RetrieveRepoMetas find all the meta information of a repository -func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository) []*models.Label { +func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository, isPull bool) []*models.Label { if !ctx.Repo.CanWrite(models.UnitTypeIssues) { return nil } @@ -373,7 +373,7 @@ func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository) []*models. ctx.Data["Branches"] = brs // Contains true if the user can create issue dependencies - ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User) + ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User, isPull) return labels } @@ -443,7 +443,7 @@ func NewIssue(ctx *context.Context) { setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates) renderAttachmentSettings(ctx) - RetrieveRepoMetas(ctx, ctx.Repo.Repository) + RetrieveRepoMetas(ctx, ctx.Repo.Repository, false) if ctx.Written() { return } @@ -458,7 +458,7 @@ func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm, isPull b err error ) - labels := RetrieveRepoMetas(ctx, ctx.Repo.Repository) + labels := RetrieveRepoMetas(ctx, ctx.Repo.Repository, isPull) if ctx.Written() { return nil, nil, 0 } @@ -670,6 +670,14 @@ func ViewIssue(ctx *context.Context) { ctx.Data["PageIsIssueList"] = true } + if issue.IsPull && !ctx.Repo.CanRead(models.UnitTypeIssues) { + ctx.Data["IssueType"] = "pulls" + } else if !issue.IsPull && !ctx.Repo.CanRead(models.UnitTypePullRequests) { + ctx.Data["IssueType"] = "issues" + } else { + ctx.Data["IssueType"] = "all" + } + ctx.Data["RequireHighlightJS"] = true ctx.Data["RequireDropzone"] = true ctx.Data["RequireTribute"] = true @@ -807,7 +815,7 @@ func ViewIssue(ctx *context.Context) { } // Check if the user can use the dependencies - ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User) + ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull) // check if dependencies can be created across repositories ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies diff --git a/routers/repo/issue_dependency.go b/routers/repo/issue_dependency.go index d865a56518..055b5ed2af 100644 --- a/routers/repo/issue_dependency.go +++ b/routers/repo/issue_dependency.go @@ -14,14 +14,6 @@ import ( // AddDependency adds new dependencies func AddDependency(ctx *context.Context) { - // Check if the Repo is allowed to have dependencies - if !ctx.Repo.CanCreateIssueDependencies(ctx.User) { - ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies") - return - } - - depID := ctx.QueryInt64("newDependency") - issueIndex := ctx.ParamsInt64("index") issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) if err != nil { @@ -29,6 +21,14 @@ func AddDependency(ctx *context.Context) { return } + // Check if the Repo is allowed to have dependencies + if !ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull) { + ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies") + return + } + + depID := ctx.QueryInt64("newDependency") + if err = issue.LoadRepo(); err != nil { ctx.ServerError("LoadRepo", err) return @@ -73,14 +73,6 @@ func AddDependency(ctx *context.Context) { // RemoveDependency removes the dependency func RemoveDependency(ctx *context.Context) { - // Check if the Repo is allowed to have dependencies - if !ctx.Repo.CanCreateIssueDependencies(ctx.User) { - ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies") - return - } - - depID := ctx.QueryInt64("removeDependencyID") - issueIndex := ctx.ParamsInt64("index") issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) if err != nil { @@ -88,6 +80,14 @@ func RemoveDependency(ctx *context.Context) { return } + // Check if the Repo is allowed to have dependencies + if !ctx.Repo.CanCreateIssueDependencies(ctx.User, issue.IsPull) { + ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies") + return + } + + depID := ctx.QueryInt64("removeDependencyID") + if err = issue.LoadRepo(); err != nil { ctx.ServerError("LoadRepo", err) return diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index dd58e8b216..02564643cc 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -428,6 +428,7 @@ + diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 519a273b4e..fad47731f3 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1173,6 +1173,12 @@ "description": "repository to prioritize in the results", "name": "priority_repo_id", "in": "query" + }, + { + "type": "string", + "description": "filter by type (issues / pulls) if set", + "name": "type", + "in": "query" } ], "responses": { diff --git a/web_src/js/index.js b/web_src/js/index.js index 7c3749c08b..619ca74e52 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -3455,9 +3455,10 @@ function initIssueList() { const repolink = $('#repolink').val(); const repoId = $('#repoId').val(); const crossRepoSearch = $('#crossRepoSearch').val(); - let issueSearchUrl = `${suburl}/api/v1/repos/${repolink}/issues?q={query}`; + const tp = $('#type').val(); + let issueSearchUrl = `${suburl}/api/v1/repos/${repolink}/issues?q={query}&type=${tp}`; if (crossRepoSearch === 'true') { - issueSearchUrl = `${suburl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}`; + issueSearchUrl = `${suburl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}&type=${tp}`; } $('#new-dependency-drop-list') .dropdown({