Multiple Escaping Improvements (#17551)
There are multiple places where Gitea does not properly escape URLs that it is building and there are multiple places where it builds urls when there is already a simpler function available to use this. This is an extensive PR attempting to fix these issues. 1. The first commit in this PR looks through all href, src and links in the Gitea codebase and has attempted to catch all the places where there is potentially incomplete escaping. 2. Whilst doing this we will prefer to use functions that create URLs over recreating them by hand. 3. All uses of strings should be directly escaped - even if they are not currently expected to contain escaping characters. The main benefit to doing this will be that we can consider relaxing the constraints on user names and reponames in future. 4. The next commit looks at escaping in the wiki and re-considers the urls that are used there. Using the improved escaping here wiki files containing '/'. (This implementation will currently still place all of the wiki files the root directory of the repo but this would not be difficult to change.) 5. The title generation in feeds is now properly escaped. 6. EscapePound is no longer needed - urls should be PathEscaped / QueryEscaped as necessary but then re-escaped with Escape when creating html with locales Signed-off-by: Andrew Thornton <art27@cantab.net> Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
7e1ae38097
commit
bbffcc3aec
153 changed files with 891 additions and 712 deletions
|
@ -6,6 +6,7 @@ package org
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
@ -159,7 +160,7 @@ func IsMember(ctx *context.APIContext) {
|
|||
}
|
||||
}
|
||||
|
||||
redirectURL := setting.AppSubURL + "/api/v1/orgs/" + ctx.Org.Organization.Name + "/public_members/" + userToCheck.Name
|
||||
redirectURL := setting.AppSubURL + "/api/v1/orgs/" + url.PathEscape(ctx.Org.Organization.Name) + "/public_members/" + url.PathEscape(userToCheck.Name)
|
||||
ctx.Redirect(redirectURL, 302)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@ package repo
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
)
|
||||
|
||||
|
@ -89,11 +91,11 @@ func getGitRefsInternal(ctx *context.APIContext, filter string) {
|
|||
for i := range refs {
|
||||
apiRefs[i] = &api.Reference{
|
||||
Ref: refs[i].Name,
|
||||
URL: ctx.Repo.Repository.APIURL() + "/git/" + refs[i].Name,
|
||||
URL: ctx.Repo.Repository.APIURL() + "/git/" + util.PathEscapeSegments(refs[i].Name),
|
||||
Object: &api.GitObject{
|
||||
SHA: refs[i].Object.String(),
|
||||
Type: refs[i].Type,
|
||||
URL: ctx.Repo.Repository.APIURL() + "/git/" + refs[i].Type + "s/" + refs[i].Object.String(),
|
||||
URL: ctx.Repo.Repository.APIURL() + "/git/" + url.PathEscape(refs[i].Type) + "s/" + url.PathEscape(refs[i].Object.String()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package repo
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
@ -33,8 +34,8 @@ func appendPrivateInformation(apiKey *api.DeployKey, key *models.DeployKey, repo
|
|||
return apiKey, nil
|
||||
}
|
||||
|
||||
func composeDeployKeysAPILink(repoPath string) string {
|
||||
return setting.AppURL + "api/v1/repos/" + repoPath + "/keys/"
|
||||
func composeDeployKeysAPILink(owner, name string) string {
|
||||
return setting.AppURL + "api/v1/repos/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/keys/"
|
||||
}
|
||||
|
||||
// ListDeployKeys list all the deploy keys of a repository
|
||||
|
@ -94,7 +95,7 @@ func ListDeployKeys(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
apiKeys := make([]*api.DeployKey, len(keys))
|
||||
for i := range keys {
|
||||
if err := keys[i].GetContent(); err != nil {
|
||||
|
@ -154,7 +155,7 @@ func GetDeployKey(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
apiKey := convert.ToDeployKey(apiLink, key)
|
||||
if ctx.User.IsAdmin || ((ctx.Repo.Repository.ID == key.RepoID) && (ctx.User.ID == ctx.Repo.Owner.ID)) {
|
||||
apiKey, _ = appendPrivateInformation(apiKey, key, ctx.Repo.Repository)
|
||||
|
@ -233,7 +234,7 @@ func CreateDeployKey(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
key.Content = content
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
ctx.JSON(http.StatusCreated, convert.ToDeployKey(apiLink, key))
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"code.gitea.io/gitea/models/login"
|
||||
"code.gitea.io/gitea/modules/auth/pam"
|
||||
|
@ -396,7 +398,7 @@ func EditAuthSourcePost(ctx *context.Context) {
|
|||
log.Trace("Authentication changed by admin(%s): %d", ctx.User.Name, source.ID)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.update_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/auths/" + fmt.Sprint(form.ID))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/auths/" + strconv.FormatInt(form.ID, 10))
|
||||
}
|
||||
|
||||
// DeleteAuthSource response for deleting an auth source
|
||||
|
@ -414,7 +416,7 @@ func DeleteAuthSource(ctx *context.Context) {
|
|||
ctx.Flash.Error(fmt.Sprintf("DeleteLoginSource: %v", err))
|
||||
}
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/auths/" + ctx.Params(":authid"),
|
||||
"redirect": setting.AppSubURL + "/admin/auths/" + url.PathEscape(ctx.Params(":authid")),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ func DeleteRepo(ctx *context.Context) {
|
|||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.deletion_success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/repos?page=" + ctx.FormString("page") + "&sort=" + ctx.FormString("sort"),
|
||||
"redirect": setting.AppSubURL + "/admin/repos?page=" + url.QueryEscape(ctx.FormString("page")) + "&sort=" + url.QueryEscape(ctx.FormString("sort")),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -161,5 +161,5 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
|
|||
}
|
||||
ctx.Flash.Success(ctx.Tr("repo.delete_preexisting_success", dir))
|
||||
}
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/repos/unadopted?search=true&q=" + url.QueryEscape(q) + "&page=" + page)
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/repos/unadopted?search=true&q=" + url.QueryEscape(q) + "&page=" + url.QueryEscape(page))
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -188,7 +188,7 @@ func NewUserPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.users.new_success", u.Name))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + fmt.Sprint(u.ID))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + strconv.FormatInt(u.ID, 10))
|
||||
}
|
||||
|
||||
func prepareUserInfo(ctx *context.Context) *models.User {
|
||||
|
@ -366,7 +366,7 @@ func EditUserPost(ctx *context.Context) {
|
|||
log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
|
||||
}
|
||||
|
||||
// DeleteUser response for deleting a user
|
||||
|
@ -382,12 +382,12 @@ func DeleteUser(ctx *context.Context) {
|
|||
case models.IsErrUserOwnRepos(err):
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"),
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")),
|
||||
})
|
||||
case models.IsErrUserHasOrgs(err):
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.still_has_org"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"),
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")),
|
||||
})
|
||||
default:
|
||||
ctx.ServerError("DeleteUser", err)
|
||||
|
|
|
@ -15,10 +15,35 @@ import (
|
|||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/gorilla/feeds"
|
||||
)
|
||||
|
||||
func toBranchLink(act *models.Action) string {
|
||||
return act.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(act.GetBranch())
|
||||
}
|
||||
|
||||
func toTagLink(act *models.Action) string {
|
||||
return act.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(act.GetTag())
|
||||
}
|
||||
|
||||
func toIssueLink(act *models.Action) string {
|
||||
return act.GetRepoLink() + "/issues/" + url.PathEscape(act.GetIssueInfos()[0])
|
||||
}
|
||||
|
||||
func toPullLink(act *models.Action) string {
|
||||
return act.GetRepoLink() + "/pulls/" + url.PathEscape(act.GetIssueInfos()[0])
|
||||
}
|
||||
|
||||
func toSrcLink(act *models.Action) string {
|
||||
return act.GetRepoLink() + "/src/" + util.PathEscapeSegments(act.GetBranch())
|
||||
}
|
||||
|
||||
func toReleaseLink(act *models.Action) string {
|
||||
return act.GetRepoLink() + "/releases/tag/" + util.PathEscapeSegments(act.GetBranch())
|
||||
}
|
||||
|
||||
// feedActionsToFeedItems convert gitea's Action feed to feeds Item
|
||||
func feedActionsToFeedItems(ctx *context.Context, actions []*models.Action) (items []*feeds.Item, err error) {
|
||||
for _, act := range actions {
|
||||
|
@ -32,62 +57,111 @@ func feedActionsToFeedItems(ctx *context.Context, actions []*models.Action) (ite
|
|||
title = act.ActUser.DisplayName() + " "
|
||||
switch act.OpType {
|
||||
case models.ActionCreateRepo:
|
||||
title += ctx.Tr("action.create_repo", act.GetRepoLink(), act.ShortRepoPath())
|
||||
title += ctx.TrHTMLEscapeArgs("action.create_repo", act.GetRepoLink(), act.ShortRepoPath())
|
||||
link.Href = act.GetRepoLink()
|
||||
case models.ActionRenameRepo:
|
||||
title += ctx.Tr("action.rename_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
|
||||
title += ctx.TrHTMLEscapeArgs("action.rename_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
|
||||
link.Href = act.GetRepoLink()
|
||||
case models.ActionCommitRepo:
|
||||
branchLink := act.GetBranch()
|
||||
link.Href = toBranchLink(act)
|
||||
if len(act.Content) != 0 {
|
||||
title += ctx.Tr("action.commit_repo", act.GetRepoLink(), branchLink, act.GetBranch(), act.ShortRepoPath())
|
||||
title += ctx.TrHTMLEscapeArgs("action.commit_repo", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
|
||||
} else {
|
||||
title += ctx.Tr("action.create_branch", act.GetRepoLink(), branchLink, act.GetBranch(), act.ShortRepoPath())
|
||||
title += ctx.TrHTMLEscapeArgs("action.create_branch", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
|
||||
}
|
||||
case models.ActionCreateIssue:
|
||||
title += ctx.Tr("action.create_issue", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
link.Href = toIssueLink(act)
|
||||
title += ctx.TrHTMLEscapeArgs("action.create_issue", link.Href, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionCreatePullRequest:
|
||||
title += ctx.Tr("action.create_pull_request", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
link.Href = toPullLink(act)
|
||||
title += ctx.TrHTMLEscapeArgs("action.create_pull_request", link.Href, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionTransferRepo:
|
||||
title += ctx.Tr("action.transfer_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
|
||||
link.Href = act.GetRepoLink()
|
||||
title += ctx.TrHTMLEscapeArgs("action.transfer_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
|
||||
case models.ActionPushTag:
|
||||
title += ctx.Tr("action.push_tag", act.GetRepoLink(), url.QueryEscape(act.GetTag()), act.ShortRepoPath())
|
||||
link.Href = toTagLink(act)
|
||||
title += ctx.TrHTMLEscapeArgs("action.push_tag", act.GetRepoLink(), link.Href, act.GetTag(), act.ShortRepoPath())
|
||||
case models.ActionCommentIssue:
|
||||
title += ctx.Tr("action.comment_issue", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
issueLink := toIssueLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = issueLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.comment_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionMergePullRequest:
|
||||
title += ctx.Tr("action.merge_pull_request", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
pullLink := toPullLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = pullLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.merge_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionCloseIssue:
|
||||
title += ctx.Tr("action.close_issue", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
issueLink := toIssueLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = issueLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.close_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionReopenIssue:
|
||||
title += ctx.Tr("action.reopen_issue", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
issueLink := toIssueLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = issueLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.reopen_issue", issueLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionClosePullRequest:
|
||||
title += ctx.Tr("action.close_pull_request", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
pullLink := toPullLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = pullLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.close_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionReopenPullRequest:
|
||||
title += ctx.Tr("action.reopen_pull_request", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath)
|
||||
pullLink := toPullLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = pullLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.reopen_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionDeleteTag:
|
||||
title += ctx.Tr("action.delete_tag", act.GetRepoLink(), html.EscapeString(act.GetTag()), act.ShortRepoPath())
|
||||
link.Href = act.GetRepoLink()
|
||||
title += ctx.TrHTMLEscapeArgs("action.delete_tag", act.GetRepoLink(), act.GetTag(), act.ShortRepoPath())
|
||||
case models.ActionDeleteBranch:
|
||||
title += ctx.Tr("action.delete_branch", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
|
||||
link.Href = act.GetRepoLink()
|
||||
title += ctx.TrHTMLEscapeArgs("action.delete_branch", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
|
||||
case models.ActionMirrorSyncPush:
|
||||
title += ctx.Tr("action.mirror_sync_push", act.GetRepoLink(), url.QueryEscape(act.GetBranch()), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
|
||||
srcLink := toSrcLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = srcLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_push", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
|
||||
case models.ActionMirrorSyncCreate:
|
||||
title += ctx.Tr("action.mirror_sync_create", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
|
||||
srcLink := toSrcLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = srcLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_create", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
|
||||
case models.ActionMirrorSyncDelete:
|
||||
title += ctx.Tr("action.mirror_sync_delete", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
|
||||
link.Href = act.GetRepoLink()
|
||||
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_delete", act.GetRepoLink(), act.GetBranch(), act.ShortRepoPath())
|
||||
case models.ActionApprovePullRequest:
|
||||
title += ctx.Tr("action.approve_pull_request", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
pullLink := toPullLink(act)
|
||||
title += ctx.TrHTMLEscapeArgs("action.approve_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionRejectPullRequest:
|
||||
title += ctx.Tr("action.reject_pull_request", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
pullLink := toPullLink(act)
|
||||
title += ctx.TrHTMLEscapeArgs("action.reject_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionCommentPull:
|
||||
title += ctx.Tr("action.comment_pull", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
pullLink := toPullLink(act)
|
||||
title += ctx.TrHTMLEscapeArgs("action.comment_pull", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
|
||||
case models.ActionPublishRelease:
|
||||
title += ctx.Tr("action.publish_release", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath(), act.Content)
|
||||
releaseLink := toReleaseLink(act)
|
||||
if link.Href == "#" {
|
||||
link.Href = releaseLink
|
||||
}
|
||||
title += ctx.TrHTMLEscapeArgs("action.publish_release", act.GetRepoLink(), releaseLink, act.ShortRepoPath(), act.Content)
|
||||
case models.ActionPullReviewDismissed:
|
||||
title += ctx.Tr("action.review_dismissed", act.GetRepoLink(), act.GetIssueInfos()[0], act.ShortRepoPath(), act.GetIssueInfos()[1])
|
||||
pullLink := toPullLink(act)
|
||||
title += ctx.TrHTMLEscapeArgs("action.review_dismissed", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath(), act.GetIssueInfos()[1])
|
||||
case models.ActionStarRepo:
|
||||
title += ctx.Tr("action.starred_repo", act.GetRepoLink(), act.GetRepoPath())
|
||||
link = &feeds.Link{Href: act.GetRepoLink()}
|
||||
link.Href = act.GetRepoLink()
|
||||
title += ctx.TrHTMLEscapeArgs("action.starred_repo", act.GetRepoLink(), act.GetRepoPath())
|
||||
case models.ActionWatchRepo:
|
||||
title += ctx.Tr("action.watched_repo", act.GetRepoLink(), act.GetRepoPath())
|
||||
link = &feeds.Link{Href: act.GetRepoLink()}
|
||||
link.Href = act.GetRepoLink()
|
||||
title += ctx.TrHTMLEscapeArgs("action.watched_repo", act.GetRepoLink(), act.GetRepoPath())
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown action type: %v", act.OpType)
|
||||
}
|
||||
|
@ -104,7 +178,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions []*models.Action) (ite
|
|||
desc += "\n\n"
|
||||
}
|
||||
desc += fmt.Sprintf("<a href=\"%s\">%s</a>\n%s",
|
||||
fmt.Sprintf("%s/commit/%s", act.GetRepoLink(), commit.Sha1),
|
||||
html.EscapeString(fmt.Sprintf("%s/commit/%s", act.GetRepoLink(), commit.Sha1)),
|
||||
commit.Sha1,
|
||||
templates.RenderCommitMessage(commit.Message, repoLink, nil),
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ package org
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
|
@ -76,7 +77,7 @@ func SettingsPost(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
// reset ctx.org.OrgLink with new name
|
||||
ctx.Org.OrgLink = setting.AppSubURL + "/org/" + form.Name
|
||||
ctx.Org.OrgLink = setting.AppSubURL + "/org/" + url.PathEscape(form.Name)
|
||||
log.Trace("Organization name changed: %s -> %s", org.Name, form.Name)
|
||||
nameChanged = false
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package org
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
|
@ -105,7 +106,7 @@ func TeamsAction(ctx *context.Context) {
|
|||
}
|
||||
ctx.JSON(http.StatusOK,
|
||||
map[string]interface{}{
|
||||
"redirect": ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName,
|
||||
"redirect": ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName),
|
||||
})
|
||||
return
|
||||
case "add":
|
||||
|
@ -119,7 +120,7 @@ func TeamsAction(ctx *context.Context) {
|
|||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName))
|
||||
} else {
|
||||
ctx.ServerError(" GetUserByName", err)
|
||||
}
|
||||
|
@ -128,7 +129,7 @@ func TeamsAction(ctx *context.Context) {
|
|||
|
||||
if u.IsOrganization() {
|
||||
ctx.Flash.Error(ctx.Tr("form.cannot_add_org_to_team"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -156,7 +157,7 @@ func TeamsAction(ctx *context.Context) {
|
|||
|
||||
switch page {
|
||||
case "team":
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName))
|
||||
case "home":
|
||||
ctx.Redirect(ctx.Org.Organization.HomeLink())
|
||||
default:
|
||||
|
@ -181,7 +182,7 @@ func TeamsRepoAction(ctx *context.Context) {
|
|||
if err != nil {
|
||||
if models.IsErrRepoNotExist(err) {
|
||||
ctx.Flash.Error(ctx.Tr("org.teams.add_nonexistent_repo"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName) + "/repositories")
|
||||
return
|
||||
}
|
||||
ctx.ServerError("GetRepositoryByName", err)
|
||||
|
@ -204,11 +205,11 @@ func TeamsRepoAction(ctx *context.Context) {
|
|||
|
||||
if action == "addall" || action == "removeall" {
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories",
|
||||
"redirect": ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName) + "/repositories",
|
||||
})
|
||||
return
|
||||
}
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName) + "/repositories")
|
||||
}
|
||||
|
||||
// NewTeam render create new team page
|
||||
|
@ -273,7 +274,7 @@ func NewTeamPost(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
log.Trace("Team created: %s/%s", ctx.Org.Organization.Name, t.Name)
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(t.LowerName))
|
||||
}
|
||||
|
||||
// TeamMembers render team members page
|
||||
|
@ -375,7 +376,7 @@ func EditTeamPost(ctx *context.Context) {
|
|||
}
|
||||
return
|
||||
}
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(t.LowerName))
|
||||
}
|
||||
|
||||
// DeleteTeam response for the delete team request
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
gotemplate "html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
|
@ -17,6 +18,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/highlight"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -54,7 +56,7 @@ func RefBlame(ctx *context.Context) {
|
|||
rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL()
|
||||
|
||||
if len(ctx.Repo.TreePath) > 0 {
|
||||
treeLink += "/" + ctx.Repo.TreePath
|
||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
}
|
||||
|
||||
var treeNames []string
|
||||
|
@ -85,7 +87,7 @@ func RefBlame(ctx *context.Context) {
|
|||
ctx.Data["TreeNames"] = treeNames
|
||||
ctx.Data["BranchLink"] = branchLink
|
||||
|
||||
ctx.Data["RawFileLink"] = rawLink + "/" + ctx.Repo.TreePath
|
||||
ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
ctx.Data["PageIsViewCode"] = true
|
||||
|
||||
ctx.Data["IsBlame"] = true
|
||||
|
@ -236,8 +238,8 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m
|
|||
br.RepoLink = repoLink
|
||||
br.PartSha = part.Sha
|
||||
br.PreviousSha = previousSha
|
||||
br.PreviousShaURL = fmt.Sprintf("%s/blame/commit/%s/%s", repoLink, previousSha, ctx.Repo.TreePath)
|
||||
br.CommitURL = fmt.Sprintf("%s/commit/%s", repoLink, part.Sha)
|
||||
br.PreviousShaURL = fmt.Sprintf("%s/blame/commit/%s/%s", repoLink, url.PathEscape(previousSha), util.PathEscapeSegments(ctx.Repo.TreePath))
|
||||
br.CommitURL = fmt.Sprintf("%s/commit/%s", repoLink, url.PathEscape(part.Sha))
|
||||
br.CommitMessage = commit.CommitMessage
|
||||
br.CommitSince = commitSince
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ package repo
|
|||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
|
@ -323,8 +322,7 @@ func Diff(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
}
|
||||
headTarget := path.Join(userName, repoName)
|
||||
setCompareContext(ctx, parentCommit, commit, headTarget)
|
||||
setCompareContext(ctx, parentCommit, commit, userName, repoName)
|
||||
ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
|
||||
ctx.Data["Commit"] = commit
|
||||
ctx.Data["Diff"] = diff
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"html"
|
||||
"io"
|
||||
"net/http"
|
||||
"path"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
@ -38,7 +38,7 @@ const (
|
|||
)
|
||||
|
||||
// setCompareContext sets context data.
|
||||
func setCompareContext(ctx *context.Context, base *git.Commit, head *git.Commit, headTarget string) {
|
||||
func setCompareContext(ctx *context.Context, base *git.Commit, head *git.Commit, headOwner, headName string) {
|
||||
ctx.Data["BaseCommit"] = base
|
||||
ctx.Data["HeadCommit"] = head
|
||||
|
||||
|
@ -54,22 +54,28 @@ func setCompareContext(ctx *context.Context, base *git.Commit, head *git.Commit,
|
|||
return blob
|
||||
}
|
||||
|
||||
setPathsCompareContext(ctx, base, head, headTarget)
|
||||
setPathsCompareContext(ctx, base, head, headOwner, headName)
|
||||
setImageCompareContext(ctx)
|
||||
setCsvCompareContext(ctx)
|
||||
}
|
||||
|
||||
// setPathsCompareContext sets context data for source and raw paths
|
||||
func setPathsCompareContext(ctx *context.Context, base *git.Commit, head *git.Commit, headTarget string) {
|
||||
sourcePath := setting.AppSubURL + "/%s/src/commit/%s"
|
||||
rawPath := setting.AppSubURL + "/%s/raw/commit/%s"
|
||||
// SourceCommitURL creates a relative URL for a commit in the given repository
|
||||
func SourceCommitURL(owner, name string, commit *git.Commit) string {
|
||||
return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/src/commit/" + url.PathEscape(commit.ID.String())
|
||||
}
|
||||
|
||||
ctx.Data["SourcePath"] = fmt.Sprintf(sourcePath, headTarget, head.ID)
|
||||
ctx.Data["RawPath"] = fmt.Sprintf(rawPath, headTarget, head.ID)
|
||||
// RawCommitURL creates a relative URL for the raw commit in the given repository
|
||||
func RawCommitURL(owner, name string, commit *git.Commit) string {
|
||||
return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/raw/commit/" + url.PathEscape(commit.ID.String())
|
||||
}
|
||||
|
||||
// setPathsCompareContext sets context data for source and raw paths
|
||||
func setPathsCompareContext(ctx *context.Context, base *git.Commit, head *git.Commit, headOwner, headName string) {
|
||||
ctx.Data["SourcePath"] = SourceCommitURL(headOwner, headName, head)
|
||||
ctx.Data["RawPath"] = RawCommitURL(headOwner, headName, head)
|
||||
if base != nil {
|
||||
baseTarget := path.Join(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
ctx.Data["BeforeSourcePath"] = fmt.Sprintf(sourcePath, baseTarget, base.ID)
|
||||
ctx.Data["BeforeRawPath"] = fmt.Sprintf(rawPath, baseTarget, base.ID)
|
||||
ctx.Data["BeforeSourcePath"] = SourceCommitURL(headOwner, headName, head)
|
||||
ctx.Data["BeforeRawPath"] = RawCommitURL(headOwner, headName, head)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,8 +625,7 @@ func PrepareCompareDiff(
|
|||
ctx.Data["Username"] = ci.HeadUser.Name
|
||||
ctx.Data["Reponame"] = ci.HeadRepo.Name
|
||||
|
||||
headTarget := path.Join(ci.HeadUser.Name, repo.Name)
|
||||
setCompareContext(ctx, baseCommit, headCommit, headTarget)
|
||||
setCompareContext(ctx, baseCommit, headCommit, ci.HeadUser.Name, repo.Name)
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
|
|||
ctx.Data["TreePath"] = form.TreePath
|
||||
ctx.Data["TreeNames"] = treeNames
|
||||
ctx.Data["TreePaths"] = treePaths
|
||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/branch/" + ctx.Repo.BranchName
|
||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName)
|
||||
ctx.Data["FileContent"] = form.Content
|
||||
ctx.Data["commit_summary"] = form.CommitSummary
|
||||
ctx.Data["commit_message"] = form.CommitMessage
|
||||
|
@ -299,9 +299,9 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
|
|||
ctx.Error(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
} else if models.IsErrCommitIDDoesNotMatch(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+ctx.Repo.CommitID), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplEditFile, &form)
|
||||
} else if git.IsErrPushOutOfDate(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+util.PathEscapeSegments(form.NewBranchName)), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(form.NewBranchName)), tplEditFile, &form)
|
||||
} else if git.IsErrPushRejected(err) {
|
||||
errPushRej := err.(*git.ErrPushRejected)
|
||||
if len(errPushRej.Message) == 0 {
|
||||
|
@ -495,7 +495,7 @@ func DeleteFilePost(ctx *context.Context) {
|
|||
ctx.Error(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
} else if models.IsErrCommitIDDoesNotMatch(err) || git.IsErrPushOutOfDate(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_deleting", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+ctx.Repo.CommitID), tplDeleteFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_deleting", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplDeleteFile, &form)
|
||||
} else if git.IsErrPushRejected(err) {
|
||||
errPushRej := err.(*git.ErrPushRejected)
|
||||
if len(errPushRej.Message) == 0 {
|
||||
|
@ -602,7 +602,7 @@ func UploadFilePost(ctx *context.Context) {
|
|||
ctx.Data["TreePath"] = form.TreePath
|
||||
ctx.Data["TreeNames"] = treeNames
|
||||
ctx.Data["TreePaths"] = treePaths
|
||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/branch/" + branchName
|
||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName)
|
||||
ctx.Data["commit_summary"] = form.CommitSummary
|
||||
ctx.Data["commit_message"] = form.CommitMessage
|
||||
ctx.Data["commit_choice"] = form.CommitChoice
|
||||
|
@ -698,7 +698,7 @@ func UploadFilePost(ctx *context.Context) {
|
|||
branchErr := err.(models.ErrBranchAlreadyExists)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplUploadFile, &form)
|
||||
} else if git.IsErrPushOutOfDate(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+ctx.Repo.CommitID+"..."+util.PathEscapeSegments(form.NewBranchName)), tplUploadFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(ctx.Repo.CommitID)+"..."+util.PathEscapeSegments(form.NewBranchName)), tplUploadFile, &form)
|
||||
} else if git.IsErrPushRejected(err) {
|
||||
errPushRej := err.(*git.ErrPushRejected)
|
||||
if len(errPushRej.Message) == 0 {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -106,7 +107,7 @@ func MustAllowPulls(ctx *context.Context) {
|
|||
// User can send pull request if owns a forked repository.
|
||||
if ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID) {
|
||||
ctx.Repo.PullRequest.Allowed = true
|
||||
ctx.Repo.PullRequest.HeadInfo = ctx.User.Name + ":" + ctx.Repo.BranchName
|
||||
ctx.Repo.PullRequest.HeadInfoSubURL = url.PathEscape(ctx.User.Name) + ":" + util.PathEscapeSegments(ctx.Repo.BranchName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -764,7 +765,7 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleDirs [
|
|||
for _, repoLabel := range repoLabels {
|
||||
if strings.EqualFold(repoLabel.Name, metaLabel) {
|
||||
repoLabel.IsChecked = true
|
||||
labelIDs = append(labelIDs, fmt.Sprintf("%d", repoLabel.ID))
|
||||
labelIDs = append(labelIDs, strconv.FormatInt(repoLabel.ID, 10))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -983,6 +984,7 @@ func NewIssuePost(ctx *context.Context) {
|
|||
|
||||
issue := &models.Issue{
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
Title: form.Title,
|
||||
PosterID: ctx.User.ID,
|
||||
Poster: ctx.User,
|
||||
|
@ -1009,9 +1011,9 @@ func NewIssuePost(ctx *context.Context) {
|
|||
|
||||
log.Trace("Issue created: %d/%d", repo.ID, issue.ID)
|
||||
if ctx.FormString("redirect_after_creation") == "project" {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/projects/" + fmt.Sprint(form.ProjectID))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/projects/" + strconv.FormatInt(form.ProjectID, 10))
|
||||
} else {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/issues/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1097,13 +1099,16 @@ func ViewIssue(ctx *context.Context) {
|
|||
}
|
||||
return
|
||||
}
|
||||
if issue.Repo == nil {
|
||||
issue.Repo = ctx.Repo.Repository
|
||||
}
|
||||
|
||||
// Make sure type and URL matches.
|
||||
if ctx.Params(":type") == "issues" && issue.IsPull {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if ctx.Params(":type") == "pulls" && !issue.IsPull {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/issues/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1496,7 +1501,7 @@ func ViewIssue(ctx *context.Context) {
|
|||
log.Error("IsProtectedBranch: %v", err)
|
||||
} else if !protected {
|
||||
canDelete = true
|
||||
ctx.Data["DeleteBranchLink"] = ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index) + "/cleanup"
|
||||
ctx.Data["DeleteBranchLink"] = issue.Link() + "/cleanup"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1624,7 +1629,7 @@ func ViewIssue(ctx *context.Context) {
|
|||
ctx.Data["NumParticipants"] = len(participants)
|
||||
ctx.Data["Issue"] = issue
|
||||
ctx.Data["ReadOnly"] = false
|
||||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login?redirect_to=" + ctx.Data["Link"].(string)
|
||||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login?redirect_to=" + url.QueryEscape(ctx.Data["Link"].(string))
|
||||
ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.User.ID)
|
||||
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
|
||||
ctx.Data["HasProjectsWritePermission"] = ctx.Repo.CanWrite(unit.TypeProjects)
|
||||
|
@ -1773,7 +1778,7 @@ func UpdateIssueContent(ctx *context.Context) {
|
|||
}
|
||||
|
||||
content, err := markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.FormString("context"),
|
||||
URLPrefix: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
|
@ -2205,7 +2210,7 @@ func UpdateCommentContent(ctx *context.Context) {
|
|||
}
|
||||
|
||||
content, err := markdown.RenderString(&markup.RenderContext{
|
||||
URLPrefix: ctx.FormString("context"),
|
||||
URLPrefix: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
|
||||
Metas: ctx.Repo.Repository.ComposeMetas(),
|
||||
GitRepo: ctx.Repo.GitRepo,
|
||||
Ctx: ctx,
|
||||
|
|
|
@ -94,6 +94,7 @@ func GetActiveStopwatch(c *context.Context) {
|
|||
}
|
||||
|
||||
c.Data["ActiveStopwatch"] = StopwatchTmplInfo{
|
||||
issue.Link(),
|
||||
issue.Repo.FullName(),
|
||||
issue.Index,
|
||||
sw.Seconds() + 1, // ensure time is never zero in ui
|
||||
|
@ -102,6 +103,7 @@ func GetActiveStopwatch(c *context.Context) {
|
|||
|
||||
// StopwatchTmplInfo is a view on a stopwatch specifically for template rendering
|
||||
type StopwatchTmplInfo struct {
|
||||
IssueLink string
|
||||
RepoSlug string
|
||||
IssueIndex int64
|
||||
Seconds int64
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
gotemplate "html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -285,7 +286,7 @@ func LFSFileGet(ctx *context.Context) {
|
|||
|
||||
fileSize := meta.Size
|
||||
ctx.Data["FileSize"] = meta.Size
|
||||
ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, "direct")
|
||||
ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s/%s.git/info/lfs/objects/%s/%s", setting.AppURL, url.PathEscape(ctx.Repo.Repository.OwnerName), url.PathEscape(ctx.Repo.Repository.Name), url.PathEscape(meta.Oid), "direct")
|
||||
switch {
|
||||
case isRepresentableAsText:
|
||||
if st.IsSvgImage() {
|
||||
|
|
|
@ -7,6 +7,7 @@ package repo
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
|
@ -237,7 +238,7 @@ func MigratePost(ctx *context.Context) {
|
|||
|
||||
err = task.MigrateRepository(ctx.User, ctxUser, opts)
|
||||
if err == nil {
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + opts.RepoName)
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(opts.RepoName))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ package repo
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
|
@ -244,7 +245,7 @@ func ChangeMilestoneStatus(ctx *context.Context) {
|
|||
}
|
||||
return
|
||||
}
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=" + ctx.Params(":action"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=" + url.QueryEscape(ctx.Params(":action")))
|
||||
}
|
||||
|
||||
// DeleteMilestone delete a milestone
|
||||
|
|
|
@ -7,6 +7,7 @@ package repo
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
|
@ -173,7 +174,7 @@ func ChangeProjectStatus(ctx *context.Context) {
|
|||
}
|
||||
return
|
||||
}
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/projects?state=" + ctx.Params(":action"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/projects?state=" + url.QueryEscape(ctx.Params(":action")))
|
||||
}
|
||||
|
||||
// DeleteProject delete a project
|
||||
|
|
|
@ -10,8 +10,10 @@ import (
|
|||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html"
|
||||
"net/http"
|
||||
"path"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -34,7 +36,6 @@ import (
|
|||
"code.gitea.io/gitea/services/gitdiff"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
"github.com/unknwon/com"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -109,8 +110,7 @@ func getForkRepository(ctx *context.Context) *models.Repository {
|
|||
ctx.Data["IsPrivate"] = forkRepo.IsPrivate || forkRepo.Owner.Visibility == structs.VisibleTypePrivate
|
||||
canForkToUser := forkRepo.OwnerID != ctx.User.ID && !ctx.User.HasForkedRepo(forkRepo.ID)
|
||||
|
||||
ctx.Data["ForkFrom"] = forkRepo.Owner.Name + "/" + forkRepo.Name
|
||||
ctx.Data["ForkFromOwnerID"] = forkRepo.Owner.ID
|
||||
ctx.Data["ForkRepo"] = forkRepo
|
||||
|
||||
if err := ctx.User.GetOwnedOrganizations(); err != nil {
|
||||
ctx.ServerError("GetOwnedOrganizations", err)
|
||||
|
@ -202,7 +202,7 @@ func ForkPost(ctx *context.Context) {
|
|||
}
|
||||
repo, has := models.HasForkedRepo(ctxUser.ID, traverseParentRepo.ID)
|
||||
if has {
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + repo.Name)
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name))
|
||||
return
|
||||
}
|
||||
if !traverseParentRepo.IsFork {
|
||||
|
@ -248,7 +248,7 @@ func ForkPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
log.Trace("Repository forked[%d]: %s/%s", forkRepo.ID, ctxUser.Name, repo.Name)
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + repo.Name)
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name))
|
||||
}
|
||||
|
||||
func checkPullInfo(ctx *context.Context) *models.Issue {
|
||||
|
@ -682,8 +682,7 @@ func ViewPullFiles(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
headTarget := path.Join(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
setCompareContext(ctx, baseCommit, commit, headTarget)
|
||||
setCompareContext(ctx, baseCommit, commit, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
ctx.Data["RequireSimpleMDE"] = true
|
||||
|
@ -746,7 +745,7 @@ func UpdatePullRequest(ctx *context.Context) {
|
|||
// ToDo: add check if maintainers are allowed to change branch ... (need migration & co)
|
||||
if (!allowedUpdateByMerge && !rebase) || (rebase && !allowedUpdateByRebase) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.update_not_allowed"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -766,7 +765,7 @@ func UpdatePullRequest(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrRebaseConflicts(err) {
|
||||
conflictError := err.(models.ErrRebaseConflicts)
|
||||
|
@ -780,19 +779,19 @@ func UpdatePullRequest(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
|
||||
}
|
||||
ctx.Flash.Error(err.Error())
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.pulls.update_branch_success"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
}
|
||||
|
||||
// MergePullRequest response for merging pull request
|
||||
|
@ -805,11 +804,11 @@ func MergePullRequest(ctx *context.Context) {
|
|||
if issue.IsClosed {
|
||||
if issue.IsPull {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.is_closed"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.closed_title"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/issues/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -822,13 +821,13 @@ func MergePullRequest(ctx *context.Context) {
|
|||
}
|
||||
if !allowedMerge {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.update_not_allowed"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if pr.HasMerged {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.has_merged"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -837,11 +836,11 @@ func MergePullRequest(ctx *context.Context) {
|
|||
if err = pull_service.MergedManually(pr, ctx.User, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
|
||||
if models.IsErrInvalidMergeStyle(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.invalid_merge_option"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if strings.Contains(err.Error(), "Wrong commit ID") {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.wrong_commit_id"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -849,19 +848,19 @@ func MergePullRequest(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if !pr.CanAutoMerge() {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if pr.IsWorkInProgress() {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_wip"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -875,14 +874,14 @@ func MergePullRequest(ctx *context.Context) {
|
|||
return
|
||||
} else if !isRepoAdmin {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -914,14 +913,14 @@ func MergePullRequest(ctx *context.Context) {
|
|||
|
||||
if !noDeps {
|
||||
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.pr_close_blocked"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
|
||||
if err = pull_service.Merge(pr, ctx.User, ctx.Repo.GitRepo, models.MergeStyle(form.Do), message); err != nil {
|
||||
if models.IsErrInvalidMergeStyle(err) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.invalid_merge_option"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrMergeConflicts(err) {
|
||||
conflictError := err.(models.ErrMergeConflicts)
|
||||
|
@ -935,7 +934,7 @@ func MergePullRequest(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrRebaseConflicts(err) {
|
||||
conflictError := err.(models.ErrRebaseConflicts)
|
||||
|
@ -949,17 +948,17 @@ func MergePullRequest(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if models.IsErrMergeUnrelatedHistories(err) {
|
||||
log.Debug("MergeUnrelatedHistories error: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.unrelated_histories"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if git.IsErrPushOutOfDate(err) {
|
||||
log.Debug("MergePushOutOfDate error: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.pulls.merge_out_of_date"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
} else if git.IsErrPushRejected(err) {
|
||||
log.Debug("MergePushRejected error: %v", err)
|
||||
|
@ -979,7 +978,7 @@ func MergePullRequest(ctx *context.Context) {
|
|||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
}
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
return
|
||||
}
|
||||
ctx.ServerError("Merge", err)
|
||||
|
@ -1008,7 +1007,7 @@ func MergePullRequest(ctx *context.Context) {
|
|||
deleteBranch(ctx, pr, headRepo)
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pr.Index))
|
||||
ctx.Redirect(issue.Link())
|
||||
}
|
||||
|
||||
func stopTimerIfAvailable(user *models.User, issue *models.Issue) error {
|
||||
|
@ -1097,6 +1096,7 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
|||
|
||||
pullIssue := &models.Issue{
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
Title: form.Title,
|
||||
PosterID: ctx.User.ID,
|
||||
Poster: ctx.User,
|
||||
|
@ -1138,7 +1138,7 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
|||
}
|
||||
ctx.Flash.Error(flashError)
|
||||
}
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pullIssue.Index))
|
||||
ctx.Redirect(pullIssue.Link())
|
||||
return
|
||||
}
|
||||
ctx.ServerError("NewPullRequest", err)
|
||||
|
@ -1146,7 +1146,7 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
log.Trace("Pull request created: %d/%d", repo.ID, pullIssue.ID)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(pullIssue.Index))
|
||||
ctx.Redirect(pullIssue.Link())
|
||||
}
|
||||
|
||||
// TriggerTask response for a trigger task request
|
||||
|
@ -1261,7 +1261,7 @@ func CleanUpPullRequest(ctx *context.Context) {
|
|||
|
||||
defer func() {
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": pr.BaseRepo.Link() + "/pulls/" + fmt.Sprint(issue.Index),
|
||||
"redirect": issue.Link(),
|
||||
})
|
||||
}()
|
||||
|
||||
|
@ -1369,7 +1369,7 @@ func UpdatePullRequestTarget(ctx *context.Context) {
|
|||
err := err.(models.ErrPullRequestAlreadyExists)
|
||||
|
||||
RepoRelPath := ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
||||
errorMessage := ctx.Tr("repo.pulls.has_pull_request", ctx.Repo.RepoLink, RepoRelPath, err.IssueID)
|
||||
errorMessage := ctx.Tr("repo.pulls.has_pull_request", html.EscapeString(ctx.Repo.RepoLink+"/pulls/"+strconv.FormatInt(err.IssueID, 10)), html.EscapeString(RepoRelPath), err.IssueID) // FIXME: Creates url insidde locale string
|
||||
|
||||
ctx.Flash.Error(errorMessage)
|
||||
ctx.JSON(http.StatusConflict, map[string]interface{}{
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/upload"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
releaseservice "code.gitea.io/gitea/services/release"
|
||||
|
@ -350,7 +351,7 @@ func NewReleasePost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.tag.create_success", form.TagName))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/tag/" + form.TagName)
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/tag/" + util.PathEscapeSegments(form.TagName))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ func CreatePost(ctx *context.Context) {
|
|||
repo, err = repo_service.GenerateRepository(ctx.User, ctxUser, templateRepo, opts)
|
||||
if err == nil {
|
||||
log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + repo.Name)
|
||||
ctx.Redirect(repo.Link())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
@ -263,7 +263,7 @@ func CreatePost(ctx *context.Context) {
|
|||
})
|
||||
if err == nil {
|
||||
log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
|
||||
ctx.Redirect(ctxUser.HomeLink() + "/" + repo.Name)
|
||||
ctx.Redirect(repo.Link())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -615,7 +615,7 @@ func SettingsPost(ctx *context.Context) {
|
|||
|
||||
log.Trace("Repository transfer process was started: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newOwner)
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_started", newOwner.DisplayName()))
|
||||
ctx.Redirect(ctx.Repo.Owner.HomeLink() + "/" + repo.Name + "/settings")
|
||||
ctx.Redirect(repo.Link() + "/settings")
|
||||
|
||||
case "cancel_transfer":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
|
@ -627,7 +627,7 @@ func SettingsPost(ctx *context.Context) {
|
|||
if err != nil {
|
||||
if models.IsErrNoPendingTransfer(err) {
|
||||
ctx.Flash.Error("repo.settings.transfer_abort_invalid")
|
||||
ctx.Redirect(ctx.User.HomeLink() + "/" + repo.Name + "/settings")
|
||||
ctx.Redirect(repo.Link() + "/settings")
|
||||
} else {
|
||||
ctx.ServerError("GetPendingRepositoryTransfer", err)
|
||||
}
|
||||
|
@ -647,7 +647,7 @@ func SettingsPost(ctx *context.Context) {
|
|||
|
||||
log.Trace("Repository transfer process was cancelled: %s/%s ", ctx.Repo.Owner.Name, repo.Name)
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_abort_success", repoTransfer.Recipient.Name))
|
||||
ctx.Redirect(ctx.Repo.Owner.HomeLink() + "/" + repo.Name + "/settings")
|
||||
ctx.Redirect(repo.Link() + "/settings")
|
||||
|
||||
case "delete":
|
||||
if !ctx.Repo.IsOwner() {
|
||||
|
@ -796,7 +796,7 @@ func Collaboration(ctx *context.Context) {
|
|||
func CollaborationPost(ctx *context.Context) {
|
||||
name := utils.RemoveUsernameParameterSuffix(strings.ToLower(ctx.FormString("collaborator")))
|
||||
if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -804,7 +804,7 @@ func CollaborationPost(ctx *context.Context) {
|
|||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
|
||||
} else {
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
}
|
||||
|
@ -813,14 +813,14 @@ func CollaborationPost(ctx *context.Context) {
|
|||
|
||||
if !u.IsActive {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_inactive_user"))
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
|
||||
return
|
||||
}
|
||||
|
||||
// Organization is not allowed to be added as a collaborator.
|
||||
if u.IsOrganization() {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.org_not_allowed_to_be_collaborator"))
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -840,7 +840,7 @@ func CollaborationPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
|
||||
}
|
||||
|
||||
// ChangeCollaborationAccessMode response for changing access of a collaboration
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
|
@ -89,7 +90,7 @@ func ProtectedBranchPost(ctx *context.Context) {
|
|||
log.Trace("Repository basic settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
|
||||
default:
|
||||
ctx.NotFound("", nil)
|
||||
}
|
||||
|
@ -197,7 +198,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
|||
}
|
||||
if f.RequiredApprovals < 0 {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_required_approvals_min"))
|
||||
ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, branch))
|
||||
ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, util.PathEscapeSegments(branch)))
|
||||
}
|
||||
|
||||
var whitelistUsers, whitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams, approvalsWhitelistUsers, approvalsWhitelistTeams []int64
|
||||
|
@ -274,7 +275,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_protect_branch_success", branch))
|
||||
ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, branch))
|
||||
ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, util.PathEscapeSegments(branch)))
|
||||
} else {
|
||||
if protectBranch != nil {
|
||||
if err := ctx.Repo.Repository.DeleteProtectedBranch(protectBranch.ID); err != nil {
|
||||
|
|
|
@ -58,7 +58,7 @@ func NewProtectedTagPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.Path)
|
||||
ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
|
||||
}
|
||||
|
||||
// EditProtectedTag render the page to edit a protect tag
|
||||
|
|
|
@ -232,7 +232,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
|||
}
|
||||
if readmeFile != nil {
|
||||
readmeFile.name = entry.Name() + "/" + readmeFile.name
|
||||
readmeTreelink = treeLink + "/" + entry.GetSubJumpablePathName()
|
||||
readmeTreelink = treeLink + "/" + util.PathEscapeSegments(entry.GetSubJumpablePathName())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
|||
fileSize = meta.Size
|
||||
ctx.Data["FileSize"] = meta.Size
|
||||
filenameBase64 := base64.RawURLEncoding.EncodeToString([]byte(readmeFile.name))
|
||||
ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, filenameBase64)
|
||||
ctx.Data["RawFileLink"] = fmt.Sprintf("%s.git/info/lfs/objects/%s/%s", ctx.Repo.Repository.HTMLURL(), url.PathEscape(meta.Oid), url.PathEscape(filenameBase64))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
|||
fileSize := blob.Size()
|
||||
ctx.Data["FileIsSymlink"] = entry.IsLink()
|
||||
ctx.Data["FileName"] = blob.Name()
|
||||
ctx.Data["RawFileLink"] = rawLink + "/" + ctx.Repo.TreePath
|
||||
ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := util.ReadAtMost(dataRc, buf)
|
||||
|
@ -422,7 +422,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
|||
isTextFile = st.IsText()
|
||||
|
||||
fileSize = meta.Size
|
||||
ctx.Data["RawFileLink"] = fmt.Sprintf("%s/media/%s/%s", ctx.Repo.RepoLink, ctx.Repo.BranchNameSubURL(), ctx.Repo.TreePath)
|
||||
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -628,7 +628,7 @@ func checkHomeCodeViewable(ctx *context.Context) {
|
|||
}
|
||||
|
||||
if firstUnit != nil {
|
||||
ctx.Redirect(fmt.Sprintf("%s/%s%s", setting.AppSubURL, ctx.Repo.Repository.FullName(), firstUnit.URI))
|
||||
ctx.Redirect(fmt.Sprintf("%s%s", ctx.Repo.Repository.Link(), firstUnit.URI))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -684,7 +684,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
|
|||
return nil
|
||||
}
|
||||
|
||||
ctx.Data["LastCommitLoaderURL"] = ctx.Repo.RepoLink + "/lastcommit/" + ctx.Repo.CommitID + "/" + ctx.Repo.TreePath
|
||||
ctx.Data["LastCommitLoaderURL"] = ctx.Repo.RepoLink + "/lastcommit/" + url.PathEscape(ctx.Repo.CommitID) + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
|
||||
// Get current entry user currently looking at.
|
||||
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
|
@ -766,7 +766,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
|
|||
treeLink := branchLink
|
||||
|
||||
if len(ctx.Repo.TreePath) > 0 {
|
||||
treeLink += "/" + ctx.Repo.TreePath
|
||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
}
|
||||
|
||||
ctx.Data["TreeLink"] = treeLink
|
||||
|
@ -815,7 +815,7 @@ func renderCode(ctx *context.Context) {
|
|||
rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL()
|
||||
|
||||
if len(ctx.Repo.TreePath) > 0 {
|
||||
treeLink += "/" + ctx.Repo.TreePath
|
||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
}
|
||||
|
||||
// Get Topics of this repo
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
|
@ -414,7 +415,7 @@ func TelegramHooksNewPost(ctx *context.Context) {
|
|||
|
||||
w := &webhook.Webhook{
|
||||
RepoID: orCtx.RepoID,
|
||||
URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", form.BotToken, form.ChatID),
|
||||
URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)),
|
||||
ContentType: webhook.ContentTypeJSON,
|
||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||
IsActive: form.Active,
|
||||
|
@ -468,7 +469,7 @@ func MatrixHooksNewPost(ctx *context.Context) {
|
|||
|
||||
w := &webhook.Webhook{
|
||||
RepoID: orCtx.RepoID,
|
||||
URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, form.RoomID),
|
||||
URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)),
|
||||
ContentType: webhook.ContentTypeJSON,
|
||||
HTTPMethod: "PUT",
|
||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||
|
@ -976,7 +977,7 @@ func TelegramHooksEditPost(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
w.Meta = string(meta)
|
||||
w.URL = fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", form.BotToken, form.ChatID)
|
||||
w.URL = fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID))
|
||||
w.HookEvent = ParseHookEvent(form.WebhookForm)
|
||||
w.IsActive = form.Active
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
|
@ -1020,7 +1021,7 @@ func MatrixHooksEditPost(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
w.Meta = string(meta)
|
||||
w.URL = fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, form.RoomID)
|
||||
w.URL = fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID))
|
||||
|
||||
w.HookEvent = ParseHookEvent(form.WebhookForm)
|
||||
w.IsActive = form.Active
|
||||
|
@ -1162,7 +1163,7 @@ func TestWebhook(ctx *context.Context) {
|
|||
apiCommit := &api.PayloadCommit{
|
||||
ID: commit.ID.String(),
|
||||
Message: commit.Message(),
|
||||
URL: ctx.Repo.Repository.HTMLURL() + "/commit/" + commit.ID.String(),
|
||||
URL: ctx.Repo.Repository.HTMLURL() + "/commit/" + url.PathEscape(commit.ID.String()),
|
||||
Author: &api.PayloadUser{
|
||||
Name: commit.Author.Name,
|
||||
Email: commit.Author.Email,
|
||||
|
|
|
@ -180,7 +180,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
|||
ctx.Data["Pages"] = pages
|
||||
|
||||
// get requested pagename
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params("*"))
|
||||
if len(pageName) == 0 {
|
||||
pageName = "Home"
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
|||
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
if noEntry {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
|
||||
}
|
||||
if entry == nil || ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
|
@ -276,7 +276,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
|||
}
|
||||
|
||||
// get requested pagename
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params("*"))
|
||||
if len(pageName) == 0 {
|
||||
pageName = "Home"
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
|||
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
if noEntry {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
|
||||
}
|
||||
if entry == nil || ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
|
@ -352,7 +352,7 @@ func renderEditPage(ctx *context.Context) {
|
|||
}()
|
||||
|
||||
// get requested pagename
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params("*"))
|
||||
if len(pageName) == 0 {
|
||||
pageName = "Home"
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ func renderEditPage(ctx *context.Context) {
|
|||
//lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||
data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
if noEntry {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
|
||||
}
|
||||
if entry == nil || ctx.Written() {
|
||||
return
|
||||
|
@ -378,6 +378,32 @@ func renderEditPage(ctx *context.Context) {
|
|||
ctx.Data["footerContent"] = ""
|
||||
}
|
||||
|
||||
// WikiPost renders post of wiki page
|
||||
func WikiPost(ctx *context.Context) {
|
||||
switch ctx.FormString("action") {
|
||||
case "_new":
|
||||
if !ctx.Repo.CanWrite(unit.TypeWiki) {
|
||||
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
|
||||
return
|
||||
}
|
||||
NewWikiPost(ctx)
|
||||
return
|
||||
case "_delete":
|
||||
if !ctx.Repo.CanWrite(unit.TypeWiki) {
|
||||
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
|
||||
return
|
||||
}
|
||||
DeleteWikiPagePost(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanWrite(unit.TypeWiki) {
|
||||
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
|
||||
return
|
||||
}
|
||||
EditWikiPost(ctx)
|
||||
}
|
||||
|
||||
// Wiki renders single wiki page
|
||||
func Wiki(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
|
@ -389,6 +415,29 @@ func Wiki(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
switch ctx.FormString("action") {
|
||||
case "_pages":
|
||||
WikiPages(ctx)
|
||||
return
|
||||
case "_revision":
|
||||
WikiRevision(ctx)
|
||||
return
|
||||
case "_edit":
|
||||
if !ctx.Repo.CanWrite(unit.TypeWiki) {
|
||||
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
|
||||
return
|
||||
}
|
||||
EditWiki(ctx)
|
||||
return
|
||||
case "_new":
|
||||
if !ctx.Repo.CanWrite(unit.TypeWiki) {
|
||||
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
|
||||
return
|
||||
}
|
||||
NewWiki(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
wikiRepo, entry := renderViewPage(ctx)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
|
@ -652,7 +701,7 @@ func EditWikiPost(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
oldWikiName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
|
||||
oldWikiName := wiki_service.NormalizeWikiName(ctx.Params("*"))
|
||||
newWikiName := wiki_service.NormalizeWikiName(form.Title)
|
||||
|
||||
if len(form.Message) == 0 {
|
||||
|
@ -669,7 +718,7 @@ func EditWikiPost(ctx *context.Context) {
|
|||
|
||||
// DeleteWikiPagePost delete wiki page
|
||||
func DeleteWikiPagePost(ctx *context.Context) {
|
||||
wikiName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
|
||||
wikiName := wiki_service.NormalizeWikiName(ctx.Params("*"))
|
||||
if len(wikiName) == 0 {
|
||||
wikiName = "Home"
|
||||
}
|
||||
|
|
|
@ -76,8 +76,8 @@ func assertPagesMetas(t *testing.T, expectedNames []string, metas interface{}) {
|
|||
func TestWiki(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_pages")
|
||||
ctx.SetParams(":page", "Home")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_pages")
|
||||
ctx.SetParams("*", "Home")
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
Wiki(ctx)
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
|
@ -88,7 +88,7 @@ func TestWiki(t *testing.T) {
|
|||
func TestWikiPages(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_pages")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_pages")
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
WikiPages(ctx)
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
|
@ -98,7 +98,7 @@ func TestWikiPages(t *testing.T) {
|
|||
func TestNewWiki(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_new")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
NewWiki(ctx)
|
||||
|
@ -113,7 +113,7 @@ func TestNewWikiPost(t *testing.T) {
|
|||
} {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_new")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
web.SetForm(ctx, &forms.NewWikiForm{
|
||||
|
@ -131,7 +131,7 @@ func TestNewWikiPost(t *testing.T) {
|
|||
func TestNewWikiPost_ReservedName(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_new")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
web.SetForm(ctx, &forms.NewWikiForm{
|
||||
|
@ -148,8 +148,8 @@ func TestNewWikiPost_ReservedName(t *testing.T) {
|
|||
func TestEditWiki(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_edit/Home")
|
||||
ctx.SetParams(":page", "Home")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/Home?action=_edit")
|
||||
ctx.SetParams("*", "Home")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
EditWiki(ctx)
|
||||
|
@ -164,8 +164,8 @@ func TestEditWikiPost(t *testing.T) {
|
|||
"New/<page>",
|
||||
} {
|
||||
unittest.PrepareTestEnv(t)
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new/Home")
|
||||
ctx.SetParams(":page", "Home")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/Home?action=_new")
|
||||
ctx.SetParams("*", "Home")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
web.SetForm(ctx, &forms.NewWikiForm{
|
||||
|
@ -186,7 +186,7 @@ func TestEditWikiPost(t *testing.T) {
|
|||
func TestDeleteWikiPagePost(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/Home/delete")
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/Home?action=_delete")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
DeleteWikiPagePost(ctx)
|
||||
|
|
|
@ -887,5 +887,5 @@ func Email2User(ctx *context.Context) {
|
|||
}
|
||||
return
|
||||
}
|
||||
ctx.Redirect(setting.AppSubURL + "/user/" + u.Name)
|
||||
ctx.Redirect(u.HomeLink())
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ func NotificationStatusPost(c *context.Context) {
|
|||
}
|
||||
|
||||
if !c.FormBool("noredirect") {
|
||||
url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, c.FormString("page"))
|
||||
url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, url.QueryEscape(c.FormString("page")))
|
||||
c.Redirect(url, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -189,6 +189,5 @@ func NotificationPurgePost(c *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/notifications", setting.AppSubURL)
|
||||
c.Redirect(url, http.StatusSeeOther)
|
||||
c.Redirect(setting.AppSubURL+"/notifications", http.StatusSeeOther)
|
||||
}
|
||||
|
|
|
@ -454,7 +454,7 @@ func AuthorizeOAuth(ctx *context.Context) {
|
|||
ctx.Data["State"] = form.State
|
||||
ctx.Data["Scope"] = form.Scope
|
||||
ctx.Data["Nonce"] = form.Nonce
|
||||
ctx.Data["ApplicationUserLink"] = "<a href=\"" + html.EscapeString(setting.AppURL) + html.EscapeString(url.PathEscape(user.LowerName)) + "\">@" + html.EscapeString(user.Name) + "</a>"
|
||||
ctx.Data["ApplicationUserLink"] = "<a href=\"" + html.EscapeString(user.HTMLURL()) + "\">@" + html.EscapeString(user.Name) + "</a>"
|
||||
ctx.Data["ApplicationRedirectDomainHTML"] = "<strong>" + html.EscapeString(form.RedirectURI) + "</strong>"
|
||||
// TODO document SESSION <=> FORM
|
||||
err = ctx.Session.Set("client_id", app.ClientID)
|
||||
|
|
|
@ -364,6 +364,6 @@ func Action(ctx *context.Context) {
|
|||
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: We should check this URL and make sure that it's a valid Gitea URL
|
||||
ctx.RedirectToFirst(ctx.FormString("redirect_to"), u.HomeLink())
|
||||
}
|
||||
|
|
|
@ -895,21 +895,23 @@ func RegisterRoutes(m *web.Route) {
|
|||
}, reqRepoProjectsReader, repo.MustEnableProjects)
|
||||
|
||||
m.Group("/wiki", func() {
|
||||
m.Get("/", repo.Wiki)
|
||||
m.Get("/{page}", repo.Wiki)
|
||||
m.Get("/_pages", repo.WikiPages)
|
||||
m.Get("/{page}/_revision", repo.WikiRevision)
|
||||
m.Combo("/").
|
||||
Get(repo.Wiki).
|
||||
Post(context.RepoMustNotBeArchived(),
|
||||
reqSignIn,
|
||||
reqRepoWikiWriter,
|
||||
bindIgnErr(forms.NewWikiForm{}),
|
||||
repo.WikiPost)
|
||||
m.Combo("/*").
|
||||
Get(repo.Wiki).
|
||||
Post(context.RepoMustNotBeArchived(),
|
||||
reqSignIn,
|
||||
reqRepoWikiWriter,
|
||||
bindIgnErr(forms.NewWikiForm{}),
|
||||
repo.WikiPost)
|
||||
m.Get("/commit/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
||||
m.Get("/commit/{sha:[a-f0-9]{7,40}}.{ext:patch|diff}", repo.RawDiff)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_new").Get(repo.NewWiki).
|
||||
Post(bindIgnErr(forms.NewWikiForm{}), repo.NewWikiPost)
|
||||
m.Combo("/{page}/_edit").Get(repo.EditWiki).
|
||||
Post(bindIgnErr(forms.NewWikiForm{}), repo.EditWikiPost)
|
||||
m.Post("/{page}/delete", repo.DeleteWikiPagePost)
|
||||
}, context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter)
|
||||
}, repo.MustEnableWiki, context.RepoRef(), func(ctx *context.Context) {
|
||||
}, repo.MustEnableWiki, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsWiki"] = true
|
||||
})
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue