diff options
author | Anthony Wang | 2023-03-04 00:03:38 +0000 |
---|---|---|
committer | Anthony Wang | 2023-03-04 00:03:38 +0000 |
commit | b4640101f3c8938ed689743606a79601201141ca (patch) | |
tree | 8469fc5ef817560db646837b41417d50e2f8ebfc /routers | |
parent | dc20c2832871f6462990751ea802e14b02bf41b0 (diff) | |
parent | 8540fc45b11eff9a73753ca139f8ea5c38509bf5 (diff) |
Merge remote-tracking branch 'origin/main' into forgejo-federation
Diffstat (limited to 'routers')
-rw-r--r-- | routers/api/packages/chef/auth.go | 3 | ||||
-rw-r--r-- | routers/api/packages/maven/maven.go | 3 | ||||
-rw-r--r-- | routers/api/v1/repo/issue.go | 7 | ||||
-rw-r--r-- | routers/api/v1/repo/pull.go | 21 | ||||
-rw-r--r-- | routers/api/v1/user/app.go | 13 | ||||
-rw-r--r-- | routers/init.go | 2 | ||||
-rw-r--r-- | routers/web/admin/config.go | 2 | ||||
-rw-r--r-- | routers/web/admin/repos.go | 7 | ||||
-rw-r--r-- | routers/web/explore/repo.go | 37 | ||||
-rw-r--r-- | routers/web/feed/profile.go | 2 | ||||
-rw-r--r-- | routers/web/feed/repo.go | 2 | ||||
-rw-r--r-- | routers/web/repo/actions/view.go | 49 | ||||
-rw-r--r-- | routers/web/repo/issue.go | 10 | ||||
-rw-r--r-- | routers/web/repo/patch.go | 11 | ||||
-rw-r--r-- | routers/web/repo/pull.go | 16 | ||||
-rw-r--r-- | routers/web/repo/setting_protected_branch.go | 34 | ||||
-rw-r--r-- | routers/web/user/home.go | 29 | ||||
-rw-r--r-- | routers/web/user/profile.go | 34 | ||||
-rw-r--r-- | routers/web/web.go | 1 |
19 files changed, 217 insertions, 66 deletions
diff --git a/routers/api/packages/chef/auth.go b/routers/api/packages/chef/auth.go index 69f7b763a..1ea453f1f 100644 --- a/routers/api/packages/chef/auth.go +++ b/routers/api/packages/chef/auth.go @@ -7,7 +7,6 @@ import ( "crypto" "crypto/rsa" "crypto/sha1" - "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" @@ -25,6 +24,8 @@ import ( chef_module "code.gitea.io/gitea/modules/packages/chef" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/auth" + + "github.com/minio/sha256-simd" ) const ( diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index d0c9983cb..a3a23ecfa 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -6,7 +6,6 @@ package maven import ( "crypto/md5" "crypto/sha1" - "crypto/sha256" "crypto/sha512" "encoding/hex" "encoding/xml" @@ -27,6 +26,8 @@ import ( maven_module "code.gitea.io/gitea/modules/packages/maven" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" + + "github.com/minio/sha256-simd" ) const ( diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 699ca3161..9ac1022b4 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -92,6 +92,10 @@ func SearchIssues(ctx *context.APIContext) { // in: query // description: filter pulls requesting your review, default is false // type: boolean + // - name: reviewed + // in: query + // description: filter pulls reviewed by you, default is false + // type: boolean // - name: owner // in: query // description: filter by owner @@ -266,6 +270,9 @@ func SearchIssues(ctx *context.APIContext) { if ctx.FormBool("review_requested") { issuesOpt.ReviewRequestedID = ctxUserID } + if ctx.FormBool("reviewed") { + issuesOpt.ReviewedID = ctxUserID + } if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err) diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 7005725cf..84eebeb94 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -767,11 +767,18 @@ func MergePullRequest(ctx *context.APIContext) { } } - manuallMerge := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged - force := form.ForceMerge != nil && *form.ForceMerge + manuallyMerged := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged + + mergeCheckType := pull_service.MergeCheckTypeGeneral + if form.MergeWhenChecksSucceed { + mergeCheckType = pull_service.MergeCheckTypeAuto + } + if manuallyMerged { + mergeCheckType = pull_service.MergeCheckTypeManually + } // start with merging by checking - if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, manuallMerge, force); err != nil { + if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, mergeCheckType, form.ForceMerge); err != nil { if errors.Is(err, pull_service.ErrIsClosed) { ctx.NotFound() } else if errors.Is(err, pull_service.ErrUserNotAllowedToMerge) { @@ -793,7 +800,7 @@ func MergePullRequest(ctx *context.APIContext) { } // handle manually-merged mark - if manuallMerge { + if manuallyMerged { if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil { if models.IsErrInvalidMergeStyle(err) { ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) @@ -1420,8 +1427,9 @@ func GetPullRequestFiles(ctx *context.APIContext) { startCommitID := prInfo.MergeBase endCommitID := headCommitID - maxLines, maxFiles := setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffFiles + maxLines := setting.Git.MaxGitDiffLines + // FIXME: If there are too many files in the repo, may cause some unpredictable issues. diff, err := gitdiff.GetDiff(baseGitRepo, &gitdiff.DiffOptions{ BeforeCommitID: startCommitID, @@ -1429,7 +1437,7 @@ func GetPullRequestFiles(ctx *context.APIContext) { SkipTo: ctx.FormString("skip-to"), MaxLines: maxLines, MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters, - MaxFiles: maxFiles, + MaxFiles: -1, // GetDiff() will return all files WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.FormString("whitespace")), }) if err != nil { @@ -1452,6 +1460,7 @@ func GetPullRequestFiles(ctx *context.APIContext) { if lenFiles < 0 { lenFiles = 0 } + apiFiles := make([]*api.ChangedFile, 0, lenFiles) for i := start; i < end; i++ { apiFiles = append(apiFiles, convert.ToChangedFile(diff.Files[i], pr.HeadRepo, endCommitID)) diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index 7b2f0d8c3..f89d53945 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -9,6 +9,7 @@ import ( "fmt" "net/http" "strconv" + "strings" auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/context" @@ -62,6 +63,7 @@ func ListAccessTokens(ctx *context.APIContext) { ID: tokens[i].ID, Name: tokens[i].Name, TokenLastEight: tokens[i].TokenLastEight, + Scopes: tokens[i].Scope.StringSlice(), } } @@ -82,9 +84,9 @@ func CreateAccessToken(ctx *context.APIContext) { // - name: username // in: path // description: username of user - // type: string // required: true - // - name: userCreateToken + // type: string + // - name: body // in: body // schema: // "$ref": "#/definitions/CreateAccessTokenOption" @@ -111,6 +113,13 @@ func CreateAccessToken(ctx *context.APIContext) { return } + scope, err := auth_model.AccessTokenScope(strings.Join(form.Scopes, ",")).Normalize() + if err != nil { + ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err)) + return + } + t.Scope = scope + if err := auth_model.NewAccessToken(t); err != nil { ctx.Error(http.StatusInternalServerError, "NewAccessToken", err) return diff --git a/routers/init.go b/routers/init.go index 6a51de669..d3f822dc8 100644 --- a/routers/init.go +++ b/routers/init.go @@ -150,7 +150,7 @@ func GlobalInitInstalled(ctx context.Context) { mustInit(system.Init) mustInit(oauth2.Init) - mustInit(models.Init) + mustInitCtx(ctx, models.Init) mustInit(repo_service.Init) // Booting long running goroutines. diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go index 2566cbe42..075fb423d 100644 --- a/routers/web/admin/config.go +++ b/routers/web/admin/config.go @@ -103,7 +103,7 @@ func Config(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminConfig"] = true - systemSettings, err := system_model.GetAllSettings() + systemSettings, err := system_model.GetAllSettings(ctx) if err != nil { ctx.ServerError("system_model.GetAllSettings", err) return diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go index dc5432c54..1c4754f6d 100644 --- a/routers/web/admin/repos.go +++ b/routers/web/admin/repos.go @@ -33,9 +33,10 @@ func Repos(ctx *context.Context) { ctx.Data["PageIsAdminRepositories"] = true explore.RenderRepoSearch(ctx, &explore.RepoSearchOptions{ - Private: true, - PageSize: setting.UI.Admin.RepoPagingNum, - TplName: tplRepos, + Private: true, + PageSize: setting.UI.Admin.RepoPagingNum, + TplName: tplRepos, + OnlyShowRelevant: false, }) } diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index e9684dd28..058971b9b 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -23,14 +23,17 @@ const ( // RepoSearchOptions when calling search repositories type RepoSearchOptions struct { - OwnerID int64 - Private bool - Restricted bool - PageSize int - TplName base.TplName + OwnerID int64 + Private bool + Restricted bool + PageSize int + OnlyShowRelevant bool + TplName base.TplName } // RenderRepoSearch render repositories search page +// This function is also used to render the Admin Repository Management page. +// The isAdmin param should be set to true when rendering the Admin page. func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { // Sitemap index for sitemap paths page := int(ctx.ParamsInt64("idx")) @@ -48,11 +51,10 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { } var ( - repos []*repo_model.Repository - count int64 - err error - orderBy db.SearchOrderBy - onlyShowRelevant bool + repos []*repo_model.Repository + count int64 + err error + orderBy db.SearchOrderBy ) ctx.Data["SortType"] = ctx.FormString("sort") @@ -84,11 +86,9 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { orderBy = db.SearchOrderByRecentUpdated } - onlyShowRelevant = !ctx.FormBool(relevantReposOnlyParam) - keyword := ctx.FormTrim("q") - ctx.Data["OnlyShowRelevant"] = onlyShowRelevant + ctx.Data["OnlyShowRelevant"] = opts.OnlyShowRelevant topicOnly := ctx.FormBool("topic") ctx.Data["TopicOnly"] = topicOnly @@ -111,7 +111,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { TopicOnly: topicOnly, Language: language, IncludeDescription: setting.UI.SearchRepoDescription, - OnlyShowRelevant: onlyShowRelevant, + OnlyShowRelevant: opts.OnlyShowRelevant, }) if err != nil { ctx.ServerError("SearchRepository", err) @@ -158,9 +158,10 @@ func Repos(ctx *context.Context) { } RenderRepoSearch(ctx, &RepoSearchOptions{ - PageSize: setting.UI.ExplorePagingNum, - OwnerID: ownerID, - Private: ctx.Doer != nil, - TplName: tplExploreRepos, + PageSize: setting.UI.ExplorePagingNum, + OwnerID: ownerID, + Private: ctx.Doer != nil, + TplName: tplExploreRepos, + OnlyShowRelevant: !ctx.FormBool(relevantReposOnlyParam), }) } diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go index 764176919..b9dda2fc1 100644 --- a/routers/web/feed/profile.go +++ b/routers/web/feed/profile.go @@ -26,7 +26,7 @@ func ShowUserFeedAtom(ctx *context.Context) { func showUserFeed(ctx *context.Context, formatType string) { includePrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) - actions, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ + actions, _, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctx.ContextUser, Actor: ctx.Doer, IncludePrivate: includePrivate, diff --git a/routers/web/feed/repo.go b/routers/web/feed/repo.go index 1d24b5880..5fcad2677 100644 --- a/routers/web/feed/repo.go +++ b/routers/web/feed/repo.go @@ -15,7 +15,7 @@ import ( // ShowRepoFeed shows user activity on the repo as RSS / Atom feed func ShowRepoFeed(ctx *context.Context, repo *repo_model.Repository, formatType string) { - actions, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ + actions, _, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedRepo: repo, Actor: ctx.Doer, IncludePrivate: true, diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 5370310e8..dd2750f90 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -49,11 +49,12 @@ type ViewRequest struct { type ViewResponse struct { State struct { Run struct { - Link string `json:"link"` - Title string `json:"title"` - CanCancel bool `json:"canCancel"` - Done bool `json:"done"` - Jobs []*ViewJob `json:"jobs"` + Link string `json:"link"` + Title string `json:"title"` + CanCancel bool `json:"canCancel"` + CanApprove bool `json:"canApprove"` // the run needs an approval and the doer has permission to approve + Done bool `json:"done"` + Jobs []*ViewJob `json:"jobs"` } `json:"run"` CurrentJob struct { Title string `json:"title"` @@ -107,6 +108,7 @@ func ViewPost(ctx *context_module.Context) { resp.State.Run.Title = run.Title resp.State.Run.Link = run.Link() resp.State.Run.CanCancel = !run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions) + resp.State.Run.CanApprove = run.NeedApproval && ctx.Repo.CanWrite(unit.TypeActions) resp.State.Run.Done = run.Status.IsDone() resp.State.Run.Jobs = make([]*ViewJob, 0, len(jobs)) // marshal to '[]' instead fo 'null' in json for _, v := range jobs { @@ -135,6 +137,9 @@ func ViewPost(ctx *context_module.Context) { resp.State.CurrentJob.Title = current.Name resp.State.CurrentJob.Detail = current.Status.LocaleString(ctx.Locale) + if run.NeedApproval { + resp.State.CurrentJob.Detail = ctx.Locale.Tr("actions.need_approval_desc") + } resp.State.CurrentJob.Steps = make([]*ViewJobStep, 0) // marshal to '[]' instead fo 'null' in json resp.Logs.StepsLog = make([]*ViewStepLog, 0) // marshal to '[]' instead fo 'null' in json if task != nil { @@ -261,6 +266,40 @@ func Cancel(ctx *context_module.Context) { ctx.JSON(http.StatusOK, struct{}{}) } +func Approve(ctx *context_module.Context) { + runIndex := ctx.ParamsInt64("run") + + current, jobs := getRunJobs(ctx, runIndex, -1) + if ctx.Written() { + return + } + run := current.Run + doer := ctx.Doer + + if err := db.WithTx(ctx, func(ctx context.Context) error { + run.NeedApproval = false + run.ApprovedBy = doer.ID + if err := actions_model.UpdateRun(ctx, run, "need_approval", "approved_by"); err != nil { + return err + } + for _, job := range jobs { + if len(job.Needs) == 0 && job.Status.IsBlocked() { + job.Status = actions_model.StatusWaiting + _, err := actions_model.UpdateRunJob(ctx, job, nil, "status") + if err != nil { + return err + } + } + } + return nil + }); err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + + ctx.JSON(http.StatusOK, struct{}{}) +} + // getRunJobs gets the jobs of runIndex, and returns jobs[jobIndex], jobs. // Any error will be written to the ctx. // It never returns a nil job of an empty jobs, if the jobIndex is out of range, it will be treated as 0. diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index d740b9344..f8cc4daeb 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -138,7 +138,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti var err error viewType := ctx.FormString("type") sortType := ctx.FormString("sort") - types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned", "review_requested"} + types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned", "review_requested", "reviewed_by"} if !util.SliceContainsString(types, viewType, true) { viewType = "all" } @@ -148,6 +148,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti posterID = ctx.FormInt64("poster") mentionedID int64 reviewRequestedID int64 + reviewedID int64 forceEmpty bool ) @@ -161,6 +162,8 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti assigneeID = ctx.Doer.ID case "review_requested": reviewRequestedID = ctx.Doer.ID + case "reviewed_by": + reviewedID = ctx.Doer.ID } } @@ -208,6 +211,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti MentionedID: mentionedID, PosterID: posterID, ReviewRequestedID: reviewRequestedID, + ReviewedID: reviewedID, IsPull: isPullOption, IssueIDs: issueIDs, }) @@ -255,6 +259,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti PosterID: posterID, MentionedID: mentionedID, ReviewRequestedID: reviewRequestedID, + ReviewedID: reviewedID, MilestoneIDs: mileIDs, ProjectID: projectID, IsClosed: util.OptionalBoolOf(isShowClosed), @@ -2425,6 +2430,9 @@ func SearchIssues(ctx *context.Context) { if ctx.FormBool("review_requested") { issuesOpt.ReviewRequestedID = ctxUserID } + if ctx.FormBool("reviewed") { + issuesOpt.ReviewedID = ctxUserID + } if issues, err = issues_model.Issues(ctx, issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err.Error()) diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go index 12b26f38e..efb466249 100644 --- a/routers/web/repo/patch.go +++ b/routers/web/repo/patch.go @@ -25,7 +25,7 @@ const ( func NewDiffPatch(ctx *context.Context) { canCommit := renderCommitRights(ctx) - ctx.Data["TreePath"] = "" + ctx.Data["PageIsPatch"] = true ctx.Data["commit_summary"] = "" ctx.Data["commit_message"] = "" @@ -51,7 +51,7 @@ func NewDiffPatchPost(ctx *context.Context) { if form.CommitChoice == frmCommitChoiceNewBranch { branchName = form.NewBranchName } - ctx.Data["TreePath"] = "" + ctx.Data["PageIsPatch"] = true ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() ctx.Data["FileContent"] = form.Content ctx.Data["commit_summary"] = form.CommitSummary @@ -86,13 +86,14 @@ func NewDiffPatchPost(ctx *context.Context) { message += "\n\n" + form.CommitMessage } - if _, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{ + fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{ LastCommitID: form.LastCommit, OldBranch: ctx.Repo.BranchName, NewBranch: branchName, Message: message, Content: strings.ReplaceAll(form.Content, "\r", ""), - }); err != nil { + }) + if err != nil { if models.IsErrBranchAlreadyExists(err) { // User has specified a branch that already exists branchErr := err.(models.ErrBranchAlreadyExists) @@ -111,6 +112,6 @@ func NewDiffPatchPost(ctx *context.Context) { if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(ctx, unit.TypePullRequests) { ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { - ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath)) + ctx.Redirect(ctx.Repo.RepoLink + "/commit/" + fileResponse.Commit.SHA) } } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index c7a59da8a..38b9f22cb 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -926,11 +926,19 @@ func MergePullRequest(ctx *context.Context) { pr := issue.PullRequest pr.Issue = issue pr.Issue.Repo = ctx.Repo.Repository - manualMerge := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged - forceMerge := form.ForceMerge != nil && *form.ForceMerge + + manuallyMerged := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged + + mergeCheckType := pull_service.MergeCheckTypeGeneral + if form.MergeWhenChecksSucceed { + mergeCheckType = pull_service.MergeCheckTypeAuto + } + if manuallyMerged { + mergeCheckType = pull_service.MergeCheckTypeManually + } // start with merging by checking - if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, manualMerge, forceMerge); err != nil { + if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, mergeCheckType, form.ForceMerge); err != nil { switch { case errors.Is(err, pull_service.ErrIsClosed): if issue.IsPull { @@ -962,7 +970,7 @@ func MergePullRequest(ctx *context.Context) { } // handle manually-merged mark - if manualMerge { + if manuallyMerged { if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil { switch { diff --git a/routers/web/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go index a54565c1f..0a8c39fef 100644 --- a/routers/web/repo/setting_protected_branch.go +++ b/routers/web/repo/setting_protected_branch.go @@ -166,10 +166,36 @@ func SettingsProtectedBranchPost(ctx *context.Context) { } var err error - protectBranch, err = git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName) - if err != nil { - ctx.ServerError("GetProtectBranchOfRepoByName", err) - return + if f.RuleID > 0 { + // If the RuleID isn't 0, it must be an edit operation. So we get rule by id. + protectBranch, err = git_model.GetProtectedBranchRuleByID(ctx, ctx.Repo.Repository.ID, f.RuleID) + if err != nil { + ctx.ServerError("GetProtectBranchOfRepoByID", err) + return + } + if protectBranch != nil && protectBranch.RuleName != f.RuleName { + // RuleName changed. We need to check if there is a rule with the same name. + // If a rule with the same name exists, an error should be returned. + sameNameProtectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName) + if err != nil { + ctx.ServerError("GetProtectBranchOfRepoByName", err) + return + } + if sameNameProtectBranch != nil { + ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_duplicate_rule_name")) + ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit?rule_name=%s", ctx.Repo.RepoLink, protectBranch.RuleName)) + return + } + } + } else { + // FIXME: If a new ProtectBranch has a duplicate RuleName, an error should be returned. + // Currently, if a new ProtectBranch with a duplicate RuleName is created, the existing ProtectBranch will be updated. + // But we cannot modify this logic now because many unit tests rely on it. + protectBranch, err = git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName) + if err != nil { + ctx.ServerError("GetProtectBranchOfRepoByName", err) + return + } } if protectBranch == nil { // No options found, create defaults. diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 4f45c1d5c..a0a5dc3c4 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -72,12 +72,23 @@ func Dashboard(ctx *context.Context) { return } + var ( + date = ctx.FormString("date") + page = ctx.FormInt("page") + ) + + // Make sure page number is at least 1. Will be posted to ctx.Data. + if page <= 1 { + page = 1 + } + ctx.Data["Title"] = ctxUser.DisplayName() + " - " + ctx.Tr("dashboard") ctx.Data["PageIsDashboard"] = true ctx.Data["PageIsNews"] = true cnt, _ := organization.GetOrganizationCount(ctx, ctxUser) ctx.Data["UserOrgsCount"] = cnt ctx.Data["MirrorsEnabled"] = setting.Mirror.Enabled + ctx.Data["Date"] = date var uid int64 if ctxUser != nil { @@ -98,8 +109,7 @@ func Dashboard(ctx *context.Context) { ctx.Data["HeatmapData"] = data } - var err error - ctx.Data["Feeds"], err = activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ + feeds, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctxUser, RequestedTeam: ctx.Org.Team, Actor: ctx.Doer, @@ -107,13 +117,22 @@ func Dashboard(ctx *context.Context) { OnlyPerformedBy: false, IncludeDeleted: false, Date: ctx.FormString("date"), - ListOptions: db.ListOptions{PageSize: setting.UI.FeedPagingNum}, + ListOptions: db.ListOptions{ + Page: page, + PageSize: setting.UI.FeedPagingNum, + }, }) if err != nil { ctx.ServerError("GetFeeds", err) return } + ctx.Data["Feeds"] = feeds + + pager := context.NewPagination(int(count), setting.UI.FeedPagingNum, page, 5) + pager.AddParam(ctx, "date", "Date") + ctx.Data["Page"] = pager + ctx.HTML(http.StatusOK, tplDashboard) } @@ -366,6 +385,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { filterMode = issues_model.FilterModeMention case "review_requested": filterMode = issues_model.FilterModeReviewRequested + case "reviewed_by": + filterMode = issues_model.FilterModeReviewed case "your_repositories": fallthrough default: @@ -434,6 +455,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { opts.MentionedID = ctx.Doer.ID case issues_model.FilterModeReviewRequested: opts.ReviewRequestedID = ctx.Doer.ID + case issues_model.FilterModeReviewed: + opts.ReviewedID = ctx.Doer.ID } // keyword holds the search term entered into the search field. diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 503562220..5d34df79b 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -120,6 +120,11 @@ func Profile(ctx *context.Context) { page = 1 } + pagingNum := setting.UI.User.RepoPagingNum + if tab == "activity" { + pagingNum = setting.UI.FeedPagingNum + } + topicOnly := ctx.FormBool("topic") var ( @@ -165,7 +170,7 @@ func Profile(ctx *context.Context) { switch tab { case "followers": items, count, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ - PageSize: setting.UI.User.RepoPagingNum, + PageSize: pagingNum, Page: page, }) if err != nil { @@ -177,7 +182,7 @@ func Profile(ctx *context.Context) { total = int(count) case "following": items, count, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ - PageSize: setting.UI.User.RepoPagingNum, + PageSize: pagingNum, Page: page, }) if err != nil { @@ -188,24 +193,32 @@ func Profile(ctx *context.Context) { total = int(count) case "activity": - ctx.Data["Feeds"], err = activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ + date := ctx.FormString("date") + items, count, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctx.ContextUser, Actor: ctx.Doer, IncludePrivate: showPrivate, OnlyPerformedBy: true, IncludeDeleted: false, - Date: ctx.FormString("date"), - ListOptions: db.ListOptions{PageSize: setting.UI.FeedPagingNum}, + Date: date, + ListOptions: db.ListOptions{ + PageSize: pagingNum, + Page: page, + }, }) if err != nil { ctx.ServerError("GetFeeds", err) return } + ctx.Data["Feeds"] = items + ctx.Data["Date"] = date + + total = int(count) case "stars": ctx.Data["PageIsProfileStarList"] = true repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ - PageSize: setting.UI.User.RepoPagingNum, + PageSize: pagingNum, Page: page, }, Actor: ctx.Doer, @@ -237,7 +250,7 @@ func Profile(ctx *context.Context) { case "watching": repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ - PageSize: setting.UI.User.RepoPagingNum, + PageSize: pagingNum, Page: page, }, Actor: ctx.Doer, @@ -259,7 +272,7 @@ func Profile(ctx *context.Context) { default: repos, count, err = repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ - PageSize: setting.UI.User.RepoPagingNum, + PageSize: pagingNum, Page: page, }, Actor: ctx.Doer, @@ -282,12 +295,15 @@ func Profile(ctx *context.Context) { ctx.Data["Repos"] = repos ctx.Data["Total"] = total - pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5) + pager := context.NewPagination(total, pagingNum, page, 5) pager.SetDefaultParams(ctx) pager.AddParam(ctx, "tab", "TabName") if tab != "followers" && tab != "following" && tab != "activity" && tab != "projects" { pager.AddParam(ctx, "language", "Language") } + if tab == "activity" { + pager.AddParam(ctx, "date", "Date") + } ctx.Data["Page"] = pager ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled diff --git a/routers/web/web.go b/routers/web/web.go index 88e27ad67..ff312992d 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1286,6 +1286,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/rerun", reqRepoActionsWriter, actions.Rerun) }) m.Post("/cancel", reqRepoActionsWriter, actions.Cancel) + m.Post("/approve", reqRepoActionsWriter, actions.Approve) }) }, reqRepoActionsReader, actions.MustEnableActions) |