Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix raw wiki links (#31825) #31845

Merged
merged 6 commits into from
Aug 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions modules/markup/html_link.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package markup

import (
"path"

"code.gitea.io/gitea/modules/util"
)

Expand All @@ -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}"
Expand Down
2 changes: 1 addition & 1 deletion modules/markup/html_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,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(
Expand Down
24 changes: 12 additions & 12 deletions modules/markup/markdown/markdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,9 @@ space</p>
Expected: `<p>space @mention-user<br/>
/just/a/path.bin<br/>
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
<a href="/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/image.jpg" alt="local image"/></a><br/>
<a href="/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/path/file" alt="local image"/></a><br/>
Expand Down Expand Up @@ -713,9 +713,9 @@ space</p>
Expected: `<p>space @mention-user<br/>
/just/a/path.bin<br/>
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
<a href="https://gitea.io/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="https://gitea.io/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="https://gitea.io/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="https://gitea.io/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="https://gitea.io/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/image.jpg" alt="local image"/></a><br/>
<a href="https://gitea.io/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/path/file" alt="local image"/></a><br/>
Expand Down Expand Up @@ -771,9 +771,9 @@ space</p>
Expected: `<p>space @mention-user<br/>
/just/a/path.bin<br/>
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
Expand Down Expand Up @@ -831,9 +831,9 @@ space</p>
Expected: `<p>space @mention-user<br/>
/just/a/path.bin<br/>
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
Expand Down Expand Up @@ -891,9 +891,9 @@ space</p>
Expected: `<p>space @mention-user<br/>
/just/a/path.bin<br/>
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
Expand Down Expand Up @@ -953,9 +953,9 @@ space</p>
Expected: `<p>space @mention-user<br/>
/just/a/path.bin<br/>
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
<a href="https://example.com" rel="nofollow">remote link</a><br/>
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
Expand Down
15 changes: 15 additions & 0 deletions routers/web/explore/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,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)
Expand Down
16 changes: 16 additions & 0 deletions routers/web/org/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package org

import (
"fmt"
"net/http"
"path"
"strings"
Expand Down Expand Up @@ -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
Expand Down
14 changes: 10 additions & 4 deletions routers/web/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -1296,9 +1296,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 {
Expand All @@ -1315,7 +1316,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"),
Expand All @@ -1325,7 +1326,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"),
Expand All @@ -1335,6 +1336,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
}
Expand Down
64 changes: 54 additions & 10 deletions routers/web/repo/wiki.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -215,18 +238,30 @@ 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()
}
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")
Expand Down Expand Up @@ -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"] = ""
Expand Down
14 changes: 14 additions & 0 deletions routers/web/repo/wiki_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.SetParams("*", "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) {
Expand Down Expand Up @@ -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.SetParams("*", "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) {
Expand Down
15 changes: 15 additions & 0 deletions routers/web/user/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,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
Expand Down
15 changes: 15 additions & 0 deletions routers/web/user/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down