From a9c6c24832bfd75ea88e2baae8954a2715ae5222 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 9 May 2021 17:59:07 +0800 Subject: [PATCH 01/16] Refactor routers directory --- cmd/web.go | 9 +- models/models.go | 26 ++ routers/api/v1/repo/file.go | 2 +- routers/common/logger.go | 33 ++ routers/common/middleware.go | 76 ++++ routers/home.go | 413 ------------------ routers/init.go | 62 +-- routers/{ => install}/install.go | 38 +- .../{routes/install.go => install/routes.go} | 34 +- routers/{ => web}/admin/admin.go | 0 routers/{ => web}/admin/admin_test.go | 0 routers/{ => web}/admin/auths.go | 0 routers/{ => web}/admin/emails.go | 0 routers/{ => web}/admin/hooks.go | 0 routers/{ => web}/admin/main_test.go | 0 routers/{ => web}/admin/notice.go | 0 routers/{ => web}/admin/orgs.go | 4 +- routers/{ => web}/admin/repos.go | 4 +- routers/{ => web}/admin/users.go | 6 +- routers/{ => web}/admin/users_test.go | 0 routers/{routes => web}/base.go | 24 +- routers/{ => web}/dev/template.go | 0 routers/{ => web}/events/events.go | 2 +- routers/web/explore/code.go | 139 ++++++ routers/web/explore/org.go | 39 ++ routers/web/explore/repo.go | 131 ++++++ routers/web/explore/user.go | 107 +++++ routers/{routes => web}/goget.go | 2 +- routers/web/home.go | 65 +++ routers/{ => web}/metrics.go | 2 +- routers/{ => web}/org/home.go | 0 routers/{ => web}/org/members.go | 0 routers/{ => web}/org/org.go | 0 routers/{ => web}/org/org_labels.go | 0 routers/{ => web}/org/setting.go | 2 +- routers/{ => web}/org/teams.go | 0 routers/{ => web}/repo/activity.go | 0 routers/{ => web}/repo/attachment.go | 0 routers/{ => web}/repo/blame.go | 0 routers/{ => web}/repo/branch.go | 0 routers/{ => web}/repo/commit.go | 0 routers/{ => web}/repo/compare.go | 0 routers/{ => web}/repo/download.go | 0 routers/{ => web}/repo/editor.go | 0 routers/{ => web}/repo/editor_test.go | 0 routers/{ => web}/repo/http.go | 0 routers/{ => web}/repo/issue.go | 0 routers/{ => web}/repo/issue_dependency.go | 0 routers/{ => web}/repo/issue_label.go | 0 routers/{ => web}/repo/issue_label_test.go | 0 routers/{ => web}/repo/issue_lock.go | 0 routers/{ => web}/repo/issue_stopwatch.go | 0 routers/{ => web}/repo/issue_test.go | 0 routers/{ => web}/repo/issue_timetrack.go | 0 routers/{ => web}/repo/issue_watch.go | 0 routers/{ => web}/repo/lfs.go | 0 routers/{ => web}/repo/main_test.go | 0 routers/{ => web}/repo/middlewares.go | 0 routers/{ => web}/repo/migrate.go | 0 routers/{ => web}/repo/milestone.go | 0 routers/{ => web}/repo/projects.go | 0 routers/{ => web}/repo/projects_test.go | 0 routers/{ => web}/repo/pull.go | 0 routers/{ => web}/repo/pull_review.go | 0 routers/{ => web}/repo/release.go | 0 routers/{ => web}/repo/release_test.go | 0 routers/{ => web}/repo/repo.go | 0 routers/{ => web}/repo/search.go | 0 routers/{ => web}/repo/setting.go | 0 .../repo/setting_protected_branch.go | 0 routers/{ => web}/repo/settings_test.go | 0 routers/{ => web}/repo/topic.go | 0 routers/{ => web}/repo/view.go | 0 routers/{ => web}/repo/webhook.go | 0 routers/{ => web}/repo/wiki.go | 0 routers/{ => web}/repo/wiki_test.go | 0 routers/{ => web}/swagger_json.go | 2 +- routers/{ => web}/user/auth.go | 0 routers/{ => web}/user/auth_openid.go | 0 routers/{ => web}/user/avatar.go | 0 routers/{ => web}/user/home.go | 0 routers/{ => web}/user/home_test.go | 0 routers/{ => web}/user/main_test.go | 0 routers/{ => web}/user/notification.go | 0 routers/{ => web}/user/oauth.go | 0 routers/{ => web}/user/profile.go | 2 +- routers/{ => web}/user/setting/account.go | 0 .../{ => web}/user/setting/account_test.go | 0 routers/{ => web}/user/setting/adopt.go | 0 .../{ => web}/user/setting/applications.go | 0 routers/{ => web}/user/setting/keys.go | 0 routers/{ => web}/user/setting/main_test.go | 0 routers/{ => web}/user/setting/oauth2.go | 0 routers/{ => web}/user/setting/profile.go | 0 routers/{ => web}/user/setting/security.go | 0 .../{ => web}/user/setting/security_openid.go | 0 .../{ => web}/user/setting/security_twofa.go | 0 .../{ => web}/user/setting/security_u2f.go | 0 routers/{ => web}/user/task.go | 0 routers/{routes => web}/web.go | 37 +- 100 files changed, 721 insertions(+), 540 deletions(-) create mode 100644 routers/common/logger.go create mode 100644 routers/common/middleware.go delete mode 100644 routers/home.go rename routers/{ => install}/install.go (94%) rename routers/{routes/install.go => install/routes.go} (83%) rename routers/{ => web}/admin/admin.go (100%) rename routers/{ => web}/admin/admin_test.go (100%) rename routers/{ => web}/admin/auths.go (100%) rename routers/{ => web}/admin/emails.go (100%) rename routers/{ => web}/admin/hooks.go (100%) rename routers/{ => web}/admin/main_test.go (100%) rename routers/{ => web}/admin/notice.go (100%) rename routers/{ => web}/admin/orgs.go (90%) rename routers/{ => web}/admin/repos.go (97%) rename routers/{ => web}/admin/users.go (98%) rename routers/{ => web}/admin/users_test.go (100%) rename routers/{routes => web}/base.go (85%) rename routers/{ => web}/dev/template.go (100%) rename routers/{ => web}/events/events.go (98%) create mode 100644 routers/web/explore/code.go create mode 100644 routers/web/explore/org.go create mode 100644 routers/web/explore/repo.go create mode 100644 routers/web/explore/user.go rename routers/{routes => web}/goget.go (99%) create mode 100644 routers/web/home.go rename routers/{ => web}/metrics.go (98%) rename routers/{ => web}/org/home.go (100%) rename routers/{ => web}/org/members.go (100%) rename routers/{ => web}/org/org.go (100%) rename routers/{ => web}/org/org_labels.go (100%) rename routers/{ => web}/org/setting.go (99%) rename routers/{ => web}/org/teams.go (100%) rename routers/{ => web}/repo/activity.go (100%) rename routers/{ => web}/repo/attachment.go (100%) rename routers/{ => web}/repo/blame.go (100%) rename routers/{ => web}/repo/branch.go (100%) rename routers/{ => web}/repo/commit.go (100%) rename routers/{ => web}/repo/compare.go (100%) rename routers/{ => web}/repo/download.go (100%) rename routers/{ => web}/repo/editor.go (100%) rename routers/{ => web}/repo/editor_test.go (100%) rename routers/{ => web}/repo/http.go (100%) rename routers/{ => web}/repo/issue.go (100%) rename routers/{ => web}/repo/issue_dependency.go (100%) rename routers/{ => web}/repo/issue_label.go (100%) rename routers/{ => web}/repo/issue_label_test.go (100%) rename routers/{ => web}/repo/issue_lock.go (100%) rename routers/{ => web}/repo/issue_stopwatch.go (100%) rename routers/{ => web}/repo/issue_test.go (100%) rename routers/{ => web}/repo/issue_timetrack.go (100%) rename routers/{ => web}/repo/issue_watch.go (100%) rename routers/{ => web}/repo/lfs.go (100%) rename routers/{ => web}/repo/main_test.go (100%) rename routers/{ => web}/repo/middlewares.go (100%) rename routers/{ => web}/repo/migrate.go (100%) rename routers/{ => web}/repo/milestone.go (100%) rename routers/{ => web}/repo/projects.go (100%) rename routers/{ => web}/repo/projects_test.go (100%) rename routers/{ => web}/repo/pull.go (100%) rename routers/{ => web}/repo/pull_review.go (100%) rename routers/{ => web}/repo/release.go (100%) rename routers/{ => web}/repo/release_test.go (100%) rename routers/{ => web}/repo/repo.go (100%) rename routers/{ => web}/repo/search.go (100%) rename routers/{ => web}/repo/setting.go (100%) rename routers/{ => web}/repo/setting_protected_branch.go (100%) rename routers/{ => web}/repo/settings_test.go (100%) rename routers/{ => web}/repo/topic.go (100%) rename routers/{ => web}/repo/view.go (100%) rename routers/{ => web}/repo/webhook.go (100%) rename routers/{ => web}/repo/wiki.go (100%) rename routers/{ => web}/repo/wiki_test.go (100%) rename routers/{ => web}/swagger_json.go (97%) rename routers/{ => web}/user/auth.go (100%) rename routers/{ => web}/user/auth_openid.go (100%) rename routers/{ => web}/user/avatar.go (100%) rename routers/{ => web}/user/home.go (100%) rename routers/{ => web}/user/home_test.go (100%) rename routers/{ => web}/user/main_test.go (100%) rename routers/{ => web}/user/notification.go (100%) rename routers/{ => web}/user/oauth.go (100%) rename routers/{ => web}/user/profile.go (99%) rename routers/{ => web}/user/setting/account.go (100%) rename routers/{ => web}/user/setting/account_test.go (100%) rename routers/{ => web}/user/setting/adopt.go (100%) rename routers/{ => web}/user/setting/applications.go (100%) rename routers/{ => web}/user/setting/keys.go (100%) rename routers/{ => web}/user/setting/main_test.go (100%) rename routers/{ => web}/user/setting/oauth2.go (100%) rename routers/{ => web}/user/setting/profile.go (100%) rename routers/{ => web}/user/setting/security.go (100%) rename routers/{ => web}/user/setting/security_openid.go (100%) rename routers/{ => web}/user/setting/security_twofa.go (100%) rename routers/{ => web}/user/setting/security_u2f.go (100%) rename routers/{ => web}/user/task.go (100%) rename routers/{routes => web}/web.go (98%) diff --git a/cmd/web.go b/cmd/web.go index 9c7d493339f04..b90f8c5f8352d 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -17,7 +17,8 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers" - "code.gitea.io/gitea/routers/routes" + "code.gitea.io/gitea/routers/install" + "code.gitea.io/gitea/routers/web" context2 "github.com/gorilla/context" "github.com/urfave/cli" @@ -88,7 +89,7 @@ func runWeb(ctx *cli.Context) error { } // Perform pre-initialization - needsInstall := routers.PreInstallInit(graceful.GetManager().HammerContext()) + needsInstall := install.PreInstallInit(graceful.GetManager().HammerContext()) if needsInstall { // Flag for port number in case first time run conflict if ctx.IsSet("port") { @@ -101,7 +102,7 @@ func runWeb(ctx *cli.Context) error { return err } } - c := routes.InstallRoutes() + c := install.InstallRoutes() err := listen(c, false) select { case <-graceful.GetManager().IsShutdown(): @@ -134,7 +135,7 @@ func runWeb(ctx *cli.Context) error { } // Set up Chi routes - c := routes.NormalRoutes() + c := web.NormalRoutes() err := listen(c, true) <-graceful.GetManager().Done() log.Info("PID: %d Gitea Web Finished", os.Getpid()) diff --git a/models/models.go b/models/models.go index b0a9062566ee3..d5701e9a3269f 100644 --- a/models/models.go +++ b/models/models.go @@ -12,7 +12,10 @@ import ( "fmt" "reflect" "strings" + "time" + "code.gitea.io/gitea/models/migrations" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" // Needed for the MySQL driver @@ -229,6 +232,29 @@ func NewEngine(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err e return nil } +// InitDBEngine In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology +func InitDBEngine(ctx context.Context) (err error) { + log.Info("Beginning ORM engine initialization.") + for i := 0; i < setting.Database.DBConnectRetries; i++ { + select { + case <-ctx.Done(): + return fmt.Errorf("Aborted due to shutdown:\nin retry ORM engine initialization") + default: + } + log.Info("ORM engine initialization attempt #%d/%d...", i+1, setting.Database.DBConnectRetries) + if err = NewEngine(ctx, migrations.Migrate); err == nil { + break + } else if i == setting.Database.DBConnectRetries-1 { + return err + } + log.Error("ORM engine initialization attempt #%d/%d failed. Error: %v", i+1, setting.Database.DBConnectRetries, err) + log.Info("Backing off for %d seconds", int64(setting.Database.DBConnectBackoff/time.Second)) + time.Sleep(setting.Database.DBConnectBackoff) + } + HasEngine = true + return nil +} + // NamesToBean return a list of beans or an error func NamesToBean(names ...string) ([]interface{}, error) { beans := []interface{}{} diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 37e02874b4ffd..48249aacd703f 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -17,7 +17,7 @@ import ( "code.gitea.io/gitea/modules/repofiles" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" - "code.gitea.io/gitea/routers/repo" + "code.gitea.io/gitea/routers/web/repo" ) // GetRawFile get a file by path on a repository diff --git a/routers/common/logger.go b/routers/common/logger.go new file mode 100644 index 0000000000000..bc1149543c94e --- /dev/null +++ b/routers/common/logger.go @@ -0,0 +1,33 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package common + +import ( + "net/http" + "time" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" +) + +// LoggerHandler is a handler that will log the routing to the default gitea log +func LoggerHandler(level log.Level) func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + start := time.Now() + + _ = log.GetLogger("router").Log(0, level, "Started %s %s for %s", log.ColoredMethod(req.Method), req.URL.RequestURI(), req.RemoteAddr) + + next.ServeHTTP(w, req) + + var status int + if v, ok := w.(context.ResponseWriter); ok { + status = v.Status() + } + + _ = log.GetLogger("router").Log(0, level, "Completed %s %s %v %s in %v", log.ColoredMethod(req.Method), req.URL.RequestURI(), log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(start))) + }) + } +} diff --git a/routers/common/middleware.go b/routers/common/middleware.go new file mode 100644 index 0000000000000..1d96522dd9d19 --- /dev/null +++ b/routers/common/middleware.go @@ -0,0 +1,76 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package common + +import ( + "fmt" + "net/http" + "strings" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "github.com/chi-middleware/proxy" + "github.com/go-chi/chi/middleware" +) + +// Middlewares returns common middlewares +func Middlewares() []func(http.Handler) http.Handler { + var handlers = []func(http.Handler) http.Handler{ + func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + next.ServeHTTP(context.NewResponse(resp), req) + }) + }, + } + + if setting.ReverseProxyLimit > 0 { + opt := proxy.NewForwardedHeadersOptions(). + WithForwardLimit(setting.ReverseProxyLimit). + ClearTrustedProxies() + for _, n := range setting.ReverseProxyTrustedProxies { + if !strings.Contains(n, "/") { + opt.AddTrustedProxy(n) + } else { + opt.AddTrustedNetwork(n) + } + } + handlers = append(handlers, proxy.ForwardedHeaders(opt)) + } + + handlers = append(handlers, middleware.StripSlashes) + + if !setting.DisableRouterLog && setting.RouterLogLevel != log.NONE { + if log.GetLogger("router").GetLevel() <= setting.RouterLogLevel { + handlers = append(handlers, LoggerHandler(setting.RouterLogLevel)) + } + } + if setting.EnableAccessLog { + handlers = append(handlers, context.AccessLogger()) + } + + handlers = append(handlers, func(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + // Why we need this? The Recovery() will try to render a beautiful + // error page for user, but the process can still panic again, and other + // middleware like session also may panic then we have to recover twice + // and send a simple error page that should not panic any more. + defer func() { + if err := recover(); err != nil { + combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, string(log.Stack(2))) + log.Error("%v", combinedErr) + if setting.IsProd() { + http.Error(resp, http.StatusText(500), 500) + } else { + http.Error(resp, combinedErr, 500) + } + } + }() + next.ServeHTTP(resp, req) + }) + }) + return handlers +} diff --git a/routers/home.go b/routers/home.go deleted file mode 100644 index 7eaebc081fd4e..0000000000000 --- a/routers/home.go +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Copyright 2019 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package routers - -import ( - "bytes" - "net/http" - "strings" - - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" - code_indexer "code.gitea.io/gitea/modules/indexer/code" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/modules/web/middleware" - "code.gitea.io/gitea/routers/user" -) - -const ( - // tplHome home page template - tplHome base.TplName = "home" - // tplExploreRepos explore repositories page template - tplExploreRepos base.TplName = "explore/repos" - // tplExploreUsers explore users page template - tplExploreUsers base.TplName = "explore/users" - // tplExploreOrganizations explore organizations page template - tplExploreOrganizations base.TplName = "explore/organizations" - // tplExploreCode explore code page template - tplExploreCode base.TplName = "explore/code" -) - -// Home render home page -func Home(ctx *context.Context) { - if ctx.IsSigned { - if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { - ctx.Data["Title"] = ctx.Tr("auth.active_your_account") - ctx.HTML(http.StatusOK, user.TplActivate) - } else if !ctx.User.IsActive || ctx.User.ProhibitLogin { - log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr()) - ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") - ctx.HTML(http.StatusOK, "user/auth/prohibit_login") - } else if ctx.User.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. - uname := ctx.GetCookie(setting.CookieUserName) - if len(uname) != 0 { - ctx.Redirect(setting.AppSubURL + "/user/login") - return - } - - ctx.Data["PageIsHome"] = true - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - ctx.HTML(http.StatusOK, tplHome) -} - -// RepoSearchOptions when calling search repositories -type RepoSearchOptions struct { - OwnerID int64 - Private bool - Restricted bool - PageSize int - TplName base.TplName -} - -var ( - nullByte = []byte{0x00} -) - -func isKeywordValid(keyword string) bool { - return !bytes.Contains([]byte(keyword), nullByte) -} - -// RenderRepoSearch render repositories search page -func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { - page := ctx.QueryInt("page") - if page <= 0 { - page = 1 - } - - var ( - repos []*models.Repository - count int64 - err error - orderBy models.SearchOrderBy - ) - - ctx.Data["SortType"] = ctx.Query("sort") - switch ctx.Query("sort") { - case "newest": - orderBy = models.SearchOrderByNewest - case "oldest": - orderBy = models.SearchOrderByOldest - case "recentupdate": - orderBy = models.SearchOrderByRecentUpdated - case "leastupdate": - orderBy = models.SearchOrderByLeastUpdated - case "reversealphabetically": - orderBy = models.SearchOrderByAlphabeticallyReverse - case "alphabetically": - orderBy = models.SearchOrderByAlphabetically - case "reversesize": - orderBy = models.SearchOrderBySizeReverse - case "size": - orderBy = models.SearchOrderBySize - case "moststars": - orderBy = models.SearchOrderByStarsReverse - case "feweststars": - orderBy = models.SearchOrderByStars - case "mostforks": - orderBy = models.SearchOrderByForksReverse - case "fewestforks": - orderBy = models.SearchOrderByForks - default: - ctx.Data["SortType"] = "recentupdate" - orderBy = models.SearchOrderByRecentUpdated - } - - keyword := strings.Trim(ctx.Query("q"), " ") - topicOnly := ctx.QueryBool("topic") - ctx.Data["TopicOnly"] = topicOnly - - repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ - ListOptions: models.ListOptions{ - Page: page, - PageSize: opts.PageSize, - }, - Actor: ctx.User, - OrderBy: orderBy, - Private: opts.Private, - Keyword: keyword, - OwnerID: opts.OwnerID, - AllPublic: true, - AllLimited: true, - TopicOnly: topicOnly, - IncludeDescription: setting.UI.SearchRepoDescription, - }) - if err != nil { - ctx.ServerError("SearchRepository", err) - return - } - ctx.Data["Keyword"] = keyword - ctx.Data["Total"] = count - ctx.Data["Repos"] = repos - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - - pager := context.NewPagination(int(count), opts.PageSize, page, 5) - pager.SetDefaultParams(ctx) - pager.AddParam(ctx, "topic", "TopicOnly") - ctx.Data["Page"] = pager - - ctx.HTML(http.StatusOK, opts.TplName) -} - -// ExploreRepos render explore repositories page -func ExploreRepos(ctx *context.Context) { - ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage - ctx.Data["Title"] = ctx.Tr("explore") - ctx.Data["PageIsExplore"] = true - ctx.Data["PageIsExploreRepositories"] = true - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - - var ownerID int64 - if ctx.User != nil && !ctx.User.IsAdmin { - ownerID = ctx.User.ID - } - - RenderRepoSearch(ctx, &RepoSearchOptions{ - PageSize: setting.UI.ExplorePagingNum, - OwnerID: ownerID, - Private: ctx.User != nil, - TplName: tplExploreRepos, - }) -} - -// RenderUserSearch render user search page -func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplName base.TplName) { - opts.Page = ctx.QueryInt("page") - if opts.Page <= 1 { - opts.Page = 1 - } - - var ( - users []*models.User - count int64 - err error - orderBy models.SearchOrderBy - ) - - ctx.Data["SortType"] = ctx.Query("sort") - switch ctx.Query("sort") { - case "newest": - orderBy = models.SearchOrderByIDReverse - case "oldest": - orderBy = models.SearchOrderByID - case "recentupdate": - orderBy = models.SearchOrderByRecentUpdated - case "leastupdate": - orderBy = models.SearchOrderByLeastUpdated - case "reversealphabetically": - orderBy = models.SearchOrderByAlphabeticallyReverse - case "alphabetically": - orderBy = models.SearchOrderByAlphabetically - default: - ctx.Data["SortType"] = "alphabetically" - orderBy = models.SearchOrderByAlphabetically - } - - opts.Keyword = strings.Trim(ctx.Query("q"), " ") - opts.OrderBy = orderBy - if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { - users, count, err = models.SearchUsers(opts) - if err != nil { - ctx.ServerError("SearchUsers", err) - return - } - } - ctx.Data["Keyword"] = opts.Keyword - ctx.Data["Total"] = count - ctx.Data["Users"] = users - ctx.Data["UsersTwoFaStatus"] = models.UserList(users).GetTwoFaStatus() - ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - - pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) - pager.SetDefaultParams(ctx) - ctx.Data["Page"] = pager - - ctx.HTML(http.StatusOK, tplName) -} - -// ExploreUsers render explore users page -func ExploreUsers(ctx *context.Context) { - if setting.Service.Explore.DisableUsersPage { - ctx.Redirect(setting.AppSubURL + "/explore/repos") - return - } - ctx.Data["Title"] = ctx.Tr("explore") - ctx.Data["PageIsExplore"] = true - ctx.Data["PageIsExploreUsers"] = true - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - - RenderUserSearch(ctx, &models.SearchUserOptions{ - Actor: ctx.User, - Type: models.UserTypeIndividual, - ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum}, - IsActive: util.OptionalBoolTrue, - Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate}, - }, tplExploreUsers) -} - -// ExploreOrganizations render explore organizations page -func ExploreOrganizations(ctx *context.Context) { - ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage - ctx.Data["Title"] = ctx.Tr("explore") - ctx.Data["PageIsExplore"] = true - ctx.Data["PageIsExploreOrganizations"] = true - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - - visibleTypes := []structs.VisibleType{structs.VisibleTypePublic} - if ctx.User != nil { - visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate) - } - - RenderUserSearch(ctx, &models.SearchUserOptions{ - Actor: ctx.User, - Type: models.UserTypeOrganization, - ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum}, - Visible: visibleTypes, - }, tplExploreOrganizations) -} - -// ExploreCode render explore code page -func ExploreCode(ctx *context.Context) { - if !setting.Indexer.RepoIndexerEnabled { - ctx.Redirect(setting.AppSubURL+"/explore", 302) - return - } - - ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - ctx.Data["Title"] = ctx.Tr("explore") - ctx.Data["PageIsExplore"] = true - ctx.Data["PageIsExploreCode"] = true - - language := strings.TrimSpace(ctx.Query("l")) - keyword := strings.TrimSpace(ctx.Query("q")) - page := ctx.QueryInt("page") - if page <= 0 { - page = 1 - } - - queryType := strings.TrimSpace(ctx.Query("t")) - isMatch := queryType == "match" - - var ( - repoIDs []int64 - err error - isAdmin bool - ) - if ctx.User != nil { - isAdmin = ctx.User.IsAdmin - } - - // guest user or non-admin user - if ctx.User == nil || !isAdmin { - repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.User) - if err != nil { - ctx.ServerError("SearchResults", err) - return - } - } - - var ( - total int - searchResults []*code_indexer.Result - searchResultLanguages []*code_indexer.SearchResultLanguages - ) - - // if non-admin login user, we need check UnitTypeCode at first - if ctx.User != nil && len(repoIDs) > 0 { - repoMaps, err := models.GetRepositoriesMapByIDs(repoIDs) - if err != nil { - ctx.ServerError("SearchResults", err) - return - } - - var rightRepoMap = make(map[int64]*models.Repository, len(repoMaps)) - repoIDs = make([]int64, 0, len(repoMaps)) - for id, repo := range repoMaps { - if repo.CheckUnitUser(ctx.User, models.UnitTypeCode) { - rightRepoMap[id] = repo - repoIDs = append(repoIDs, id) - } - } - - ctx.Data["RepoMaps"] = rightRepoMap - - total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) - if err != nil { - ctx.ServerError("SearchResults", err) - return - } - // if non-login user or isAdmin, no need to check UnitTypeCode - } else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin { - total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) - if err != nil { - ctx.ServerError("SearchResults", err) - return - } - - var loadRepoIDs = make([]int64, 0, len(searchResults)) - for _, result := range searchResults { - var find bool - for _, id := range loadRepoIDs { - if id == result.RepoID { - find = true - break - } - } - if !find { - loadRepoIDs = append(loadRepoIDs, result.RepoID) - } - } - - repoMaps, err := models.GetRepositoriesMapByIDs(loadRepoIDs) - if err != nil { - ctx.ServerError("SearchResults", err) - return - } - - ctx.Data["RepoMaps"] = repoMaps - } - - ctx.Data["Keyword"] = keyword - ctx.Data["Language"] = language - ctx.Data["queryType"] = queryType - ctx.Data["SearchResults"] = searchResults - ctx.Data["SearchResultLanguages"] = searchResultLanguages - ctx.Data["RequireHighlightJS"] = true - ctx.Data["PageIsViewCode"] = true - - pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) - pager.SetDefaultParams(ctx) - pager.AddParam(ctx, "l", "Language") - ctx.Data["Page"] = pager - - ctx.HTML(http.StatusOK, tplExploreCode) -} - -// NotFound render 404 page -func NotFound(ctx *context.Context) { - ctx.Data["Title"] = "Page Not Found" - ctx.NotFound("home.NotFound", nil) -} diff --git a/routers/init.go b/routers/init.go index 220d87a29da87..dadbddf6e0d0c 100644 --- a/routers/init.go +++ b/routers/init.go @@ -6,12 +6,9 @@ package routers import ( "context" - "fmt" "strings" - "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/models/migrations" "code.gitea.io/gitea/modules/auth/sso" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/cron" @@ -63,63 +60,6 @@ func NewServices() { notification.NewContext() } -// In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology -func initDBEngine(ctx context.Context) (err error) { - log.Info("Beginning ORM engine initialization.") - for i := 0; i < setting.Database.DBConnectRetries; i++ { - select { - case <-ctx.Done(): - return fmt.Errorf("Aborted due to shutdown:\nin retry ORM engine initialization") - default: - } - log.Info("ORM engine initialization attempt #%d/%d...", i+1, setting.Database.DBConnectRetries) - if err = models.NewEngine(ctx, migrations.Migrate); err == nil { - break - } else if i == setting.Database.DBConnectRetries-1 { - return err - } - log.Error("ORM engine initialization attempt #%d/%d failed. Error: %v", i+1, setting.Database.DBConnectRetries, err) - log.Info("Backing off for %d seconds", int64(setting.Database.DBConnectBackoff/time.Second)) - time.Sleep(setting.Database.DBConnectBackoff) - } - models.HasEngine = true - return nil -} - -// PreInstallInit preloads the configuration to check if we need to run install -func PreInstallInit(ctx context.Context) bool { - setting.NewContext() - if !setting.InstallLock { - log.Trace("AppPath: %s", setting.AppPath) - log.Trace("AppWorkPath: %s", setting.AppWorkPath) - log.Trace("Custom path: %s", setting.CustomPath) - log.Trace("Log path: %s", setting.LogRootPath) - log.Trace("Preparing to run install page") - translation.InitLocales() - if setting.EnableSQLite3 { - log.Info("SQLite3 Supported") - } - setting.InitDBConfig() - svg.Init() - } - - return !setting.InstallLock -} - -// PostInstallInit rereads the settings and starts up the database -func PostInstallInit(ctx context.Context) { - setting.NewContext() - setting.InitDBConfig() - if setting.InstallLock { - if err := initDBEngine(ctx); err == nil { - log.Info("ORM engine initialization successful!") - } else { - log.Fatal("ORM engine initialization failed: %v", err) - } - svg.Init() - } -} - // GlobalInit is for global configuration reload-able. func GlobalInit(ctx context.Context) { setting.NewContext() @@ -151,7 +91,7 @@ func GlobalInit(ctx context.Context) { } else if setting.Database.UseSQLite3 { log.Fatal("SQLite3 is set in settings but NOT Supported") } - if err := initDBEngine(ctx); err == nil { + if err := models.InitDBEngine(ctx); err == nil { log.Info("ORM engine initialization successful!") } else { log.Fatal("ORM engine initialization failed: %v", err) diff --git a/routers/install.go b/routers/install/install.go similarity index 94% rename from routers/install.go rename to routers/install/install.go index 6c460a887d81c..38495164bfc66 100644 --- a/routers/install.go +++ b/routers/install/install.go @@ -2,9 +2,10 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package routers +package install import ( + std_context "context" "fmt" "net/http" "os" @@ -20,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/svg" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/user" @@ -158,6 +160,40 @@ func Install(ctx *context.Context) { ctx.HTML(http.StatusOK, tplInstall) } +// PreInstallInit preloads the configuration to check if we need to run install +func PreInstallInit(ctx std_context.Context) bool { + setting.NewContext() + if !setting.InstallLock { + log.Trace("AppPath: %s", setting.AppPath) + log.Trace("AppWorkPath: %s", setting.AppWorkPath) + log.Trace("Custom path: %s", setting.CustomPath) + log.Trace("Log path: %s", setting.LogRootPath) + log.Trace("Preparing to run install page") + translation.InitLocales() + if setting.EnableSQLite3 { + log.Info("SQLite3 Supported") + } + setting.InitDBConfig() + svg.Init() + } + + return !setting.InstallLock +} + +// PostInstallInit rereads the settings and starts up the database +func PostInstallInit(ctx std_context.Context) { + setting.NewContext() + setting.InitDBConfig() + if setting.InstallLock { + if err := models.InitDBEngine(ctx); err == nil { + log.Info("ORM engine initialization successful!") + } else { + log.Fatal("ORM engine initialization failed: %v", err) + } + svg.Init() + } +} + // InstallPost response for submit install items func InstallPost(ctx *context.Context) { form := *web.GetForm(ctx).(*forms.InstallForm) diff --git a/routers/routes/install.go b/routers/install/routes.go similarity index 83% rename from routers/routes/install.go rename to routers/install/routes.go index 0918da1a4b8ab..0610f60ab2c23 100644 --- a/routers/routes/install.go +++ b/routers/install/routes.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package routes +package install import ( "fmt" @@ -15,12 +15,20 @@ import ( "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/middleware" - "code.gitea.io/gitea/routers" + "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/forms" "gitea.com/go-chi/session" ) +type dataStore struct { + Data map[string]interface{} +} + +func (d *dataStore) GetData() map[string]interface{} { + return d.Data +} + func installRecovery() func(next http.Handler) http.Handler { var rnd = templates.HTMLRenderer() return func(next http.Handler) http.Handler { @@ -77,7 +85,7 @@ func installRecovery() func(next http.Handler) http.Handler { // InstallRoutes registers the install routes func InstallRoutes() *web.Route { r := web.NewRoute() - for _, middle := range commonMiddlewares() { + for _, middle := range common.Middlewares() { r.Use(middle) } @@ -99,9 +107,23 @@ func InstallRoutes() *web.Route { })) r.Use(installRecovery()) - r.Use(routers.InstallInit) - r.Get("/", routers.Install) - r.Post("/", web.Bind(forms.InstallForm{}), routers.InstallPost) + + r.Use(public.Custom( + &public.Options{ + SkipLogging: setting.DisableRouterLog, + }, + )) + r.Use(public.Static( + &public.Options{ + Directory: path.Join(setting.StaticRootPath, "public"), + SkipLogging: setting.DisableRouterLog, + Prefix: "/assets", + }, + )) + + r.Use(InstallInit) + r.Get("/", Install) + r.Post("/", web.Bind(forms.InstallForm{}), InstallPost) r.NotFound(func(w http.ResponseWriter, req *http.Request) { http.Redirect(w, req, setting.AppURL, http.StatusFound) }) diff --git a/routers/admin/admin.go b/routers/web/admin/admin.go similarity index 100% rename from routers/admin/admin.go rename to routers/web/admin/admin.go diff --git a/routers/admin/admin_test.go b/routers/web/admin/admin_test.go similarity index 100% rename from routers/admin/admin_test.go rename to routers/web/admin/admin_test.go diff --git a/routers/admin/auths.go b/routers/web/admin/auths.go similarity index 100% rename from routers/admin/auths.go rename to routers/web/admin/auths.go diff --git a/routers/admin/emails.go b/routers/web/admin/emails.go similarity index 100% rename from routers/admin/emails.go rename to routers/web/admin/emails.go diff --git a/routers/admin/hooks.go b/routers/web/admin/hooks.go similarity index 100% rename from routers/admin/hooks.go rename to routers/web/admin/hooks.go diff --git a/routers/admin/main_test.go b/routers/web/admin/main_test.go similarity index 100% rename from routers/admin/main_test.go rename to routers/web/admin/main_test.go diff --git a/routers/admin/notice.go b/routers/web/admin/notice.go similarity index 100% rename from routers/admin/notice.go rename to routers/web/admin/notice.go diff --git a/routers/admin/orgs.go b/routers/web/admin/orgs.go similarity index 90% rename from routers/admin/orgs.go rename to routers/web/admin/orgs.go index 627f56eaecdfc..618f945704492 100644 --- a/routers/admin/orgs.go +++ b/routers/web/admin/orgs.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/routers" + "code.gitea.io/gitea/routers/web/explore" ) const ( @@ -24,7 +24,7 @@ func Organizations(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminOrganizations"] = true - routers.RenderUserSearch(ctx, &models.SearchUserOptions{ + explore.RenderUserSearch(ctx, &models.SearchUserOptions{ Type: models.UserTypeOrganization, ListOptions: models.ListOptions{ PageSize: setting.UI.Admin.OrgPagingNum, diff --git a/routers/admin/repos.go b/routers/web/admin/repos.go similarity index 97% rename from routers/admin/repos.go rename to routers/web/admin/repos.go index d23f7c3d5a613..6128992f5a336 100644 --- a/routers/admin/repos.go +++ b/routers/web/admin/repos.go @@ -17,7 +17,7 @@ import ( "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/routers" + "code.gitea.io/gitea/routers/web/explore" repo_service "code.gitea.io/gitea/services/repository" ) @@ -32,7 +32,7 @@ func Repos(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminRepositories"] = true - routers.RenderRepoSearch(ctx, &routers.RepoSearchOptions{ + explore.RenderRepoSearch(ctx, &explore.RepoSearchOptions{ Private: true, PageSize: setting.UI.Admin.RepoPagingNum, TplName: tplRepos, diff --git a/routers/admin/users.go b/routers/web/admin/users.go similarity index 98% rename from routers/admin/users.go rename to routers/web/admin/users.go index a71a11dd8a225..1b65795865fa7 100644 --- a/routers/admin/users.go +++ b/routers/web/admin/users.go @@ -18,8 +18,8 @@ import ( "code.gitea.io/gitea/modules/password" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" - "code.gitea.io/gitea/routers" - router_user_setting "code.gitea.io/gitea/routers/user/setting" + "code.gitea.io/gitea/routers/web/explore" + router_user_setting "code.gitea.io/gitea/routers/web/user/setting" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/mailer" ) @@ -36,7 +36,7 @@ func Users(ctx *context.Context) { ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminUsers"] = true - routers.RenderUserSearch(ctx, &models.SearchUserOptions{ + explore.RenderUserSearch(ctx, &models.SearchUserOptions{ Type: models.UserTypeIndividual, ListOptions: models.ListOptions{ PageSize: setting.UI.Admin.UserPagingNum, diff --git a/routers/admin/users_test.go b/routers/web/admin/users_test.go similarity index 100% rename from routers/admin/users_test.go rename to routers/web/admin/users_test.go diff --git a/routers/routes/base.go b/routers/web/base.go similarity index 85% rename from routers/routes/base.go rename to routers/web/base.go index 0b784508a7902..60639279edc71 100644 --- a/routers/routes/base.go +++ b/routers/web/base.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package routes +package web import ( "errors" @@ -13,11 +13,9 @@ import ( "path" "path/filepath" "strings" - "time" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth/sso" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -28,26 +26,6 @@ import ( "gitea.com/go-chi/session" ) -// LoggerHandler is a handler that will log the routing to the default gitea log -func LoggerHandler(level log.Level) func(next http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - start := time.Now() - - _ = log.GetLogger("router").Log(0, level, "Started %s %s for %s", log.ColoredMethod(req.Method), req.URL.RequestURI(), req.RemoteAddr) - - next.ServeHTTP(w, req) - - var status int - if v, ok := w.(context.ResponseWriter); ok { - status = v.Status() - } - - _ = log.GetLogger("router").Log(0, level, "Completed %s %s %v %s in %v", log.ColoredMethod(req.Method), req.URL.RequestURI(), log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(start))) - }) - } -} - func storageHandler(storageSetting setting.Storage, prefix string, objStore storage.ObjectStorage) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { if storageSetting.ServeDirect { diff --git a/routers/dev/template.go b/routers/web/dev/template.go similarity index 100% rename from routers/dev/template.go rename to routers/web/dev/template.go diff --git a/routers/events/events.go b/routers/web/events/events.go similarity index 98% rename from routers/events/events.go rename to routers/web/events/events.go index b140bf660cace..f9cc274851756 100644 --- a/routers/events/events.go +++ b/routers/web/events/events.go @@ -15,7 +15,7 @@ import ( "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/routers/user" + "code.gitea.io/gitea/routers/web/user" jsoniter "github.com/json-iterator/go" ) diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go new file mode 100644 index 0000000000000..845e2bf2a03d2 --- /dev/null +++ b/routers/web/explore/code.go @@ -0,0 +1,139 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package explore + +import ( + "net/http" + "strings" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + code_indexer "code.gitea.io/gitea/modules/indexer/code" + "code.gitea.io/gitea/modules/setting" +) + +const ( + // tplExploreCode explore code page template + tplExploreCode base.TplName = "explore/code" +) + +// ExploreCode render explore code page +func ExploreCode(ctx *context.Context) { + if !setting.Indexer.RepoIndexerEnabled { + ctx.Redirect(setting.AppSubURL+"/explore", 302) + return + } + + ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + ctx.Data["Title"] = ctx.Tr("explore") + ctx.Data["PageIsExplore"] = true + ctx.Data["PageIsExploreCode"] = true + + language := strings.TrimSpace(ctx.Query("l")) + keyword := strings.TrimSpace(ctx.Query("q")) + page := ctx.QueryInt("page") + if page <= 0 { + page = 1 + } + + queryType := strings.TrimSpace(ctx.Query("t")) + isMatch := queryType == "match" + + var ( + repoIDs []int64 + err error + isAdmin bool + ) + if ctx.User != nil { + isAdmin = ctx.User.IsAdmin + } + + // guest user or non-admin user + if ctx.User == nil || !isAdmin { + repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.User) + if err != nil { + ctx.ServerError("SearchResults", err) + return + } + } + + var ( + total int + searchResults []*code_indexer.Result + searchResultLanguages []*code_indexer.SearchResultLanguages + ) + + // if non-admin login user, we need check UnitTypeCode at first + if ctx.User != nil && len(repoIDs) > 0 { + repoMaps, err := models.GetRepositoriesMapByIDs(repoIDs) + if err != nil { + ctx.ServerError("SearchResults", err) + return + } + + var rightRepoMap = make(map[int64]*models.Repository, len(repoMaps)) + repoIDs = make([]int64, 0, len(repoMaps)) + for id, repo := range repoMaps { + if repo.CheckUnitUser(ctx.User, models.UnitTypeCode) { + rightRepoMap[id] = repo + repoIDs = append(repoIDs, id) + } + } + + ctx.Data["RepoMaps"] = rightRepoMap + + total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) + if err != nil { + ctx.ServerError("SearchResults", err) + return + } + // if non-login user or isAdmin, no need to check UnitTypeCode + } else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin { + total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) + if err != nil { + ctx.ServerError("SearchResults", err) + return + } + + var loadRepoIDs = make([]int64, 0, len(searchResults)) + for _, result := range searchResults { + var find bool + for _, id := range loadRepoIDs { + if id == result.RepoID { + find = true + break + } + } + if !find { + loadRepoIDs = append(loadRepoIDs, result.RepoID) + } + } + + repoMaps, err := models.GetRepositoriesMapByIDs(loadRepoIDs) + if err != nil { + ctx.ServerError("SearchResults", err) + return + } + + ctx.Data["RepoMaps"] = repoMaps + } + + ctx.Data["Keyword"] = keyword + ctx.Data["Language"] = language + ctx.Data["queryType"] = queryType + ctx.Data["SearchResults"] = searchResults + ctx.Data["SearchResultLanguages"] = searchResultLanguages + ctx.Data["RequireHighlightJS"] = true + ctx.Data["PageIsViewCode"] = true + + pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) + pager.SetDefaultParams(ctx) + pager.AddParam(ctx, "l", "Language") + ctx.Data["Page"] = pager + + ctx.HTML(http.StatusOK, tplExploreCode) +} diff --git a/routers/web/explore/org.go b/routers/web/explore/org.go new file mode 100644 index 0000000000000..25d6627c0d925 --- /dev/null +++ b/routers/web/explore/org.go @@ -0,0 +1,39 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package explore + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" +) + +const ( + // tplExploreOrganizations explore organizations page template + tplExploreOrganizations base.TplName = "explore/organizations" +) + +// ExploreOrganizations render explore organizations page +func ExploreOrganizations(ctx *context.Context) { + ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["Title"] = ctx.Tr("explore") + ctx.Data["PageIsExplore"] = true + ctx.Data["PageIsExploreOrganizations"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + + visibleTypes := []structs.VisibleType{structs.VisibleTypePublic} + if ctx.User != nil { + visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate) + } + + RenderUserSearch(ctx, &models.SearchUserOptions{ + Actor: ctx.User, + Type: models.UserTypeOrganization, + ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum}, + Visible: visibleTypes, + }, tplExploreOrganizations) +} diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go new file mode 100644 index 0000000000000..9f99ff6adf98a --- /dev/null +++ b/routers/web/explore/repo.go @@ -0,0 +1,131 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package explore + +import ( + "net/http" + "strings" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" +) + +const ( + // tplExploreRepos explore repositories page template + tplExploreRepos base.TplName = "explore/repos" +) + +// RepoSearchOptions when calling search repositories +type RepoSearchOptions struct { + OwnerID int64 + Private bool + Restricted bool + PageSize int + TplName base.TplName +} + +// RenderRepoSearch render repositories search page +func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { + page := ctx.QueryInt("page") + if page <= 0 { + page = 1 + } + + var ( + repos []*models.Repository + count int64 + err error + orderBy models.SearchOrderBy + ) + + ctx.Data["SortType"] = ctx.Query("sort") + switch ctx.Query("sort") { + case "newest": + orderBy = models.SearchOrderByNewest + case "oldest": + orderBy = models.SearchOrderByOldest + case "recentupdate": + orderBy = models.SearchOrderByRecentUpdated + case "leastupdate": + orderBy = models.SearchOrderByLeastUpdated + case "reversealphabetically": + orderBy = models.SearchOrderByAlphabeticallyReverse + case "alphabetically": + orderBy = models.SearchOrderByAlphabetically + case "reversesize": + orderBy = models.SearchOrderBySizeReverse + case "size": + orderBy = models.SearchOrderBySize + case "moststars": + orderBy = models.SearchOrderByStarsReverse + case "feweststars": + orderBy = models.SearchOrderByStars + case "mostforks": + orderBy = models.SearchOrderByForksReverse + case "fewestforks": + orderBy = models.SearchOrderByForks + default: + ctx.Data["SortType"] = "recentupdate" + orderBy = models.SearchOrderByRecentUpdated + } + + keyword := strings.Trim(ctx.Query("q"), " ") + topicOnly := ctx.QueryBool("topic") + ctx.Data["TopicOnly"] = topicOnly + + repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ + ListOptions: models.ListOptions{ + Page: page, + PageSize: opts.PageSize, + }, + Actor: ctx.User, + OrderBy: orderBy, + Private: opts.Private, + Keyword: keyword, + OwnerID: opts.OwnerID, + AllPublic: true, + AllLimited: true, + TopicOnly: topicOnly, + IncludeDescription: setting.UI.SearchRepoDescription, + }) + if err != nil { + ctx.ServerError("SearchRepository", err) + return + } + ctx.Data["Keyword"] = keyword + ctx.Data["Total"] = count + ctx.Data["Repos"] = repos + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + + pager := context.NewPagination(int(count), opts.PageSize, page, 5) + pager.SetDefaultParams(ctx) + pager.AddParam(ctx, "topic", "TopicOnly") + ctx.Data["Page"] = pager + + ctx.HTML(http.StatusOK, opts.TplName) +} + +// ExploreRepos render explore repositories page +func ExploreRepos(ctx *context.Context) { + ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage + ctx.Data["Title"] = ctx.Tr("explore") + ctx.Data["PageIsExplore"] = true + ctx.Data["PageIsExploreRepositories"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + + var ownerID int64 + if ctx.User != nil && !ctx.User.IsAdmin { + ownerID = ctx.User.ID + } + + RenderRepoSearch(ctx, &RepoSearchOptions{ + PageSize: setting.UI.ExplorePagingNum, + OwnerID: ownerID, + Private: ctx.User != nil, + TplName: tplExploreRepos, + }) +} diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go new file mode 100644 index 0000000000000..6741c080b448e --- /dev/null +++ b/routers/web/explore/user.go @@ -0,0 +1,107 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package explore + +import ( + "bytes" + "net/http" + "strings" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" +) + +const ( + // tplExploreUsers explore users page template + tplExploreUsers base.TplName = "explore/users" +) + +var ( + nullByte = []byte{0x00} +) + +func isKeywordValid(keyword string) bool { + return !bytes.Contains([]byte(keyword), nullByte) +} + +// RenderUserSearch render user search page +func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplName base.TplName) { + opts.Page = ctx.QueryInt("page") + if opts.Page <= 1 { + opts.Page = 1 + } + + var ( + users []*models.User + count int64 + err error + orderBy models.SearchOrderBy + ) + + ctx.Data["SortType"] = ctx.Query("sort") + switch ctx.Query("sort") { + case "newest": + orderBy = models.SearchOrderByIDReverse + case "oldest": + orderBy = models.SearchOrderByID + case "recentupdate": + orderBy = models.SearchOrderByRecentUpdated + case "leastupdate": + orderBy = models.SearchOrderByLeastUpdated + case "reversealphabetically": + orderBy = models.SearchOrderByAlphabeticallyReverse + case "alphabetically": + orderBy = models.SearchOrderByAlphabetically + default: + ctx.Data["SortType"] = "alphabetically" + orderBy = models.SearchOrderByAlphabetically + } + + opts.Keyword = strings.Trim(ctx.Query("q"), " ") + opts.OrderBy = orderBy + if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { + users, count, err = models.SearchUsers(opts) + if err != nil { + ctx.ServerError("SearchUsers", err) + return + } + } + ctx.Data["Keyword"] = opts.Keyword + ctx.Data["Total"] = count + ctx.Data["Users"] = users + ctx.Data["UsersTwoFaStatus"] = models.UserList(users).GetTwoFaStatus() + ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + + pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) + pager.SetDefaultParams(ctx) + ctx.Data["Page"] = pager + + ctx.HTML(http.StatusOK, tplName) +} + +// ExploreUsers render explore users page +func ExploreUsers(ctx *context.Context) { + if setting.Service.Explore.DisableUsersPage { + ctx.Redirect(setting.AppSubURL + "/explore/repos") + return + } + ctx.Data["Title"] = ctx.Tr("explore") + ctx.Data["PageIsExplore"] = true + ctx.Data["PageIsExploreUsers"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + + RenderUserSearch(ctx, &models.SearchUserOptions{ + Actor: ctx.User, + Type: models.UserTypeIndividual, + ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum}, + IsActive: util.OptionalBoolTrue, + Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate}, + }, tplExploreUsers) +} diff --git a/routers/routes/goget.go b/routers/web/goget.go similarity index 99% rename from routers/routes/goget.go rename to routers/web/goget.go index 518f5e3073402..77934e7f55efc 100644 --- a/routers/routes/goget.go +++ b/routers/web/goget.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package routes +package web import ( "net/http" diff --git a/routers/web/home.go b/routers/web/home.go new file mode 100644 index 0000000000000..f50197691ffdd --- /dev/null +++ b/routers/web/home.go @@ -0,0 +1,65 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package web + +import ( + "net/http" + + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/routers/web/user" +) + +const ( + // tplHome home page template + tplHome base.TplName = "home" +) + +// Home render home page +func Home(ctx *context.Context) { + if ctx.IsSigned { + if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { + ctx.Data["Title"] = ctx.Tr("auth.active_your_account") + ctx.HTML(http.StatusOK, user.TplActivate) + } else if !ctx.User.IsActive || ctx.User.ProhibitLogin { + log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr()) + ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") + ctx.HTML(http.StatusOK, "user/auth/prohibit_login") + } else if ctx.User.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. + uname := ctx.GetCookie(setting.CookieUserName) + if len(uname) != 0 { + ctx.Redirect(setting.AppSubURL + "/user/login") + return + } + + ctx.Data["PageIsHome"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + ctx.HTML(http.StatusOK, tplHome) +} + +// NotFound render 404 page +func NotFound(ctx *context.Context) { + ctx.Data["Title"] = "Page Not Found" + ctx.NotFound("home.NotFound", nil) +} diff --git a/routers/metrics.go b/routers/web/metrics.go similarity index 98% rename from routers/metrics.go rename to routers/web/metrics.go index db2fb8de44386..37558ee337646 100644 --- a/routers/metrics.go +++ b/routers/web/metrics.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package routers +package web import ( "crypto/subtle" diff --git a/routers/org/home.go b/routers/web/org/home.go similarity index 100% rename from routers/org/home.go rename to routers/web/org/home.go diff --git a/routers/org/members.go b/routers/web/org/members.go similarity index 100% rename from routers/org/members.go rename to routers/web/org/members.go diff --git a/routers/org/org.go b/routers/web/org/org.go similarity index 100% rename from routers/org/org.go rename to routers/web/org/org.go diff --git a/routers/org/org_labels.go b/routers/web/org/org_labels.go similarity index 100% rename from routers/org/org_labels.go rename to routers/web/org/org_labels.go diff --git a/routers/org/setting.go b/routers/web/org/setting.go similarity index 99% rename from routers/org/setting.go rename to routers/web/org/setting.go index 0e28a93acef95..aed90c66f7455 100644 --- a/routers/org/setting.go +++ b/routers/web/org/setting.go @@ -15,7 +15,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" - userSetting "code.gitea.io/gitea/routers/user/setting" + userSetting "code.gitea.io/gitea/routers/web/user/setting" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/org/teams.go b/routers/web/org/teams.go similarity index 100% rename from routers/org/teams.go rename to routers/web/org/teams.go diff --git a/routers/repo/activity.go b/routers/web/repo/activity.go similarity index 100% rename from routers/repo/activity.go rename to routers/web/repo/activity.go diff --git a/routers/repo/attachment.go b/routers/web/repo/attachment.go similarity index 100% rename from routers/repo/attachment.go rename to routers/web/repo/attachment.go diff --git a/routers/repo/blame.go b/routers/web/repo/blame.go similarity index 100% rename from routers/repo/blame.go rename to routers/web/repo/blame.go diff --git a/routers/repo/branch.go b/routers/web/repo/branch.go similarity index 100% rename from routers/repo/branch.go rename to routers/web/repo/branch.go diff --git a/routers/repo/commit.go b/routers/web/repo/commit.go similarity index 100% rename from routers/repo/commit.go rename to routers/web/repo/commit.go diff --git a/routers/repo/compare.go b/routers/web/repo/compare.go similarity index 100% rename from routers/repo/compare.go rename to routers/web/repo/compare.go diff --git a/routers/repo/download.go b/routers/web/repo/download.go similarity index 100% rename from routers/repo/download.go rename to routers/web/repo/download.go diff --git a/routers/repo/editor.go b/routers/web/repo/editor.go similarity index 100% rename from routers/repo/editor.go rename to routers/web/repo/editor.go diff --git a/routers/repo/editor_test.go b/routers/web/repo/editor_test.go similarity index 100% rename from routers/repo/editor_test.go rename to routers/web/repo/editor_test.go diff --git a/routers/repo/http.go b/routers/web/repo/http.go similarity index 100% rename from routers/repo/http.go rename to routers/web/repo/http.go diff --git a/routers/repo/issue.go b/routers/web/repo/issue.go similarity index 100% rename from routers/repo/issue.go rename to routers/web/repo/issue.go diff --git a/routers/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go similarity index 100% rename from routers/repo/issue_dependency.go rename to routers/web/repo/issue_dependency.go diff --git a/routers/repo/issue_label.go b/routers/web/repo/issue_label.go similarity index 100% rename from routers/repo/issue_label.go rename to routers/web/repo/issue_label.go diff --git a/routers/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go similarity index 100% rename from routers/repo/issue_label_test.go rename to routers/web/repo/issue_label_test.go diff --git a/routers/repo/issue_lock.go b/routers/web/repo/issue_lock.go similarity index 100% rename from routers/repo/issue_lock.go rename to routers/web/repo/issue_lock.go diff --git a/routers/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go similarity index 100% rename from routers/repo/issue_stopwatch.go rename to routers/web/repo/issue_stopwatch.go diff --git a/routers/repo/issue_test.go b/routers/web/repo/issue_test.go similarity index 100% rename from routers/repo/issue_test.go rename to routers/web/repo/issue_test.go diff --git a/routers/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go similarity index 100% rename from routers/repo/issue_timetrack.go rename to routers/web/repo/issue_timetrack.go diff --git a/routers/repo/issue_watch.go b/routers/web/repo/issue_watch.go similarity index 100% rename from routers/repo/issue_watch.go rename to routers/web/repo/issue_watch.go diff --git a/routers/repo/lfs.go b/routers/web/repo/lfs.go similarity index 100% rename from routers/repo/lfs.go rename to routers/web/repo/lfs.go diff --git a/routers/repo/main_test.go b/routers/web/repo/main_test.go similarity index 100% rename from routers/repo/main_test.go rename to routers/web/repo/main_test.go diff --git a/routers/repo/middlewares.go b/routers/web/repo/middlewares.go similarity index 100% rename from routers/repo/middlewares.go rename to routers/web/repo/middlewares.go diff --git a/routers/repo/migrate.go b/routers/web/repo/migrate.go similarity index 100% rename from routers/repo/migrate.go rename to routers/web/repo/migrate.go diff --git a/routers/repo/milestone.go b/routers/web/repo/milestone.go similarity index 100% rename from routers/repo/milestone.go rename to routers/web/repo/milestone.go diff --git a/routers/repo/projects.go b/routers/web/repo/projects.go similarity index 100% rename from routers/repo/projects.go rename to routers/web/repo/projects.go diff --git a/routers/repo/projects_test.go b/routers/web/repo/projects_test.go similarity index 100% rename from routers/repo/projects_test.go rename to routers/web/repo/projects_test.go diff --git a/routers/repo/pull.go b/routers/web/repo/pull.go similarity index 100% rename from routers/repo/pull.go rename to routers/web/repo/pull.go diff --git a/routers/repo/pull_review.go b/routers/web/repo/pull_review.go similarity index 100% rename from routers/repo/pull_review.go rename to routers/web/repo/pull_review.go diff --git a/routers/repo/release.go b/routers/web/repo/release.go similarity index 100% rename from routers/repo/release.go rename to routers/web/repo/release.go diff --git a/routers/repo/release_test.go b/routers/web/repo/release_test.go similarity index 100% rename from routers/repo/release_test.go rename to routers/web/repo/release_test.go diff --git a/routers/repo/repo.go b/routers/web/repo/repo.go similarity index 100% rename from routers/repo/repo.go rename to routers/web/repo/repo.go diff --git a/routers/repo/search.go b/routers/web/repo/search.go similarity index 100% rename from routers/repo/search.go rename to routers/web/repo/search.go diff --git a/routers/repo/setting.go b/routers/web/repo/setting.go similarity index 100% rename from routers/repo/setting.go rename to routers/web/repo/setting.go diff --git a/routers/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go similarity index 100% rename from routers/repo/setting_protected_branch.go rename to routers/web/repo/setting_protected_branch.go diff --git a/routers/repo/settings_test.go b/routers/web/repo/settings_test.go similarity index 100% rename from routers/repo/settings_test.go rename to routers/web/repo/settings_test.go diff --git a/routers/repo/topic.go b/routers/web/repo/topic.go similarity index 100% rename from routers/repo/topic.go rename to routers/web/repo/topic.go diff --git a/routers/repo/view.go b/routers/web/repo/view.go similarity index 100% rename from routers/repo/view.go rename to routers/web/repo/view.go diff --git a/routers/repo/webhook.go b/routers/web/repo/webhook.go similarity index 100% rename from routers/repo/webhook.go rename to routers/web/repo/webhook.go diff --git a/routers/repo/wiki.go b/routers/web/repo/wiki.go similarity index 100% rename from routers/repo/wiki.go rename to routers/web/repo/wiki.go diff --git a/routers/repo/wiki_test.go b/routers/web/repo/wiki_test.go similarity index 100% rename from routers/repo/wiki_test.go rename to routers/web/repo/wiki_test.go diff --git a/routers/swagger_json.go b/routers/web/swagger_json.go similarity index 97% rename from routers/swagger_json.go rename to routers/web/swagger_json.go index 78c7fb1e24b33..82d72698c606c 100644 --- a/routers/swagger_json.go +++ b/routers/web/swagger_json.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package routers +package web import ( "net/http" diff --git a/routers/user/auth.go b/routers/web/user/auth.go similarity index 100% rename from routers/user/auth.go rename to routers/web/user/auth.go diff --git a/routers/user/auth_openid.go b/routers/web/user/auth_openid.go similarity index 100% rename from routers/user/auth_openid.go rename to routers/web/user/auth_openid.go diff --git a/routers/user/avatar.go b/routers/web/user/avatar.go similarity index 100% rename from routers/user/avatar.go rename to routers/web/user/avatar.go diff --git a/routers/user/home.go b/routers/web/user/home.go similarity index 100% rename from routers/user/home.go rename to routers/web/user/home.go diff --git a/routers/user/home_test.go b/routers/web/user/home_test.go similarity index 100% rename from routers/user/home_test.go rename to routers/web/user/home_test.go diff --git a/routers/user/main_test.go b/routers/web/user/main_test.go similarity index 100% rename from routers/user/main_test.go rename to routers/web/user/main_test.go diff --git a/routers/user/notification.go b/routers/web/user/notification.go similarity index 100% rename from routers/user/notification.go rename to routers/web/user/notification.go diff --git a/routers/user/oauth.go b/routers/web/user/oauth.go similarity index 100% rename from routers/user/oauth.go rename to routers/web/user/oauth.go diff --git a/routers/user/profile.go b/routers/web/user/profile.go similarity index 99% rename from routers/user/profile.go rename to routers/web/user/profile.go index 8ff1ee24adc80..e66820e1317bc 100644 --- a/routers/user/profile.go +++ b/routers/web/user/profile.go @@ -17,7 +17,7 @@ import ( "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/routers/org" + "code.gitea.io/gitea/routers/web/org" ) // GetUserByName get user by name diff --git a/routers/user/setting/account.go b/routers/web/user/setting/account.go similarity index 100% rename from routers/user/setting/account.go rename to routers/web/user/setting/account.go diff --git a/routers/user/setting/account_test.go b/routers/web/user/setting/account_test.go similarity index 100% rename from routers/user/setting/account_test.go rename to routers/web/user/setting/account_test.go diff --git a/routers/user/setting/adopt.go b/routers/web/user/setting/adopt.go similarity index 100% rename from routers/user/setting/adopt.go rename to routers/web/user/setting/adopt.go diff --git a/routers/user/setting/applications.go b/routers/web/user/setting/applications.go similarity index 100% rename from routers/user/setting/applications.go rename to routers/web/user/setting/applications.go diff --git a/routers/user/setting/keys.go b/routers/web/user/setting/keys.go similarity index 100% rename from routers/user/setting/keys.go rename to routers/web/user/setting/keys.go diff --git a/routers/user/setting/main_test.go b/routers/web/user/setting/main_test.go similarity index 100% rename from routers/user/setting/main_test.go rename to routers/web/user/setting/main_test.go diff --git a/routers/user/setting/oauth2.go b/routers/web/user/setting/oauth2.go similarity index 100% rename from routers/user/setting/oauth2.go rename to routers/web/user/setting/oauth2.go diff --git a/routers/user/setting/profile.go b/routers/web/user/setting/profile.go similarity index 100% rename from routers/user/setting/profile.go rename to routers/web/user/setting/profile.go diff --git a/routers/user/setting/security.go b/routers/web/user/setting/security.go similarity index 100% rename from routers/user/setting/security.go rename to routers/web/user/setting/security.go diff --git a/routers/user/setting/security_openid.go b/routers/web/user/setting/security_openid.go similarity index 100% rename from routers/user/setting/security_openid.go rename to routers/web/user/setting/security_openid.go diff --git a/routers/user/setting/security_twofa.go b/routers/web/user/setting/security_twofa.go similarity index 100% rename from routers/user/setting/security_twofa.go rename to routers/web/user/setting/security_twofa.go diff --git a/routers/user/setting/security_u2f.go b/routers/web/user/setting/security_u2f.go similarity index 100% rename from routers/user/setting/security_u2f.go rename to routers/web/user/setting/security_u2f.go diff --git a/routers/user/task.go b/routers/web/user/task.go similarity index 100% rename from routers/user/task.go rename to routers/web/user/task.go diff --git a/routers/routes/web.go b/routers/web/web.go similarity index 98% rename from routers/routes/web.go rename to routers/web/web.go index fbc41d547d163..adfed8a6aa4e0 100644 --- a/routers/routes/web.go +++ b/routers/web/web.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package routes +package web import ( "encoding/gob" @@ -23,17 +23,18 @@ import ( "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" - "code.gitea.io/gitea/routers" - "code.gitea.io/gitea/routers/admin" apiv1 "code.gitea.io/gitea/routers/api/v1" "code.gitea.io/gitea/routers/api/v1/misc" - "code.gitea.io/gitea/routers/dev" - "code.gitea.io/gitea/routers/events" - "code.gitea.io/gitea/routers/org" + "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/routers/private" - "code.gitea.io/gitea/routers/repo" - "code.gitea.io/gitea/routers/user" - userSetting "code.gitea.io/gitea/routers/user/setting" + "code.gitea.io/gitea/routers/web/admin" + "code.gitea.io/gitea/routers/web/dev" + "code.gitea.io/gitea/routers/web/events" + "code.gitea.io/gitea/routers/web/explore" + "code.gitea.io/gitea/routers/web/org" + "code.gitea.io/gitea/routers/web/repo" + "code.gitea.io/gitea/routers/web/user" + userSetting "code.gitea.io/gitea/routers/web/user/setting" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/lfs" "code.gitea.io/gitea/services/mailer" @@ -118,7 +119,7 @@ var corsHandler func(http.Handler) http.Handler // NormalRoutes represents non install routes func NormalRoutes() *web.Route { r := web.NewRoute() - for _, middle := range commonMiddlewares() { + for _, middle := range common.Middlewares() { r.Use(middle) } @@ -216,7 +217,7 @@ func WebRoutes() *web.Route { c := metrics.NewCollector() prometheus.MustRegister(c) - routes.Get("/metrics", append(common, routers.Metrics)...) + routes.Get("/metrics", append(common, Metrics)...) } // Removed: toolbox.Toolboxer middleware will provide debug informations which seems unnecessary @@ -297,16 +298,16 @@ func RegisterRoutes(m *web.Route) { // Especially some AJAX requests, we can reduce middleware number to improve performance. // Routers. // for health check - m.Get("/", routers.Home) + m.Get("/", Home) m.Get("/.well-known/openid-configuration", user.OIDCWellKnown) m.Group("/explore", func() { m.Get("", func(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/explore/repos") }) - m.Get("/repos", routers.ExploreRepos) - m.Get("/users", routers.ExploreUsers) - m.Get("/organizations", routers.ExploreOrganizations) - m.Get("/code", routers.ExploreCode) + m.Get("/repos", explore.ExploreRepos) + m.Get("/users", explore.ExploreUsers) + m.Get("/organizations", explore.ExploreOrganizations) + m.Get("/code", explore.ExploreCode) }, ignExploreSignIn) m.Get("/issues", reqSignIn, user.Issues) m.Get("/pulls", reqSignIn, user.Pulls) @@ -1091,9 +1092,9 @@ func RegisterRoutes(m *web.Route) { }, reqSignIn) if setting.API.EnableSwagger { - m.Get("/swagger.v1.json", routers.SwaggerV1Json) + m.Get("/swagger.v1.json", SwaggerV1Json) } // Not found handler. - m.NotFound(web.Wrap(routers.NotFound)) + m.NotFound(web.Wrap(NotFound)) } From 37071d61378e373ed4e9bfa43ba93c0070f415d3 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 9 May 2021 20:34:30 +0800 Subject: [PATCH 02/16] Fix lint --- contrib/pr/checkout.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go index 9ee692fd35b1a..b7e1d18c274b2 100644 --- a/contrib/pr/checkout.go +++ b/contrib/pr/checkout.go @@ -31,7 +31,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers" - "code.gitea.io/gitea/routers/routes" + "code.gitea.io/gitea/routers/web" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" @@ -116,7 +116,7 @@ func runPR() { //routers.GlobalInit() external.RegisterRenderers() markup.Init() - c := routes.NormalRoutes() + c := web.NormalRoutes() log.Printf("[PR] Ready for testing !\n") log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n") From d1b48596c062351846c398a32929fcf59de4dc77 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 10 May 2021 13:27:39 +0800 Subject: [PATCH 03/16] Fix lint --- .golangci.yml | 4 +- cmd/web.go | 7 +-- contrib/pr/checkout.go | 3 +- integrations/create_no_session_test.go | 6 +- integrations/integration_test.go | 3 +- integrations/lfs_getobject_test.go | 8 +-- models/models.go | 26 --------- routers/common/db.go | 39 +++++++++++++ routers/init.go | 20 ++++++- routers/install/install.go | 77 +++++++++++++------------- routers/install/routes.go | 8 +-- routers/web/explore/code.go | 4 +- routers/web/explore/org.go | 4 +- routers/web/explore/repo.go | 4 +- routers/web/explore/user.go | 4 +- routers/web/web.go | 15 +++-- 16 files changed, 129 insertions(+), 103 deletions(-) create mode 100644 routers/common/db.go diff --git a/.golangci.yml b/.golangci.yml index 0d7f90e263c40..c3dd47ec29da6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -70,9 +70,6 @@ issues: - path: modules/log/ linters: - errcheck - - path: routers/routes/web.go - linters: - - dupl - path: routers/api/v1/repo/issue_subscription.go linters: - dupl @@ -114,3 +111,4 @@ issues: linters: - staticcheck text: "svc.IsAnInteractiveSession is deprecated: Use IsWindowsService instead." + diff --git a/cmd/web.go b/cmd/web.go index b90f8c5f8352d..bcb764080b3fb 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -18,7 +18,6 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers" "code.gitea.io/gitea/routers/install" - "code.gitea.io/gitea/routers/web" context2 "github.com/gorilla/context" "github.com/urfave/cli" @@ -89,7 +88,7 @@ func runWeb(ctx *cli.Context) error { } // Perform pre-initialization - needsInstall := install.PreInstallInit(graceful.GetManager().HammerContext()) + needsInstall := install.PreInit(graceful.GetManager().HammerContext()) if needsInstall { // Flag for port number in case first time run conflict if ctx.IsSet("port") { @@ -102,7 +101,7 @@ func runWeb(ctx *cli.Context) error { return err } } - c := install.InstallRoutes() + c := install.Routes() err := listen(c, false) select { case <-graceful.GetManager().IsShutdown(): @@ -135,7 +134,7 @@ func runWeb(ctx *cli.Context) error { } // Set up Chi routes - c := web.NormalRoutes() + c := routers.NormalRoutes() err := listen(c, true) <-graceful.GetManager().Done() log.Info("PID: %d Gitea Web Finished", os.Getpid()) diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go index b7e1d18c274b2..9ce84f762cecd 100644 --- a/contrib/pr/checkout.go +++ b/contrib/pr/checkout.go @@ -31,7 +31,6 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers" - "code.gitea.io/gitea/routers/web" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" @@ -116,7 +115,7 @@ func runPR() { //routers.GlobalInit() external.RegisterRenderers() markup.Init() - c := web.NormalRoutes() + c := routers.NormalRoutes() log.Printf("[PR] Ready for testing !\n") log.Printf("[PR] Login with user1, user2, user3, ... with pass: password\n") diff --git a/integrations/create_no_session_test.go b/integrations/create_no_session_test.go index c864b9c7ae125..46f111b6f7d84 100644 --- a/integrations/create_no_session_test.go +++ b/integrations/create_no_session_test.go @@ -14,7 +14,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/routers/routes" + "code.gitea.io/gitea/routers" "gitea.com/go-chi/session" jsoniter "github.com/json-iterator/go" @@ -58,7 +58,7 @@ func TestSessionFileCreation(t *testing.T) { oldSessionConfig := setting.SessionConfig.ProviderConfig defer func() { setting.SessionConfig.ProviderConfig = oldSessionConfig - c = routes.NormalRoutes() + c = routers.NormalRoutes() }() var config session.Options @@ -84,7 +84,7 @@ func TestSessionFileCreation(t *testing.T) { setting.SessionConfig.ProviderConfig = string(newConfigBytes) - c = routes.NormalRoutes() + c = routers.NormalRoutes() t.Run("NoSessionOnViewIssue", func(t *testing.T) { defer PrintCurrentTest(t)() diff --git a/integrations/integration_test.go b/integrations/integration_test.go index 74227416c4be5..d755977d1ab16 100644 --- a/integrations/integration_test.go +++ b/integrations/integration_test.go @@ -34,7 +34,6 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers" - "code.gitea.io/gitea/routers/routes" "github.com/PuerkitoBio/goquery" jsoniter "github.com/json-iterator/go" @@ -88,7 +87,7 @@ func TestMain(m *testing.M) { defer cancel() initIntegrationTest() - c = routes.NormalRoutes() + c = routers.NormalRoutes() // integration test settings... if setting.Cfg != nil { diff --git a/integrations/lfs_getobject_test.go b/integrations/lfs_getobject_test.go index b7423a2dbe55f..337a93567a49f 100644 --- a/integrations/lfs_getobject_test.go +++ b/integrations/lfs_getobject_test.go @@ -15,7 +15,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/routers/routes" + "code.gitea.io/gitea/routers/web" jsoniter "github.com/json-iterator/go" gzipp "github.com/klauspost/compress/gzip" @@ -99,7 +99,7 @@ func TestGetLFSLarge(t *testing.T) { t.Skip() return } - content := make([]byte, routes.GzipMinSize*10) + content := make([]byte, web.GzipMinSize*10) for i := range content { content[i] = byte(i % 256) } @@ -115,7 +115,7 @@ func TestGetLFSGzip(t *testing.T) { t.Skip() return } - b := make([]byte, routes.GzipMinSize*10) + b := make([]byte, web.GzipMinSize*10) for i := range b { b[i] = byte(i % 256) } @@ -136,7 +136,7 @@ func TestGetLFSZip(t *testing.T) { t.Skip() return } - b := make([]byte, routes.GzipMinSize*10) + b := make([]byte, web.GzipMinSize*10) for i := range b { b[i] = byte(i % 256) } diff --git a/models/models.go b/models/models.go index d5701e9a3269f..b0a9062566ee3 100644 --- a/models/models.go +++ b/models/models.go @@ -12,10 +12,7 @@ import ( "fmt" "reflect" "strings" - "time" - "code.gitea.io/gitea/models/migrations" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" // Needed for the MySQL driver @@ -232,29 +229,6 @@ func NewEngine(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err e return nil } -// InitDBEngine In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology -func InitDBEngine(ctx context.Context) (err error) { - log.Info("Beginning ORM engine initialization.") - for i := 0; i < setting.Database.DBConnectRetries; i++ { - select { - case <-ctx.Done(): - return fmt.Errorf("Aborted due to shutdown:\nin retry ORM engine initialization") - default: - } - log.Info("ORM engine initialization attempt #%d/%d...", i+1, setting.Database.DBConnectRetries) - if err = NewEngine(ctx, migrations.Migrate); err == nil { - break - } else if i == setting.Database.DBConnectRetries-1 { - return err - } - log.Error("ORM engine initialization attempt #%d/%d failed. Error: %v", i+1, setting.Database.DBConnectRetries, err) - log.Info("Backing off for %d seconds", int64(setting.Database.DBConnectBackoff/time.Second)) - time.Sleep(setting.Database.DBConnectBackoff) - } - HasEngine = true - return nil -} - // NamesToBean return a list of beans or an error func NamesToBean(names ...string) ([]interface{}, error) { beans := []interface{}{} diff --git a/routers/common/db.go b/routers/common/db.go new file mode 100644 index 0000000000000..069a46f64fe4d --- /dev/null +++ b/routers/common/db.go @@ -0,0 +1,39 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package common + +import ( + "context" + "fmt" + "time" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/migrations" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" +) + +// InitDBEngine In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology +func InitDBEngine(ctx context.Context) (err error) { + log.Info("Beginning ORM engine initialization.") + for i := 0; i < setting.Database.DBConnectRetries; i++ { + select { + case <-ctx.Done(): + return fmt.Errorf("Aborted due to shutdown:\nin retry ORM engine initialization") + default: + } + log.Info("ORM engine initialization attempt #%d/%d...", i+1, setting.Database.DBConnectRetries) + if err = models.NewEngine(ctx, migrations.Migrate); err == nil { + break + } else if i == setting.Database.DBConnectRetries-1 { + return err + } + log.Error("ORM engine initialization attempt #%d/%d failed. Error: %v", i+1, setting.Database.DBConnectRetries, err) + log.Info("Backing off for %d seconds", int64(setting.Database.DBConnectBackoff/time.Second)) + time.Sleep(setting.Database.DBConnectBackoff) + } + models.HasEngine = true + return nil +} diff --git a/routers/init.go b/routers/init.go index dadbddf6e0d0c..5e2eca439eb68 100644 --- a/routers/init.go +++ b/routers/init.go @@ -29,6 +29,11 @@ import ( "code.gitea.io/gitea/modules/svg" "code.gitea.io/gitea/modules/task" "code.gitea.io/gitea/modules/translation" + "code.gitea.io/gitea/modules/web" + apiv1 "code.gitea.io/gitea/routers/api/v1" + "code.gitea.io/gitea/routers/common" + "code.gitea.io/gitea/routers/private" + web_routers "code.gitea.io/gitea/routers/web" "code.gitea.io/gitea/services/mailer" mirror_service "code.gitea.io/gitea/services/mirror" pull_service "code.gitea.io/gitea/services/pull" @@ -91,7 +96,7 @@ func GlobalInit(ctx context.Context) { } else if setting.Database.UseSQLite3 { log.Fatal("SQLite3 is set in settings but NOT Supported") } - if err := models.InitDBEngine(ctx); err == nil { + if err := common.InitDBEngine(ctx); err == nil { log.Info("ORM engine initialization successful!") } else { log.Fatal("ORM engine initialization failed: %v", err) @@ -133,3 +138,16 @@ func GlobalInit(ctx context.Context) { svg.Init() } + +// NormalRoutes represents non install routes +func NormalRoutes() *web.Route { + r := web.NewRoute() + for _, middle := range common.Middlewares() { + r.Use(middle) + } + + r.Mount("/", web_routers.Routes()) + r.Mount("/api/v1", apiv1.Routes()) + r.Mount("/api/internal", private.Routes()) + return r +} diff --git a/routers/install/install.go b/routers/install/install.go index 38495164bfc66..5b14470e9253e 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -28,6 +28,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/forms" "gitea.com/go-chi/session" @@ -40,8 +41,8 @@ const ( tplPostInstall base.TplName = "post-install" ) -// InstallInit prepare for rendering installation page -func InstallInit(next http.Handler) http.Handler { +// Init prepare for rendering installation page +func Init(next http.Handler) http.Handler { var rnd = templates.HTMLRenderer() return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { @@ -85,6 +86,40 @@ func InstallInit(next http.Handler) http.Handler { }) } +// PreInit preloads the configuration to check if we need to run install +func PreInit(ctx std_context.Context) bool { + setting.NewContext() + if !setting.InstallLock { + log.Trace("AppPath: %s", setting.AppPath) + log.Trace("AppWorkPath: %s", setting.AppWorkPath) + log.Trace("Custom path: %s", setting.CustomPath) + log.Trace("Log path: %s", setting.LogRootPath) + log.Trace("Preparing to run install page") + translation.InitLocales() + if setting.EnableSQLite3 { + log.Info("SQLite3 Supported") + } + setting.InitDBConfig() + svg.Init() + } + + return !setting.InstallLock +} + +// PostInit rereads the settings and starts up the database +func PostInit(ctx std_context.Context) { + setting.NewContext() + setting.InitDBConfig() + if setting.InstallLock { + if err := common.InitDBEngine(ctx); err == nil { + log.Info("ORM engine initialization successful!") + } else { + log.Fatal("ORM engine initialization failed: %v", err) + } + svg.Init() + } +} + // Install render installation page func Install(ctx *context.Context) { form := forms.InstallForm{} @@ -160,42 +195,8 @@ func Install(ctx *context.Context) { ctx.HTML(http.StatusOK, tplInstall) } -// PreInstallInit preloads the configuration to check if we need to run install -func PreInstallInit(ctx std_context.Context) bool { - setting.NewContext() - if !setting.InstallLock { - log.Trace("AppPath: %s", setting.AppPath) - log.Trace("AppWorkPath: %s", setting.AppWorkPath) - log.Trace("Custom path: %s", setting.CustomPath) - log.Trace("Log path: %s", setting.LogRootPath) - log.Trace("Preparing to run install page") - translation.InitLocales() - if setting.EnableSQLite3 { - log.Info("SQLite3 Supported") - } - setting.InitDBConfig() - svg.Init() - } - - return !setting.InstallLock -} - -// PostInstallInit rereads the settings and starts up the database -func PostInstallInit(ctx std_context.Context) { - setting.NewContext() - setting.InitDBConfig() - if setting.InstallLock { - if err := models.InitDBEngine(ctx); err == nil { - log.Info("ORM engine initialization successful!") - } else { - log.Fatal("ORM engine initialization failed: %v", err) - } - svg.Init() - } -} - -// InstallPost response for submit install items -func InstallPost(ctx *context.Context) { +// SubmitInstall response for submit install items +func SubmitInstall(ctx *context.Context) { form := *web.GetForm(ctx).(*forms.InstallForm) var err error ctx.Data["CurDbOption"] = form.DbType diff --git a/routers/install/routes.go b/routers/install/routes.go index 0610f60ab2c23..61cb795d81ea1 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -82,8 +82,8 @@ func installRecovery() func(next http.Handler) http.Handler { } } -// InstallRoutes registers the install routes -func InstallRoutes() *web.Route { +// Routes registers the install routes +func Routes() *web.Route { r := web.NewRoute() for _, middle := range common.Middlewares() { r.Use(middle) @@ -121,9 +121,9 @@ func InstallRoutes() *web.Route { }, )) - r.Use(InstallInit) + r.Use(Init) r.Get("/", Install) - r.Post("/", web.Bind(forms.InstallForm{}), InstallPost) + r.Post("/", web.Bind(forms.InstallForm{}), SubmitInstall) r.NotFound(func(w http.ResponseWriter, req *http.Request) { http.Redirect(w, req, setting.AppURL, http.StatusFound) }) diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index 845e2bf2a03d2..0c4353a935f14 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -20,8 +20,8 @@ const ( tplExploreCode base.TplName = "explore/code" ) -// ExploreCode render explore code page -func ExploreCode(ctx *context.Context) { +// Codes render explore code page +func Codes(ctx *context.Context) { if !setting.Indexer.RepoIndexerEnabled { ctx.Redirect(setting.AppSubURL+"/explore", 302) return diff --git a/routers/web/explore/org.go b/routers/web/explore/org.go index 25d6627c0d925..470e0eb8530b1 100644 --- a/routers/web/explore/org.go +++ b/routers/web/explore/org.go @@ -17,8 +17,8 @@ const ( tplExploreOrganizations base.TplName = "explore/organizations" ) -// ExploreOrganizations render explore organizations page -func ExploreOrganizations(ctx *context.Context) { +// Organizations render explore organizations page +func Organizations(ctx *context.Context) { ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["PageIsExplore"] = true diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index 9f99ff6adf98a..e9efae5688d7d 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -109,8 +109,8 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { ctx.HTML(http.StatusOK, opts.TplName) } -// ExploreRepos render explore repositories page -func ExploreRepos(ctx *context.Context) { +// Repos render explore repositories page +func Repos(ctx *context.Context) { ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["PageIsExplore"] = true diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index 6741c080b448e..52f543fe6696a 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -86,8 +86,8 @@ func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplN ctx.HTML(http.StatusOK, tplName) } -// ExploreUsers render explore users page -func ExploreUsers(ctx *context.Context) { +// Users render explore users page +func Users(ctx *context.Context) { if setting.Service.Explore.DisableUsersPage { ctx.Redirect(setting.AppSubURL + "/explore/repos") return diff --git a/routers/web/web.go b/routers/web/web.go index adfed8a6aa4e0..fc38bb7625a91 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -137,15 +137,14 @@ func NormalRoutes() *web.Route { return next } } - - r.Mount("/", WebRoutes()) + r.Mount("/", Routes()) r.Mount("/api/v1", apiv1.Routes()) r.Mount("/api/internal", private.Routes()) return r } -// WebRoutes returns all web routes -func WebRoutes() *web.Route { +// Routes returns all web routes +func Routes() *web.Route { routes := web.NewRoute() routes.Use(public.AssetsHandler(&public.Options{ @@ -304,10 +303,10 @@ func RegisterRoutes(m *web.Route) { m.Get("", func(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/explore/repos") }) - m.Get("/repos", explore.ExploreRepos) - m.Get("/users", explore.ExploreUsers) - m.Get("/organizations", explore.ExploreOrganizations) - m.Get("/code", explore.ExploreCode) + m.Get("/repos", explore.Repos) + m.Get("/users", explore.Users) + m.Get("/organizations", explore.Organizations) + m.Get("/code", explore.Codes) }, ignExploreSignIn) m.Get("/issues", reqSignIn, user.Issues) m.Get("/pulls", reqSignIn, user.Pulls) From b3e627b1e0ecd701319117970fa5716301d42522 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 29 May 2021 17:56:28 +0800 Subject: [PATCH 04/16] Fix lint --- routers/web/base.go | 1 + 1 file changed, 1 insertion(+) diff --git a/routers/web/base.go b/routers/web/base.go index 60639279edc71..7d9d0c3b9c416 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth/sso" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" From b88b2f7240282b816f59b0f5416f032ed01314a5 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 30 May 2021 19:24:57 +0800 Subject: [PATCH 05/16] merge --- routers/install/routes.go | 14 --------- routers/web/web.go | 60 --------------------------------------- 2 files changed, 74 deletions(-) diff --git a/routers/install/routes.go b/routers/install/routes.go index 61cb795d81ea1..bab60247c0dce 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -107,20 +107,6 @@ func Routes() *web.Route { })) r.Use(installRecovery()) - - r.Use(public.Custom( - &public.Options{ - SkipLogging: setting.DisableRouterLog, - }, - )) - r.Use(public.Static( - &public.Options{ - Directory: path.Join(setting.StaticRootPath, "public"), - SkipLogging: setting.DisableRouterLog, - Prefix: "/assets", - }, - )) - r.Use(Init) r.Get("/", Install) r.Post("/", web.Bind(forms.InstallForm{}), SubmitInstall) diff --git a/routers/web/web.go b/routers/web/web.go index fc38bb7625a91..560c41e987db1 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -6,11 +6,9 @@ package web import ( "encoding/gob" - "fmt" "net/http" "os" "path" - "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" @@ -45,7 +43,6 @@ import ( "gitea.com/go-chi/captcha" "gitea.com/go-chi/session" "github.com/NYTimes/gziphandler" - "github.com/chi-middleware/proxy" "github.com/go-chi/chi/middleware" "github.com/go-chi/cors" "github.com/prometheus/client_golang/prometheus" @@ -57,63 +54,6 @@ const ( GzipMinSize = 1400 ) -func commonMiddlewares() []func(http.Handler) http.Handler { - var handlers = []func(http.Handler) http.Handler{ - func(next http.Handler) http.Handler { - return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - next.ServeHTTP(context.NewResponse(resp), req) - }) - }, - } - - if setting.ReverseProxyLimit > 0 { - opt := proxy.NewForwardedHeadersOptions(). - WithForwardLimit(setting.ReverseProxyLimit). - ClearTrustedProxies() - for _, n := range setting.ReverseProxyTrustedProxies { - if !strings.Contains(n, "/") { - opt.AddTrustedProxy(n) - } else { - opt.AddTrustedNetwork(n) - } - } - handlers = append(handlers, proxy.ForwardedHeaders(opt)) - } - - handlers = append(handlers, middleware.StripSlashes) - - if !setting.DisableRouterLog && setting.RouterLogLevel != log.NONE { - if log.GetLogger("router").GetLevel() <= setting.RouterLogLevel { - handlers = append(handlers, LoggerHandler(setting.RouterLogLevel)) - } - } - if setting.EnableAccessLog { - handlers = append(handlers, context.AccessLogger()) - } - - handlers = append(handlers, func(next http.Handler) http.Handler { - return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - // Why we need this? The Recovery() will try to render a beautiful - // error page for user, but the process can still panic again, and other - // middleware like session also may panic then we have to recover twice - // and send a simple error page that should not panic any more. - defer func() { - if err := recover(); err != nil { - combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, string(log.Stack(2))) - log.Error("%v", combinedErr) - if setting.IsProd() { - http.Error(resp, http.StatusText(500), 500) - } else { - http.Error(resp, combinedErr, 500) - } - } - }() - next.ServeHTTP(resp, req) - }) - }) - return handlers -} - var corsHandler func(http.Handler) http.Handler // NormalRoutes represents non install routes From 62a91aa00648f2052e5a49e9e1bfaa9c9df14e71 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 1 Jun 2021 23:19:23 +0800 Subject: [PATCH 06/16] Fix lint --- routers/install/install.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/install/install.go b/routers/install/install.go index 5b14470e9253e..ce0d4f5085fa6 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -446,7 +446,7 @@ func SubmitInstall(ctx *context.Context) { } // Re-read settings - PostInstallInit(ctx) + PostInit(ctx) // Create admin account if len(form.AdminName) > 0 { From 5f507c7035315a5fc0377af4971225f8abb50d1b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 5 Jun 2021 22:44:11 +0800 Subject: [PATCH 07/16] Fix test --- routers/web/admin/main_test.go | 2 +- routers/web/repo/main_test.go | 2 +- routers/web/user/main_test.go | 2 +- routers/web/user/setting/main_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/routers/web/admin/main_test.go b/routers/web/admin/main_test.go index 9a7191d471f54..352907c73717c 100644 --- a/routers/web/admin/main_test.go +++ b/routers/web/admin/main_test.go @@ -12,5 +12,5 @@ import ( ) func TestMain(m *testing.M) { - models.MainTest(m, filepath.Join("..", "..")) + models.MainTest(m, filepath.Join("..", "..", "..")) } diff --git a/routers/web/repo/main_test.go b/routers/web/repo/main_test.go index 04bbeeb211780..47f266365fd7f 100644 --- a/routers/web/repo/main_test.go +++ b/routers/web/repo/main_test.go @@ -12,5 +12,5 @@ import ( ) func TestMain(m *testing.M) { - models.MainTest(m, filepath.Join("..", "..")) + models.MainTest(m, filepath.Join("..", "..", "..")) } diff --git a/routers/web/user/main_test.go b/routers/web/user/main_test.go index ed0724dc7733e..be17dd1f3135f 100644 --- a/routers/web/user/main_test.go +++ b/routers/web/user/main_test.go @@ -12,5 +12,5 @@ import ( ) func TestMain(m *testing.M) { - models.MainTest(m, filepath.Join("..", "..")) + models.MainTest(m, filepath.Join("..", "..", "..")) } diff --git a/routers/web/user/setting/main_test.go b/routers/web/user/setting/main_test.go index d343c02f484ba..daa3f7fe5bf16 100644 --- a/routers/web/user/setting/main_test.go +++ b/routers/web/user/setting/main_test.go @@ -12,5 +12,5 @@ import ( ) func TestMain(m *testing.M) { - models.MainTest(m, filepath.Join("..", "..", "..")) + models.MainTest(m, filepath.Join("..", "..", "..", "..")) } From 3d60f16f23fe760c35053756d2e25eb805ae3fe3 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 6 Jun 2021 04:23:46 +0200 Subject: [PATCH 08/16] routers: move func used for web and api to common --- routers/api/v1/repo/file.go | 6 +- routers/common/repo.go | 127 +++++++++++++++++++++++++++++++++ routers/web/repo/attachment.go | 3 +- routers/web/repo/download.go | 100 ++------------------------ routers/web/repo/repo.go | 24 ------- routers/web/repo/wiki.go | 3 +- routers/web/web.go | 2 +- 7 files changed, 141 insertions(+), 124 deletions(-) create mode 100644 routers/common/repo.go diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 48249aacd703f..39a60df33f01b 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -17,7 +17,7 @@ import ( "code.gitea.io/gitea/modules/repofiles" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" - "code.gitea.io/gitea/routers/web/repo" + "code.gitea.io/gitea/routers/common" ) // GetRawFile get a file by path on a repository @@ -83,7 +83,7 @@ func GetRawFile(ctx *context.APIContext) { } return } - if err = repo.ServeBlob(ctx.Context, blob); err != nil { + if err = common.ServeBlob(ctx.Context, blob); err != nil { ctx.Error(http.StatusInternalServerError, "ServeBlob", err) } } @@ -126,7 +126,7 @@ func GetArchive(ctx *context.APIContext) { ctx.Repo.GitRepo = gitRepo defer gitRepo.Close() - repo.Download(ctx.Context) + common.Download(ctx.Context) } // GetEditorconfig get editor config of a repository diff --git a/routers/common/repo.go b/routers/common/repo.go new file mode 100644 index 0000000000000..c61b5ec57f525 --- /dev/null +++ b/routers/common/repo.go @@ -0,0 +1,127 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package common + +import ( + "fmt" + "io" + "net/http" + "path" + "path/filepath" + "strings" + + "code.gitea.io/gitea/modules/charset" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httpcache" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/typesniffer" + "code.gitea.io/gitea/services/archiver" +) + +// ServeBlob download a git.Blob +func ServeBlob(ctx *context.Context, blob *git.Blob) error { + if httpcache.HandleGenericETagCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`) { + return nil + } + + dataRc, err := blob.DataAsync() + if err != nil { + return err + } + defer func() { + if err = dataRc.Close(); err != nil { + log.Error("ServeBlob: Close: %v", err) + } + }() + + return ServeData(ctx, ctx.Repo.TreePath, blob.Size(), dataRc) +} + +// Download an archive of a repository +func Download(ctx *context.Context) { + uri := ctx.Params("*") + aReq := archiver.DeriveRequestFrom(ctx, uri) + + if aReq == nil { + ctx.Error(http.StatusNotFound) + return + } + + downloadName := ctx.Repo.Repository.Name + "-" + aReq.GetArchiveName() + complete := aReq.IsComplete() + if !complete { + aReq = archiver.ArchiveRepository(aReq) + complete = aReq.WaitForCompletion(ctx) + } + + if complete { + ctx.ServeFile(aReq.GetArchivePath(), downloadName) + } else { + ctx.Error(http.StatusNotFound) + } +} + +// ServeData download file from io.Reader +func ServeData(ctx *context.Context, name string, size int64, reader io.Reader) error { + buf := make([]byte, 1024) + n, err := reader.Read(buf) + if err != nil && err != io.EOF { + return err + } + if n >= 0 { + buf = buf[:n] + } + + ctx.Resp.Header().Set("Cache-Control", "public,max-age=86400") + + if size >= 0 { + ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", size)) + } else { + log.Error("ServeData called to serve data: %s with size < 0: %d", name, size) + } + name = path.Base(name) + + // Google Chrome dislike commas in filenames, so let's change it to a space + name = strings.ReplaceAll(name, ",", " ") + + st := typesniffer.DetectContentType(buf) + + if st.IsText() || ctx.QueryBool("render") { + cs, err := charset.DetectEncoding(buf) + if err != nil { + log.Error("Detect raw file %s charset failed: %v, using by default utf-8", name, err) + cs = "utf-8" + } + ctx.Resp.Header().Set("Content-Type", "text/plain; charset="+strings.ToLower(cs)) + } else { + ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") + + if (st.IsImage() || st.IsPDF()) && (setting.UI.SVG.Enabled || !st.IsSvgImage()) { + ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name)) + if st.IsSvgImage() { + ctx.Resp.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox") + ctx.Resp.Header().Set("X-Content-Type-Options", "nosniff") + ctx.Resp.Header().Set("Content-Type", typesniffer.SvgMimeType) + } + } else { + ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name)) + if setting.MimeTypeMap.Enabled { + fileExtension := strings.ToLower(filepath.Ext(name)) + if mimetype, ok := setting.MimeTypeMap.Map[fileExtension]; ok { + ctx.Resp.Header().Set("Content-Type", mimetype) + } + } + } + } + + _, err = ctx.Resp.Write(buf) + if err != nil { + return err + } + _, err = io.Copy(ctx.Resp, reader) + return err +} diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go index f53e7450ae028..5becbea2713a1 100644 --- a/routers/web/repo/attachment.go +++ b/routers/web/repo/attachment.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/upload" + "code.gitea.io/gitea/routers/common" ) // UploadIssueAttachment response for Issue/PR attachments @@ -152,7 +153,7 @@ func GetAttachment(ctx *context.Context) { } defer fr.Close() - if err = ServeData(ctx, attach.Name, attach.Size, fr); err != nil { + if err = common.ServeData(ctx, attach.Name, attach.Size, fr); err != nil { ctx.ServerError("ServeData", err) return } diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go index bbf4684b2ec7b..6f43d4b839198 100644 --- a/routers/web/repo/download.go +++ b/routers/web/repo/download.go @@ -6,102 +6,14 @@ package repo import ( - "fmt" - "io" - "path" - "path/filepath" - "strings" - - "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/typesniffer" + "code.gitea.io/gitea/routers/common" ) -// ServeData download file from io.Reader -func ServeData(ctx *context.Context, name string, size int64, reader io.Reader) error { - buf := make([]byte, 1024) - n, err := reader.Read(buf) - if err != nil && err != io.EOF { - return err - } - if n >= 0 { - buf = buf[:n] - } - - ctx.Resp.Header().Set("Cache-Control", "public,max-age=86400") - - if size >= 0 { - ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", size)) - } else { - log.Error("ServeData called to serve data: %s with size < 0: %d", name, size) - } - name = path.Base(name) - - // Google Chrome dislike commas in filenames, so let's change it to a space - name = strings.ReplaceAll(name, ",", " ") - - st := typesniffer.DetectContentType(buf) - - if st.IsText() || ctx.QueryBool("render") { - cs, err := charset.DetectEncoding(buf) - if err != nil { - log.Error("Detect raw file %s charset failed: %v, using by default utf-8", name, err) - cs = "utf-8" - } - ctx.Resp.Header().Set("Content-Type", "text/plain; charset="+strings.ToLower(cs)) - } else { - ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") - - if (st.IsImage() || st.IsPDF()) && (setting.UI.SVG.Enabled || !st.IsSvgImage()) { - ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name)) - if st.IsSvgImage() { - ctx.Resp.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox") - ctx.Resp.Header().Set("X-Content-Type-Options", "nosniff") - ctx.Resp.Header().Set("Content-Type", typesniffer.SvgMimeType) - } - } else { - ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name)) - if setting.MimeTypeMap.Enabled { - fileExtension := strings.ToLower(filepath.Ext(name)) - if mimetype, ok := setting.MimeTypeMap.Map[fileExtension]; ok { - ctx.Resp.Header().Set("Content-Type", mimetype) - } - } - } - } - - _, err = ctx.Resp.Write(buf) - if err != nil { - return err - } - _, err = io.Copy(ctx.Resp, reader) - return err -} - -// ServeBlob download a git.Blob -func ServeBlob(ctx *context.Context, blob *git.Blob) error { - if httpcache.HandleGenericETagCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`) { - return nil - } - - dataRc, err := blob.DataAsync() - if err != nil { - return err - } - defer func() { - if err = dataRc.Close(); err != nil { - log.Error("ServeBlob: Close: %v", err) - } - }() - - return ServeData(ctx, ctx.Repo.TreePath, blob.Size(), dataRc) -} - // ServeBlobOrLFS download a git.Blob redirecting to LFS if necessary func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob) error { if httpcache.HandleGenericETagCache(ctx.Req, ctx.Resp, `"`+blob.ID.String()+`"`) { @@ -130,7 +42,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob) error { log.Error("ServeBlobOrLFS: Close: %v", err) } closed = true - return ServeBlob(ctx, blob) + return common.ServeBlob(ctx, blob) } if httpcache.HandleGenericETagCache(ctx.Req, ctx.Resp, `"`+pointer.Oid+`"`) { return nil @@ -144,14 +56,14 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob) error { log.Error("ServeBlobOrLFS: Close: %v", err) } }() - return ServeData(ctx, ctx.Repo.TreePath, meta.Size, lfsDataRc) + return common.ServeData(ctx, ctx.Repo.TreePath, meta.Size, lfsDataRc) } if err = dataRc.Close(); err != nil { log.Error("ServeBlobOrLFS: Close: %v", err) } closed = true - return ServeBlob(ctx, blob) + return common.ServeBlob(ctx, blob) } // SingleDownload download a file by repos path @@ -165,7 +77,7 @@ func SingleDownload(ctx *context.Context) { } return } - if err = ServeBlob(ctx, blob); err != nil { + if err = common.ServeBlob(ctx, blob); err != nil { ctx.ServerError("ServeBlob", err) } } @@ -197,7 +109,7 @@ func DownloadByID(ctx *context.Context) { } return } - if err = ServeBlob(ctx, blob); err != nil { + if err = common.ServeBlob(ctx, blob); err != nil { ctx.ServerError("ServeBlob", err) } } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 69471a83d398b..f149e92a8b6b5 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -364,30 +364,6 @@ func RedirectDownload(ctx *context.Context) { ctx.Error(http.StatusNotFound) } -// Download an archive of a repository -func Download(ctx *context.Context) { - uri := ctx.Params("*") - aReq := archiver_service.DeriveRequestFrom(ctx, uri) - - if aReq == nil { - ctx.Error(http.StatusNotFound) - return - } - - downloadName := ctx.Repo.Repository.Name + "-" + aReq.GetArchiveName() - complete := aReq.IsComplete() - if !complete { - aReq = archiver_service.ArchiveRepository(aReq) - complete = aReq.WaitForCompletion(ctx) - } - - if complete { - ctx.ServeFile(aReq.GetArchivePath(), downloadName) - } else { - ctx.Error(http.StatusNotFound) - } -} - // InitiateDownload will enqueue an archival request, as needed. It may submit // a request that's already in-progress, but the archiver service will just // kind of drop it on the floor if this is the case. diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 1bdd06dce57d7..cceb8451e58f5 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -24,6 +24,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/forms" wiki_service "code.gitea.io/gitea/services/wiki" ) @@ -558,7 +559,7 @@ func WikiRaw(ctx *context.Context) { } if entry != nil { - if err = ServeBlob(ctx, entry.Blob()); err != nil { + if err = common.ServeBlob(ctx, entry.Blob()); err != nil { ctx.ServerError("ServeBlob", err) } return diff --git a/routers/web/web.go b/routers/web/web.go index 560c41e987db1..638131aa5179a 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -896,7 +896,7 @@ func RegisterRoutes(m *web.Route) { }, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(models.UnitTypeCode)) m.Group("/archive", func() { - m.Get("/*", repo.Download) + m.Get("/*", common.Download) m.Post("/*", repo.InitiateDownload) }, repo.MustBeNotEmpty, reqRepoCodeReader) From 2da6968733225618be12dd43f56377469b04d043 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 6 Jun 2021 04:43:47 +0200 Subject: [PATCH 09/16] make corsHandler a function to prohibit side efects --- routers/common/cors.go | 5 +++++ routers/web/web.go | 28 +++++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 routers/common/cors.go diff --git a/routers/common/cors.go b/routers/common/cors.go new file mode 100644 index 0000000000000..34dffc0d2b695 --- /dev/null +++ b/routers/common/cors.go @@ -0,0 +1,5 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package common diff --git a/routers/web/web.go b/routers/web/web.go index 638131aa5179a..55b846469bdc7 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -54,17 +54,10 @@ const ( GzipMinSize = 1400 ) -var corsHandler func(http.Handler) http.Handler - -// NormalRoutes represents non install routes -func NormalRoutes() *web.Route { - r := web.NewRoute() - for _, middle := range common.Middlewares() { - r.Use(middle) - } - +// CorsHandler return a http handler who set CORS options if enabled by config +func CorsHandler() func(next http.Handler) http.Handler { if setting.CORSConfig.Enabled { - corsHandler = cors.Handler(cors.Options{ + return cors.Handler(cors.Options{ //Scheme: setting.CORSConfig.Scheme, // FIXME: the cors middleware needs scheme option AllowedOrigins: setting.CORSConfig.AllowDomain, //setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option @@ -73,10 +66,19 @@ func NormalRoutes() *web.Route { MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), }) } else { - corsHandler = func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { return next } } +} + +// NormalRoutes represents non install routes +func NormalRoutes() *web.Route { + r := web.NewRoute() + for _, middle := range common.Middlewares() { + r.Use(middle) + } + r.Mount("/", Routes()) r.Mount("/api/v1", apiv1.Routes()) r.Mount("/api/internal", private.Routes()) @@ -90,7 +92,7 @@ func Routes() *web.Route { routes.Use(public.AssetsHandler(&public.Options{ Directory: path.Join(setting.StaticRootPath, "public"), Prefix: "/assets", - CorsHandler: corsHandler, + CorsHandler: CorsHandler(), })) routes.Use(session.Sessioner(session.Options{ @@ -303,7 +305,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/authorize", bindIgnErr(forms.AuthorizationForm{}), user.AuthorizeOAuth) }, ignSignInAndCsrf, reqSignIn) m.Get("/login/oauth/userinfo", ignSignInAndCsrf, user.InfoOAuth) - m.Post("/login/oauth/access_token", corsHandler, bindIgnErr(forms.AccessTokenForm{}), ignSignInAndCsrf, user.AccessTokenOAuth) + m.Post("/login/oauth/access_token", CorsHandler(), bindIgnErr(forms.AccessTokenForm{}), ignSignInAndCsrf, user.AccessTokenOAuth) m.Group("/user/settings", func() { m.Get("", userSetting.Profile) From ab3e40b9fa7d83cf613784c76c4de5866fbbbc85 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 6 Jun 2021 04:45:53 +0200 Subject: [PATCH 10/16] move CorsHandler to common --- routers/common/cors.go | 26 ++++++++++++++++++++++++++ routers/web/web.go | 23 ++--------------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/routers/common/cors.go b/routers/common/cors.go index 34dffc0d2b695..ee2b1188c49ca 100644 --- a/routers/common/cors.go +++ b/routers/common/cors.go @@ -3,3 +3,29 @@ // license that can be found in the LICENSE file. package common + +import ( + "net/http" + + "code.gitea.io/gitea/modules/setting" + + "github.com/go-chi/cors" +) + +// CorsHandler return a http handler who set CORS options if enabled by config +func CorsHandler() func(next http.Handler) http.Handler { + if setting.CORSConfig.Enabled { + return cors.Handler(cors.Options{ + //Scheme: setting.CORSConfig.Scheme, // FIXME: the cors middleware needs scheme option + AllowedOrigins: setting.CORSConfig.AllowDomain, + //setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option + AllowedMethods: setting.CORSConfig.Methods, + AllowCredentials: setting.CORSConfig.AllowCredentials, + MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), + }) + } else { + return func(next http.Handler) http.Handler { + return next + } + } +} diff --git a/routers/web/web.go b/routers/web/web.go index 55b846469bdc7..9f31a76dd6954 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -44,7 +44,6 @@ import ( "gitea.com/go-chi/session" "github.com/NYTimes/gziphandler" "github.com/go-chi/chi/middleware" - "github.com/go-chi/cors" "github.com/prometheus/client_golang/prometheus" "github.com/tstranex/u2f" ) @@ -54,24 +53,6 @@ const ( GzipMinSize = 1400 ) -// CorsHandler return a http handler who set CORS options if enabled by config -func CorsHandler() func(next http.Handler) http.Handler { - if setting.CORSConfig.Enabled { - return cors.Handler(cors.Options{ - //Scheme: setting.CORSConfig.Scheme, // FIXME: the cors middleware needs scheme option - AllowedOrigins: setting.CORSConfig.AllowDomain, - //setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option - AllowedMethods: setting.CORSConfig.Methods, - AllowCredentials: setting.CORSConfig.AllowCredentials, - MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), - }) - } else { - return func(next http.Handler) http.Handler { - return next - } - } -} - // NormalRoutes represents non install routes func NormalRoutes() *web.Route { r := web.NewRoute() @@ -92,7 +73,7 @@ func Routes() *web.Route { routes.Use(public.AssetsHandler(&public.Options{ Directory: path.Join(setting.StaticRootPath, "public"), Prefix: "/assets", - CorsHandler: CorsHandler(), + CorsHandler: common.CorsHandler(), })) routes.Use(session.Sessioner(session.Options{ @@ -305,7 +286,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/authorize", bindIgnErr(forms.AuthorizationForm{}), user.AuthorizeOAuth) }, ignSignInAndCsrf, reqSignIn) m.Get("/login/oauth/userinfo", ignSignInAndCsrf, user.InfoOAuth) - m.Post("/login/oauth/access_token", CorsHandler(), bindIgnErr(forms.AccessTokenForm{}), ignSignInAndCsrf, user.AccessTokenOAuth) + m.Post("/login/oauth/access_token", common.CorsHandler(), bindIgnErr(forms.AccessTokenForm{}), ignSignInAndCsrf, user.AccessTokenOAuth) m.Group("/user/settings", func() { m.Get("", userSetting.Profile) From 57f2698ce20b61be9e2ac563b7cd9ad9d233ba55 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 6 Jun 2021 04:51:16 +0200 Subject: [PATCH 11/16] rm unused func --- routers/web/web.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/routers/web/web.go b/routers/web/web.go index 9f31a76dd6954..d5e10508fede0 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -21,10 +21,8 @@ import ( "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" - apiv1 "code.gitea.io/gitea/routers/api/v1" "code.gitea.io/gitea/routers/api/v1/misc" "code.gitea.io/gitea/routers/common" - "code.gitea.io/gitea/routers/private" "code.gitea.io/gitea/routers/web/admin" "code.gitea.io/gitea/routers/web/dev" "code.gitea.io/gitea/routers/web/events" @@ -53,19 +51,6 @@ const ( GzipMinSize = 1400 ) -// NormalRoutes represents non install routes -func NormalRoutes() *web.Route { - r := web.NewRoute() - for _, middle := range common.Middlewares() { - r.Use(middle) - } - - r.Mount("/", Routes()) - r.Mount("/api/v1", apiv1.Routes()) - r.Mount("/api/internal", private.Routes()) - return r -} - // Routes returns all web routes func Routes() *web.Route { routes := web.NewRoute() From 71a255efba086d62951b08c0c663805ecda2c276 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 6 Jun 2021 05:03:14 +0200 Subject: [PATCH 12/16] make linter happy --- routers/common/cors.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/routers/common/cors.go b/routers/common/cors.go index ee2b1188c49ca..bfd7d49d75a90 100644 --- a/routers/common/cors.go +++ b/routers/common/cors.go @@ -23,9 +23,9 @@ func CorsHandler() func(next http.Handler) http.Handler { AllowCredentials: setting.CORSConfig.AllowCredentials, MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), }) - } else { - return func(next http.Handler) http.Handler { - return next - } + } + + return func(next http.Handler) http.Handler { + return next } } From f4c98a43593f24ff5d7d850112cd05059b733f16 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 6 Jun 2021 14:29:48 +0200 Subject: [PATCH 13/16] rm --- routers/web/web.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/routers/web/web.go b/routers/web/web.go index d5e10508fede0..bda2991fbc92b 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1001,7 +1001,4 @@ func RegisterRoutes(m *web.Route) { if setting.API.EnableSwagger { m.Get("/swagger.v1.json", SwaggerV1Json) } - - // Not found handler. - m.NotFound(web.Wrap(NotFound)) } From 140337a3e082c8ee367ba7a385d75c0b1f7f2a38 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 8 Jun 2021 05:17:02 +0200 Subject: [PATCH 14/16] Revert "move CorsHandler to common" This reverts commit 1bbc7aa6fe89df015e65d6794d2f1d6c5e8ca7ce. --- routers/common/cors.go | 31 ------------------------------- routers/web/web.go | 23 +++++++++++++++++++++-- 2 files changed, 21 insertions(+), 33 deletions(-) delete mode 100644 routers/common/cors.go diff --git a/routers/common/cors.go b/routers/common/cors.go deleted file mode 100644 index bfd7d49d75a90..0000000000000 --- a/routers/common/cors.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package common - -import ( - "net/http" - - "code.gitea.io/gitea/modules/setting" - - "github.com/go-chi/cors" -) - -// CorsHandler return a http handler who set CORS options if enabled by config -func CorsHandler() func(next http.Handler) http.Handler { - if setting.CORSConfig.Enabled { - return cors.Handler(cors.Options{ - //Scheme: setting.CORSConfig.Scheme, // FIXME: the cors middleware needs scheme option - AllowedOrigins: setting.CORSConfig.AllowDomain, - //setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option - AllowedMethods: setting.CORSConfig.Methods, - AllowCredentials: setting.CORSConfig.AllowCredentials, - MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), - }) - } - - return func(next http.Handler) http.Handler { - return next - } -} diff --git a/routers/web/web.go b/routers/web/web.go index bda2991fbc92b..8dbecc131f846 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -42,6 +42,7 @@ import ( "gitea.com/go-chi/session" "github.com/NYTimes/gziphandler" "github.com/go-chi/chi/middleware" + "github.com/go-chi/cors" "github.com/prometheus/client_golang/prometheus" "github.com/tstranex/u2f" ) @@ -51,6 +52,24 @@ const ( GzipMinSize = 1400 ) +// CorsHandler return a http handler who set CORS options if enabled by config +func CorsHandler() func(next http.Handler) http.Handler { + if setting.CORSConfig.Enabled { + return cors.Handler(cors.Options{ + //Scheme: setting.CORSConfig.Scheme, // FIXME: the cors middleware needs scheme option + AllowedOrigins: setting.CORSConfig.AllowDomain, + //setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option + AllowedMethods: setting.CORSConfig.Methods, + AllowCredentials: setting.CORSConfig.AllowCredentials, + MaxAge: int(setting.CORSConfig.MaxAge.Seconds()), + }) + } + + return func(next http.Handler) http.Handler { + return next + } +} + // Routes returns all web routes func Routes() *web.Route { routes := web.NewRoute() @@ -58,7 +77,7 @@ func Routes() *web.Route { routes.Use(public.AssetsHandler(&public.Options{ Directory: path.Join(setting.StaticRootPath, "public"), Prefix: "/assets", - CorsHandler: common.CorsHandler(), + CorsHandler: CorsHandler(), })) routes.Use(session.Sessioner(session.Options{ @@ -271,7 +290,7 @@ func RegisterRoutes(m *web.Route) { m.Post("/authorize", bindIgnErr(forms.AuthorizationForm{}), user.AuthorizeOAuth) }, ignSignInAndCsrf, reqSignIn) m.Get("/login/oauth/userinfo", ignSignInAndCsrf, user.InfoOAuth) - m.Post("/login/oauth/access_token", common.CorsHandler(), bindIgnErr(forms.AccessTokenForm{}), ignSignInAndCsrf, user.AccessTokenOAuth) + m.Post("/login/oauth/access_token", CorsHandler(), bindIgnErr(forms.AccessTokenForm{}), ignSignInAndCsrf, user.AccessTokenOAuth) m.Group("/user/settings", func() { m.Get("", userSetting.Profile) From 069fa9d9aebaa901fa2d30bceaee06ca183449c4 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Jun 2021 20:57:20 +0800 Subject: [PATCH 15/16] Follow @zeripath's review --- cmd/web.go | 2 +- routers/install/install.go | 40 ++---------------------------- routers/install/routes.go | 22 +++++++---------- routers/install/setting.go | 49 +++++++++++++++++++++++++++++++++++++ routers/web/base.go | 32 +++++++++++------------- routers/web/explore/code.go | 2 +- routers/web/web.go | 2 +- 7 files changed, 77 insertions(+), 72 deletions(-) create mode 100644 routers/install/setting.go diff --git a/cmd/web.go b/cmd/web.go index bcb764080b3fb..0ba14ae70642c 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -88,7 +88,7 @@ func runWeb(ctx *cli.Context) error { } // Perform pre-initialization - needsInstall := install.PreInit(graceful.GetManager().HammerContext()) + needsInstall := install.PreloadSettings(graceful.GetManager().HammerContext()) if needsInstall { // Flag for port number in case first time run conflict if ctx.IsSet("port") { diff --git a/routers/install/install.go b/routers/install/install.go index ce0d4f5085fa6..a7040bccad9f7 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -1,11 +1,11 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2021 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package install import ( - std_context "context" "fmt" "net/http" "os" @@ -21,14 +21,12 @@ import ( "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/svg" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/user" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/middleware" - "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/forms" "gitea.com/go-chi/session" @@ -86,40 +84,6 @@ func Init(next http.Handler) http.Handler { }) } -// PreInit preloads the configuration to check if we need to run install -func PreInit(ctx std_context.Context) bool { - setting.NewContext() - if !setting.InstallLock { - log.Trace("AppPath: %s", setting.AppPath) - log.Trace("AppWorkPath: %s", setting.AppWorkPath) - log.Trace("Custom path: %s", setting.CustomPath) - log.Trace("Log path: %s", setting.LogRootPath) - log.Trace("Preparing to run install page") - translation.InitLocales() - if setting.EnableSQLite3 { - log.Info("SQLite3 Supported") - } - setting.InitDBConfig() - svg.Init() - } - - return !setting.InstallLock -} - -// PostInit rereads the settings and starts up the database -func PostInit(ctx std_context.Context) { - setting.NewContext() - setting.InitDBConfig() - if setting.InstallLock { - if err := common.InitDBEngine(ctx); err == nil { - log.Info("ORM engine initialization successful!") - } else { - log.Fatal("ORM engine initialization failed: %v", err) - } - svg.Init() - } -} - // Install render installation page func Install(ctx *context.Context) { form := forms.InstallForm{} @@ -446,7 +410,7 @@ func SubmitInstall(ctx *context.Context) { } // Re-read settings - PostInit(ctx) + ReloadSettings(ctx) // Create admin account if len(form.AdminName) > 0 { diff --git a/routers/install/routes.go b/routers/install/routes.go index bab60247c0dce..36130d4b3f398 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -21,12 +21,10 @@ import ( "gitea.com/go-chi/session" ) -type dataStore struct { - Data map[string]interface{} -} +type dataStore map[string]interface{} func (d *dataStore) GetData() map[string]interface{} { - return d.Data + return *d } func installRecovery() func(next http.Handler) http.Handler { @@ -56,21 +54,19 @@ func installRecovery() func(next http.Handler) http.Handler { lc := middleware.Locale(w, req) var store = dataStore{ - Data: templates.Vars{ - "Language": lc.Language(), - "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), - "i18n": lc, - "SignedUserID": int64(0), - "SignedUserName": "", - }, + "Language": lc.Language(), + "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), + "i18n": lc, + "SignedUserID": int64(0), + "SignedUserName": "", } w.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) if !setting.IsProd() { - store.Data["ErrorMsg"] = combinedErr + store["ErrorMsg"] = combinedErr } - err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store.Data)) + err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store)) if err != nil { log.Error("%v", err) } diff --git a/routers/install/setting.go b/routers/install/setting.go new file mode 100644 index 0000000000000..50bb6aa355bfa --- /dev/null +++ b/routers/install/setting.go @@ -0,0 +1,49 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package install + +import ( + "context" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/svg" + "code.gitea.io/gitea/modules/translation" + "code.gitea.io/gitea/routers/common" +) + +// PreloadSettings preloads the configuration to check if we need to run install +func PreloadSettings(ctx context.Context) bool { + setting.NewContext() + if !setting.InstallLock { + log.Trace("AppPath: %s", setting.AppPath) + log.Trace("AppWorkPath: %s", setting.AppWorkPath) + log.Trace("Custom path: %s", setting.CustomPath) + log.Trace("Log path: %s", setting.LogRootPath) + log.Trace("Preparing to run install page") + translation.InitLocales() + if setting.EnableSQLite3 { + log.Info("SQLite3 Supported") + } + setting.InitDBConfig() + svg.Init() + } + + return !setting.InstallLock +} + +// ReloadSettings rereads the settings and starts up the database +func ReloadSettings(ctx context.Context) { + setting.NewContext() + setting.InitDBConfig() + if setting.InstallLock { + if err := common.InitDBEngine(ctx); err == nil { + log.Info("ORM engine initialization successful!") + } else { + log.Fatal("ORM engine initialization failed: %v", err) + } + svg.Init() + } +} diff --git a/routers/web/base.go b/routers/web/base.go index 7d9d0c3b9c416..8a44736434bdc 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -113,12 +113,10 @@ func storageHandler(storageSetting setting.Storage, prefix string, objStore stor } } -type dataStore struct { - Data map[string]interface{} -} +type dataStore map[string]interface{} func (d *dataStore) GetData() map[string]interface{} { - return d.Data + return *d } // Recovery returns a middleware that recovers from any panics and writes a 500 and a log if so. @@ -144,11 +142,9 @@ func Recovery() func(next http.Handler) http.Handler { var lc = middleware.Locale(w, req) var store = dataStore{ - Data: templates.Vars{ - "Language": lc.Language(), - "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), - "i18n": lc, - }, + "Language": lc.Language(), + "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), + "i18n": lc, } var user *models.User @@ -165,22 +161,22 @@ func Recovery() func(next http.Handler) http.Handler { user = sso.SessionUser(sessionStore) } if user != nil { - store.Data["IsSigned"] = true - store.Data["SignedUser"] = user - store.Data["SignedUserID"] = user.ID - store.Data["SignedUserName"] = user.Name - store.Data["IsAdmin"] = user.IsAdmin + store["IsSigned"] = true + store["SignedUser"] = user + store["SignedUserID"] = user.ID + store["SignedUserName"] = user.Name + store["IsAdmin"] = user.IsAdmin } else { - store.Data["SignedUserID"] = int64(0) - store.Data["SignedUserName"] = "" + store["SignedUserID"] = int64(0) + store["SignedUserName"] = "" } w.Header().Set(`X-Frame-Options`, `SAMEORIGIN`) if !setting.IsProd() { - store.Data["ErrorMsg"] = combinedErr + store["ErrorMsg"] = combinedErr } - err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store.Data)) + err = rnd.HTML(w, 500, "status/500", templates.BaseVars().Merge(store)) if err != nil { log.Error("%v", err) } diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index 0c4353a935f14..16509b35179fb 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -21,7 +21,7 @@ const ( ) // Codes render explore code page -func Codes(ctx *context.Context) { +func Code(ctx *context.Context) { if !setting.Indexer.RepoIndexerEnabled { ctx.Redirect(setting.AppSubURL+"/explore", 302) return diff --git a/routers/web/web.go b/routers/web/web.go index 8dbecc131f846..6c0141eef30a7 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -233,7 +233,7 @@ func RegisterRoutes(m *web.Route) { m.Get("/repos", explore.Repos) m.Get("/users", explore.Users) m.Get("/organizations", explore.Organizations) - m.Get("/code", explore.Codes) + m.Get("/code", explore.Code) }, ignExploreSignIn) m.Get("/issues", reqSignIn, user.Issues) m.Get("/pulls", reqSignIn, user.Pulls) From 37b84b827df59053a420a6d140a94bf314169735 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 8 Jun 2021 15:16:16 +0200 Subject: [PATCH 16/16] please linter --- routers/web/explore/code.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index 16509b35179fb..bf15b93cffd4c 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -20,7 +20,7 @@ const ( tplExploreCode base.TplName = "explore/code" ) -// Codes render explore code page +// Code render explore code page func Code(ctx *context.Context) { if !setting.Indexer.RepoIndexerEnabled { ctx.Redirect(setting.AppSubURL+"/explore", 302)