diff options
Diffstat (limited to 'routers/web/repo/view_home.go')
-rw-r--r-- | routers/web/repo/view_home.go | 119 |
1 files changed, 47 insertions, 72 deletions
diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index 48fa47d738..f475e93f60 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -15,13 +15,12 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" - access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" - giturl "code.gitea.io/gitea/modules/git/url" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/htmlutil" "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" @@ -143,7 +142,7 @@ func prepareToRenderDirectory(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefFullName.ShortName()) } - subfolder, readmeFile, err := findReadmeFileInEntries(ctx, entries, true) + subfolder, readmeFile, err := findReadmeFileInEntries(ctx, ctx.Repo.TreePath, entries, true) if err != nil { ctx.ServerError("findReadmeFileInEntries", err) return @@ -196,56 +195,6 @@ func prepareUpstreamDivergingInfo(ctx *context.Context) { ctx.Data["UpstreamDivergingInfo"] = upstreamDivergingInfo } -func prepareRecentlyPushedNewBranches(ctx *context.Context) { - if ctx.Doer != nil { - if err := ctx.Repo.Repository.GetBaseRepo(ctx); err != nil { - ctx.ServerError("GetBaseRepo", err) - return - } - - opts := &git_model.FindRecentlyPushedNewBranchesOptions{ - Repo: ctx.Repo.Repository, - BaseRepo: ctx.Repo.Repository, - } - if ctx.Repo.Repository.IsFork { - opts.BaseRepo = ctx.Repo.Repository.BaseRepo - } - - baseRepoPerm, err := access_model.GetUserRepoPermission(ctx, opts.BaseRepo, ctx.Doer) - if err != nil { - ctx.ServerError("GetUserRepoPermission", err) - return - } - - if !opts.Repo.IsMirror && !opts.BaseRepo.IsMirror && - opts.BaseRepo.UnitEnabled(ctx, unit_model.TypePullRequests) && - baseRepoPerm.CanRead(unit_model.TypePullRequests) { - var finalBranches []*git_model.RecentlyPushedNewBranch - branches, err := git_model.FindRecentlyPushedNewBranches(ctx, ctx.Doer, opts) - if err != nil { - log.Error("FindRecentlyPushedNewBranches failed: %v", err) - } - - for _, branch := range branches { - divergingInfo, err := repo_service.GetBranchDivergingInfo(ctx, - branch.BranchRepo, branch.BranchName, // "base" repo for diverging info - opts.BaseRepo, opts.BaseRepo.DefaultBranch, // "head" repo for diverging info - ) - if err != nil { - log.Error("GetBranchDivergingInfo failed: %v", err) - continue - } - branchRepoHasNewCommits := divergingInfo.BaseHasNewCommits - baseRepoCommitsBehind := divergingInfo.HeadCommitsBehind - if branchRepoHasNewCommits || baseRepoCommitsBehind > 0 { - finalBranches = append(finalBranches, branch) - } - } - ctx.Data["RecentlyPushedNewBranches"] = finalBranches - } - } -} - func updateContextRepoEmptyAndStatus(ctx *context.Context, empty bool, status repo_model.RepositoryStatus) { if ctx.Repo.Repository.IsEmpty == empty && ctx.Repo.Repository.Status == status { return @@ -309,37 +258,44 @@ func handleRepoEmptyOrBroken(ctx *context.Context) { ctx.Redirect(link) } -func handleRepoViewSubmodule(ctx *context.Context, submodule *git.SubModule) { - submoduleRepoURL, err := giturl.ParseRepositoryURL(ctx, submodule.URL) - if err != nil { - HandleGitError(ctx, "prepareToRenderDirOrFile: ParseRepositoryURL", err) +func isViewHomeOnlyContent(ctx *context.Context) bool { + return ctx.FormBool("only_content") +} + +func handleRepoViewSubmodule(ctx *context.Context, commitSubmoduleFile *git.CommitSubmoduleFile) { + submoduleWebLink := commitSubmoduleFile.SubmoduleWebLinkTree(ctx) + if submoduleWebLink == nil { + ctx.Data["NotFoundPrompt"] = ctx.Repo.TreePath + ctx.NotFound(nil) return } - submoduleURL := giturl.MakeRepositoryWebLink(submoduleRepoURL) - if httplib.IsCurrentGiteaSiteURL(ctx, submoduleURL) { - ctx.RedirectToCurrentSite(submoduleURL) - } else { + + redirectLink := submoduleWebLink.CommitWebLink + if isViewHomeOnlyContent(ctx) { + ctx.Resp.Header().Set("Content-Type", "text/html; charset=utf-8") + _, _ = ctx.Resp.Write([]byte(htmlutil.HTMLFormat(`<a href="%s">%s</a>`, redirectLink, redirectLink))) + } else if !httplib.IsCurrentGiteaSiteURL(ctx, redirectLink) { // don't auto-redirect to external URL, to avoid open redirect or phishing - ctx.Data["NotFoundPrompt"] = submoduleURL + ctx.Data["NotFoundPrompt"] = redirectLink ctx.NotFound(nil) + } else { + ctx.Redirect(submoduleWebLink.CommitWebLink) } } func prepareToRenderDirOrFile(entry *git.TreeEntry) func(ctx *context.Context) { return func(ctx *context.Context) { if entry.IsSubModule() { - submodule, err := ctx.Repo.Commit.GetSubModule(entry.Name()) + commitSubmoduleFile, err := git.GetCommitInfoSubmoduleFile(ctx.Repo.RepoLink, ctx.Repo.TreePath, ctx.Repo.Commit, entry.ID) if err != nil { - HandleGitError(ctx, "prepareToRenderDirOrFile: GetSubModule", err) + HandleGitError(ctx, "prepareToRenderDirOrFile: GetCommitInfoSubmoduleFile", err) return } - handleRepoViewSubmodule(ctx, submodule) - return - } - if entry.IsDir() { + handleRepoViewSubmodule(ctx, commitSubmoduleFile) + } else if entry.IsDir() { prepareToRenderDirectory(ctx) } else { - prepareToRenderFile(ctx, entry) + prepareFileView(ctx, entry) } } } @@ -377,8 +333,8 @@ func prepareHomeTreeSideBarSwitch(ctx *context.Context) { func redirectSrcToRaw(ctx *context.Context) bool { // GitHub redirects a tree path with "?raw=1" to the raw path - // It is useful to embed some raw contents into markdown files, - // then viewing the markdown in "src" path could embed the raw content correctly. + // It is useful to embed some raw contents into Markdown files, + // then viewing the Markdown in "src" path could embed the raw content correctly. if ctx.Repo.TreePath != "" && ctx.FormBool("raw") { ctx.Redirect(ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)) return true @@ -386,6 +342,20 @@ func redirectSrcToRaw(ctx *context.Context) bool { return false } +func redirectFollowSymlink(ctx *context.Context, treePathEntry *git.TreeEntry) bool { + if ctx.Repo.TreePath == "" || !ctx.FormBool("follow_symlink") { + return false + } + if treePathEntry.IsLink() { + if res, err := git.EntryFollowLinks(ctx.Repo.Commit, ctx.Repo.TreePath, treePathEntry); err == nil { + redirect := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(res.TargetFullPath) + "?" + ctx.Req.URL.RawQuery + ctx.Redirect(redirect) + return true + } // else: don't handle the links we cannot resolve, so ignore the error + } + return false +} + // Home render repository home page func Home(ctx *context.Context) { if handleRepoHomeFeed(ctx) { @@ -394,6 +364,7 @@ func Home(ctx *context.Context) { if redirectSrcToRaw(ctx) { return } + // Check whether the repo is viewable: not in migration, and the code unit should be enabled // Ideally the "feed" logic should be after this, but old code did so, so keep it as-is. checkHomeCodeViewable(ctx) @@ -424,6 +395,10 @@ func Home(ctx *context.Context) { return } + if redirectFollowSymlink(ctx, entry) { + return + } + // prepare the tree path var treeNames, paths []string branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() @@ -472,7 +447,7 @@ func Home(ctx *context.Context) { } } - if ctx.FormBool("only_content") { + if isViewHomeOnlyContent(ctx) { ctx.HTML(http.StatusOK, tplRepoViewContent) } else if len(treeNames) != 0 { ctx.HTML(http.StatusOK, tplRepoView) |