From 7092402a2db255ecde2c20574b973fb632c16d2e Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 16 Aug 2024 01:34:24 +0900 Subject: [PATCH 001/129] Add missing repository type filter parameters to pager (#31832) Fix #31807 ps: the newly added params's value will be changed. When the first time you selected the filter, the values of params will be `0` or `1` But in pager it will be `true` or `false`. So do we have `boolToInt` function? --- routers/web/explore/repo.go | 15 +++++++++++++++ routers/web/org/home.go | 16 ++++++++++++++++ routers/web/user/notification.go | 15 +++++++++++++++ routers/web/user/profile.go | 15 +++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index 67f138aca9f..ab487dff5fc 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -144,6 +144,21 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { pager.AddParamString("topic", fmt.Sprint(topicOnly)) pager.AddParamString("language", language) pager.AddParamString(relevantReposOnlyParam, fmt.Sprint(opts.OnlyShowRelevant)) + if archived.Has() { + pager.AddParamString("archived", fmt.Sprint(archived.Value())) + } + if fork.Has() { + pager.AddParamString("fork", fmt.Sprint(fork.Value())) + } + if mirror.Has() { + pager.AddParamString("mirror", fmt.Sprint(mirror.Value())) + } + if template.Has() { + pager.AddParamString("template", fmt.Sprint(template.Value())) + } + if private.Has() { + pager.AddParamString("private", fmt.Sprint(private.Value())) + } ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, opts.TplName) diff --git a/routers/web/org/home.go b/routers/web/org/home.go index c3fc4e099a4..77d49f5b78f 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -4,6 +4,7 @@ package org import ( + "fmt" "net/http" "path" "strings" @@ -155,6 +156,21 @@ func Home(ctx *context.Context) { pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5) pager.SetDefaultParams(ctx) pager.AddParamString("language", language) + if archived.Has() { + pager.AddParamString("archived", fmt.Sprint(archived.Value())) + } + if fork.Has() { + pager.AddParamString("fork", fmt.Sprint(fork.Value())) + } + if mirror.Has() { + pager.AddParamString("mirror", fmt.Sprint(mirror.Value())) + } + if template.Has() { + pager.AddParamString("template", fmt.Sprint(template.Value())) + } + if private.Has() { + pager.AddParamString("private", fmt.Sprint(private.Value())) + } ctx.Data["Page"] = pager ctx.Data["ShowMemberAndTeamTab"] = ctx.Org.IsMember || len(members) > 0 diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 833a9c049c8..414cb0be490 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -446,6 +446,21 @@ func NotificationWatching(ctx *context.Context) { // redirect to last page if request page is more than total pages pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5) pager.SetDefaultParams(ctx) + if archived.Has() { + pager.AddParamString("archived", fmt.Sprint(archived.Value())) + } + if fork.Has() { + pager.AddParamString("fork", fmt.Sprint(fork.Value())) + } + if mirror.Has() { + pager.AddParamString("mirror", fmt.Sprint(mirror.Value())) + } + if template.Has() { + pager.AddParamString("template", fmt.Sprint(template.Value())) + } + if private.Has() { + pager.AddParamString("private", fmt.Sprint(private.Value())) + } ctx.Data["Page"] = pager ctx.Data["Status"] = 2 diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index f0749e10216..3f91233ee6e 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -333,6 +333,21 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb pager.AddParamString("date", fmt.Sprint(ctx.Data["Date"])) } } + if archived.Has() { + pager.AddParamString("archived", fmt.Sprint(archived.Value())) + } + if fork.Has() { + pager.AddParamString("fork", fmt.Sprint(fork.Value())) + } + if mirror.Has() { + pager.AddParamString("mirror", fmt.Sprint(mirror.Value())) + } + if template.Has() { + pager.AddParamString("template", fmt.Sprint(template.Value())) + } + if private.Has() { + pager.AddParamString("private", fmt.Sprint(private.Value())) + } ctx.Data["Page"] = pager } From e4f850bf635365083344af0c0109c29e7021ba03 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Fri, 16 Aug 2024 00:27:28 +0000 Subject: [PATCH 002/129] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index b36b3204396..4fc06bc71a0 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1475,6 +1475,7 @@ issues.remove_labels=がラベル %s を除去 %s issues.add_remove_labels=がラベル %s を追加、 %s を除去 %s issues.add_milestone_at=`がマイルストーン %[1]s に追加 %[2]s` issues.add_project_at=`がプロジェクト %s に追加 %s` +issues.move_to_column_of_project=`がこれを %[2]s の %[1]s に移動 %[3]s` issues.change_milestone_at=`がマイルストーンを %[1]s から %[2]s へ変更 %[3]s` issues.change_project_at=`がプロジェクトを %s から %s へ変更 %s` issues.remove_milestone_at=`がマイルストーン %[1]s から除去 %[2]s` @@ -1764,6 +1765,7 @@ compare.compare_head=比較 pulls.desc=プルリクエストとコードレビューの有効化。 pulls.new=新しいプルリクエスト pulls.new.blocked_user=リポジトリのオーナーがあなたをブロックしているため、プルリクエストを作成できません。 +pulls.new.must_collaborator=プルリクエストを作成するには、共同作業者である必要があります。 pulls.edit.already_changed=プルリクエストの変更を保存できません。 他のユーザーによって内容がすでに変更されているようです。 変更を上書きしないようにするため、ページを更新してからもう一度編集してください pulls.view=プルリクエストを表示 pulls.compare_changes=新規プルリクエスト @@ -1888,6 +1890,7 @@ pulls.cmd_instruction_checkout_title=チェックアウト pulls.cmd_instruction_checkout_desc=プロジェクトリポジトリから新しいブランチをチェックアウトし、変更内容をテストします。 pulls.cmd_instruction_merge_title=マージ pulls.cmd_instruction_merge_desc=変更内容をマージして、Giteaに反映します。 +pulls.cmd_instruction_merge_warning=警告: 「手動マージの自動検出」が有効ではないため、この操作ではプルリクエストをマージできません pulls.clear_merge_message=マージメッセージをクリア pulls.clear_merge_message_hint=マージメッセージのクリアは、コミットメッセージの除去だけを行います。 生成されたGitトレーラー("Co-Authored-By …" 等)はそのまま残ります。 From 2010fbe06054b9d9cada430f1a60f45ac7689b93 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Fri, 16 Aug 2024 20:40:51 +0800 Subject: [PATCH 003/129] Fix raw wiki links (#31825) Fix #31395 This regression is introduced by #30273. To find out how GitHub handles this case, I did [some tests](https://github.com/go-gitea/gitea/issues/31395#issuecomment-2278929115). I use redirect in this PR instead of checking if the corresponding `.md` file exists when rendering the link because GitHub also uses redirect. With this PR, there is no need to resolve the raw wiki link when rendering a wiki page. If a wiki link points to a raw file, access will be redirected to the raw link. --- modules/markup/html_link.go | 12 ++--- modules/markup/html_test.go | 2 +- modules/markup/markdown/markdown_test.go | 24 ++++----- routers/web/repo/wiki.go | 64 ++++++++++++++++++++---- routers/web/repo/wiki_test.go | 14 ++++++ 5 files changed, 84 insertions(+), 32 deletions(-) diff --git a/modules/markup/html_link.go b/modules/markup/html_link.go index a41b87e9fa8..b0861353485 100644 --- a/modules/markup/html_link.go +++ b/modules/markup/html_link.go @@ -4,8 +4,6 @@ package markup import ( - "path" - "code.gitea.io/gitea/modules/util" ) @@ -14,13 +12,9 @@ func ResolveLink(ctx *RenderContext, link, userContentAnchorPrefix string) (resu if !isAnchorFragment && !IsFullURLString(link) { linkBase := ctx.Links.Base if ctx.IsWiki { - if ext := path.Ext(link); ext == "" || ext == ".-" { - linkBase = ctx.Links.WikiLink() // the link is for a wiki page - } else if DetectMarkupTypeByFileName(link) != "" { - linkBase = ctx.Links.WikiLink() // the link is renderable as a wiki page - } else { - linkBase = ctx.Links.WikiRawLink() // otherwise, use a raw link instead to view&download medias - } + // no need to check if the link should be resolved as a wiki link or a wiki raw link + // just use wiki link here and it will be redirected to a wiki raw link if necessary + linkBase = ctx.Links.WikiLink() } else if ctx.Links.BranchPath != "" || ctx.Links.TreePath != "" { // if there is no BranchPath, then the link will be something like "/owner/repo/src/{the-file-path}" // and then this link will be handled by the "legacy-ref" code and be redirected to the default branch like "/owner/repo/src/branch/main/{the-file-path}" diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index c69f3ddd648..32858dbd6b3 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -437,7 +437,7 @@ func TestRender_ShortLinks(t *testing.T) { renderableFileURL := util.URLJoin(tree, "markdown_file.md") renderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "markdown_file.md") unrenderableFileURL := util.URLJoin(tree, "file.zip") - unrenderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "file.zip") + unrenderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "file.zip") favicon := "http://google.com/favicon.ico" test( diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 671276e45c5..cfb821ab19f 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -672,9 +672,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -730,9 +730,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -788,9 +788,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -848,9 +848,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -908,9 +908,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -970,9 +970,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 13b6a7b8e3b..d2056353d88 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -138,18 +138,41 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte { return content } -// wikiContentsByName returns the contents of a wiki page, along with a boolean -// indicating whether the page exists. Writes to ctx if an error occurs. -func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool) { +// wikiEntryByName returns the entry of a wiki page, along with a boolean +// indicating whether the entry exists. Writes to ctx if an error occurs. +// The last return value indicates whether the file should be returned as a raw file +func wikiEntryByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) (*git.TreeEntry, string, bool, bool) { + isRaw := false gitFilename := wiki_service.WebPathToGitPath(wikiName) entry, err := findEntryForFile(commit, gitFilename) if err != nil && !git.IsErrNotExist(err) { ctx.ServerError("findEntryForFile", err) - return nil, nil, "", false - } else if entry == nil { + return nil, "", false, false + } + if entry == nil { + // check if the file without ".md" suffix exists + gitFilename := strings.TrimSuffix(gitFilename, ".md") + entry, err = findEntryForFile(commit, gitFilename) + if err != nil && !git.IsErrNotExist(err) { + ctx.ServerError("findEntryForFile", err) + return nil, "", false, false + } + isRaw = true + } + if entry == nil { + return nil, "", true, false + } + return entry, gitFilename, false, isRaw +} + +// wikiContentsByName returns the contents of a wiki page, along with a boolean +// indicating whether the page exists. Writes to ctx if an error occurs. +func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool) { + entry, gitFilename, noEntry, _ := wikiEntryByName(ctx, commit, wikiName) + if entry == nil { return nil, nil, "", true } - return wikiContentsByEntry(ctx, entry), entry, gitFilename, false + return wikiContentsByEntry(ctx, entry), entry, gitFilename, noEntry } func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { @@ -215,11 +238,14 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { isSideBar := pageName == "_Sidebar" isFooter := pageName == "_Footer" - // lookup filename in wiki - get filecontent, gitTree entry , real filename - data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName) + // lookup filename in wiki - get gitTree entry , real filename + entry, pageFilename, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName) if noEntry { ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages") } + if isRaw { + ctx.Redirect(util.URLJoin(ctx.Repo.RepoLink, "wiki/raw", string(pageName))) + } if entry == nil || ctx.Written() { if wikiRepo != nil { wikiRepo.Close() @@ -227,6 +253,15 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { return nil, nil } + // get filecontent + data := wikiContentsByEntry(ctx, entry) + if ctx.Written() { + if wikiRepo != nil { + wikiRepo.Close() + } + return nil, nil + } + var sidebarContent []byte if !isSideBar { sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar") @@ -442,15 +477,24 @@ func renderEditPage(ctx *context.Context) { ctx.Data["Title"] = displayName ctx.Data["title"] = displayName - // lookup filename in wiki - get filecontent, gitTree entry , real filename - data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName) + // lookup filename in wiki - gitTree entry , real filename + entry, _, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName) if noEntry { ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages") } + if isRaw { + ctx.Error(http.StatusForbidden, "Editing of raw wiki files is not allowed") + } if entry == nil || ctx.Written() { return } + // get filecontent + data := wikiContentsByEntry(ctx, entry) + if ctx.Written() { + return + } + ctx.Data["content"] = string(data) ctx.Data["sidebarPresent"] = false ctx.Data["sidebarContent"] = "" diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go index 7de5899e21c..b81f2ea02e3 100644 --- a/routers/web/repo/wiki_test.go +++ b/routers/web/repo/wiki_test.go @@ -87,6 +87,13 @@ func TestWiki(t *testing.T) { assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) assert.EqualValues(t, "Home", ctx.Data["Title"]) assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"]) + + ctx, _ = contexttest.MockContext(t, "user2/repo1/jpeg.jpg") + ctx.SetPathParam("*", "jpeg.jpg") + contexttest.LoadRepo(t, ctx, 1) + Wiki(ctx) + assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) + assert.Equal(t, "/user2/repo1/wiki/raw/jpeg.jpg", ctx.Resp.Header().Get("Location")) } func TestWikiPages(t *testing.T) { @@ -160,6 +167,13 @@ func TestEditWiki(t *testing.T) { assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) assert.EqualValues(t, "Home", ctx.Data["Title"]) assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"]) + + ctx, _ = contexttest.MockContext(t, "user2/repo1/wiki/jpeg.jpg?action=_edit") + ctx.SetPathParam("*", "jpeg.jpg") + contexttest.LoadUser(t, ctx, 2) + contexttest.LoadRepo(t, ctx, 1) + EditWiki(ctx) + assert.EqualValues(t, http.StatusForbidden, ctx.Resp.Status()) } func TestEditWikiPost(t *testing.T) { From acd7053e9d4968e8b9812ab379be9027ac8e7771 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Sat, 17 Aug 2024 01:04:54 +0800 Subject: [PATCH 004/129] Avoid returning without written ctx when posting PR (#31843) Fix #31625. If `pull_service.NewPullRequest` return an error which misses each `if` check, `CompareAndPullRequestPost` will return immediately, since it doesn't write the HTTP response, a 200 response with empty body will be sent to clients. ```go if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil { if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) } else if git.IsErrPushRejected(err) { // ... ctx.JSONError(flashError) } else if errors.Is(err, user_model.ErrBlockedUser) { // ... ctx.JSONError(flashError) } else if errors.Is(err, issues_model.ErrMustCollaborator) { // ... ctx.JSONError(flashError) } return } ``` Not sure what kind of error can cause it to happen, so this PR just expose it. And we can fix it when users report that creating PRs failed with error responses. It's all my guess since I cannot reproduce the problem, but even if it's not related, the code here needs to be improved. --- routers/web/repo/pull.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 9531482bee7..e001e872aa8 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -1308,9 +1308,10 @@ func CompareAndPullRequestPost(ctx *context.Context) { // instead of 500. if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil { - if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { + switch { + case repo_model.IsErrUserDoesNotHaveAccessToRepo(err): ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) - } else if git.IsErrPushRejected(err) { + case git.IsErrPushRejected(err): pushrejErr := err.(*git.ErrPushRejected) message := pushrejErr.Message if len(message) == 0 { @@ -1327,7 +1328,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { return } ctx.JSONError(flashError) - } else if errors.Is(err, user_model.ErrBlockedUser) { + case errors.Is(err, user_model.ErrBlockedUser): flashError, err := ctx.RenderToHTML(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.pulls.push_rejected"), "Summary": ctx.Tr("repo.pulls.new.blocked_user"), @@ -1337,7 +1338,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { return } ctx.JSONError(flashError) - } else if errors.Is(err, issues_model.ErrMustCollaborator) { + case errors.Is(err, issues_model.ErrMustCollaborator): flashError, err := ctx.RenderToHTML(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.pulls.push_rejected"), "Summary": ctx.Tr("repo.pulls.new.must_collaborator"), @@ -1347,6 +1348,11 @@ func CompareAndPullRequestPost(ctx *context.Context) { return } ctx.JSONError(flashError) + default: + // It's an unexpected error. + // If it happens, we should add another case to handle it. + log.Error("Unexpected error of NewPullRequest: %T %s", err, err) + ctx.ServerError("CompareAndPullRequest", err) } return } From 2e7d202a7f8051d140220d1c195ff73b80e0d1ff Mon Sep 17 00:00:00 2001 From: sillyguodong <33891828+sillyguodong@users.noreply.github.com> Date: Sat, 17 Aug 2024 01:37:36 +0800 Subject: [PATCH 005/129] fix the component of access token list not mounted (#31824) try to fix #31771 --- templates/user/settings/applications.tmpl | 14 ++++++------- .../components/ScopedAccessTokenSelector.vue | 13 ------------ web_src/js/features/scoped-access-token.ts | 20 +++++++++++++++++++ web_src/js/index.ts | 2 +- 4 files changed, 28 insertions(+), 21 deletions(-) create mode 100644 web_src/js/features/scoped-access-token.ts diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl index 3c1934dd8b4..65525aac2b2 100644 --- a/templates/user/settings/applications.tmpl +++ b/templates/user/settings/applications.tmpl @@ -77,13 +77,13 @@

{{ctx.Locale.Tr "settings.access_token_desc" (HTMLFormat `href="%s/api/swagger" target="_blank"` AppSubUrl) (`href="https://docs.gitea.com/development/oauth2-provider#scopes" target="_blank"`|SafeHTML)}}

-
- +