gitea/routers/web/home.go
Philip Peterson c5e78fc7ad Do not mutate incoming options to SearchRepositoryByName (#34553)
Similar to #34544, this PR changes the `opts` argument in
`SearchRepositoryByName()` to be passed by value instead of by pointer,
as its mutations do not escape the function scope and are not used
elsewhere. This simplifies reasoning about the function and avoids
unnecessary pointer usage.

This insight emerged during an initial attempt to refactor
`RenderUserSearch()`, which currently intermixes multiple concerns.

---------

Co-authored-by: Philip Peterson <philip-peterson@users.noreply.github.com>
2025-06-02 17:33:25 +00:00

118 lines
3.5 KiB
Go

// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package web
import (
"net/http"
"strconv"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/sitemap"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/routers/web/auth"
"code.gitea.io/gitea/routers/web/user"
"code.gitea.io/gitea/services/context"
)
const (
// tplHome home page template
tplHome templates.TplName = "home"
)
// Home render home page
func Home(ctx *context.Context) {
if ctx.IsSigned {
if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
ctx.HTML(http.StatusOK, auth.TplActivate)
} else if !ctx.Doer.IsActive || ctx.Doer.ProhibitLogin {
log.Info("Failed authentication attempt for %s from %s", ctx.Doer.Name, ctx.RemoteAddr())
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
} else if ctx.Doer.MustChangePassword {
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
} else {
user.Dashboard(ctx)
}
return
// Check non-logged users landing page.
} else if setting.LandingPageURL != setting.LandingPageHome {
ctx.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
return
}
// Check auto-login.
if ctx.GetSiteCookie(setting.CookieRememberName) != "" {
ctx.Redirect(setting.AppSubURL + "/user/login")
return
}
ctx.Data["PageIsHome"] = true
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.HTML(http.StatusOK, tplHome)
}
// HomeSitemap renders the main sitemap
func HomeSitemap(ctx *context.Context) {
m := sitemap.NewSitemapIndex()
if !setting.Service.Explore.DisableUsersPage {
_, cnt, err := user_model.SearchUsers(ctx, user_model.SearchUserOptions{
Type: user_model.UserTypeIndividual,
ListOptions: db.ListOptions{PageSize: 1},
IsActive: optional.Some(true),
Visible: []structs.VisibleType{structs.VisibleTypePublic},
})
if err != nil {
ctx.ServerError("SearchUsers", err)
return
}
count := int(cnt)
idx := 1
for i := 0; i < count; i += setting.UI.SitemapPagingNum {
m.Add(sitemap.URL{URL: setting.AppURL + "explore/users/sitemap-" + strconv.Itoa(idx) + ".xml"})
idx++
}
}
_, cnt, err := repo_model.SearchRepository(ctx, repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
PageSize: 1,
},
Actor: ctx.Doer,
AllPublic: true,
})
if err != nil {
ctx.ServerError("SearchRepository", err)
return
}
count := int(cnt)
idx := 1
for i := 0; i < count; i += setting.UI.SitemapPagingNum {
m.Add(sitemap.URL{URL: setting.AppURL + "explore/repos/sitemap-" + strconv.Itoa(idx) + ".xml"})
idx++
}
ctx.Resp.Header().Set("Content-Type", "text/xml")
if _, err := m.WriteTo(ctx.Resp); err != nil {
log.Error("Failed writing sitemap: %v", err)
}
}
// NotFound render 404 page
func NotFound(ctx *context.Context) {
ctx.Data["Title"] = "Page Not Found"
ctx.NotFound(nil)
}