From c8e5c79cfda7e4c36b1a98c1abd3cdb50bde9d77 Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 11 Mar 2021 13:40:54 +0000 Subject: [PATCH] Add ui.explore settings to control view of explore pages (2) (#14094) This is an alternative PR to #13687. Add `[ui.explore]` settings to allow restricting the explore pages to logged in users only and to disable the users explore page. The two proposed settings are: - `REQUIRE_SIGNIN_VIEW`: Only allows access to the explore pages if the user is signed in. Also restricts - `/api/v1/user/search` - `/api/v1/users/{username}` - `/api/v1/users/{username}/repos` - but does not restrict `/api/v1/users/{username}/heatmap` - `DISABLE_USERS_PAGE`: Disables the /explore/users page Fix #2908 Close #13687 Signed-off-by: Andrew Thornton Co-authored-by: 6543 <6543@obermui.de> --- .../doc/advanced/config-cheat-sheet.en-us.md | 6 ++++++ .../doc/advanced/config-cheat-sheet.zh-cn.md | 5 +++++ modules/setting/service.go | 11 +++++++++++ routers/api/v1/api.go | 14 +++++++++++--- routers/home.go | 7 +++++++ routers/routes/web.go | 3 ++- templates/explore/navbar.tmpl | 8 +++++--- 7 files changed, 47 insertions(+), 7 deletions(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 61831d083b..c19f9fc717 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -479,6 +479,12 @@ relation to port exhaustion. The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS. - `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted. +### Service - Expore (`service.explore`) + +- `REQUIRE_SIGNIN_VIEW`: **false**: Only allow signed in users to view the explore pages. +- `DISABLE_USERS_PAGE`: **false**: Disable the users explore page. + + ## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`) Define allowed algorithms and their minimum key length (use -1 to disable a type): diff --git a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md index 5bae3cb03a..cc12005d57 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/advanced/config-cheat-sheet.zh-cn.md @@ -135,6 +135,11 @@ menu: - `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: 允许通过反向认证做自动注册。 - `ENABLE_CAPTCHA`: 注册时使用图片验证码。 +### Service - Expore (`service.explore`) + +- `REQUIRE_SIGNIN_VIEW`: **false**: 仅允许已登录的用户查看探索页面。 +- `DISABLE_USERS_PAGE`: **false**: 不显示用户探索页面。 + ## Webhook (`webhook`) - `QUEUE_LENGTH`: 说明: Hook 任务队列长度。 diff --git a/modules/setting/service.go b/modules/setting/service.go index fc4326fde5..9696e98641 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -8,6 +8,7 @@ import ( "regexp" "time" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" ) @@ -59,6 +60,12 @@ var Service struct { EnableOpenIDSignUp bool OpenIDWhitelist []*regexp.Regexp OpenIDBlacklist []*regexp.Regexp + + // Explore page settings + Explore struct { + RequireSigninView bool `ini:"REQUIRE_SIGNIN_VIEW"` + DisableUsersPage bool `ini:"DISABLE_USERS_PAGE"` + } `ini:"service.explore"` } func newService() { @@ -108,6 +115,10 @@ func newService() { Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool() Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0) + if err := Cfg.Section("service.explore").MapTo(&Service.Explore); err != nil { + log.Fatal("Failed to map service.explore settings: %v", err) + } + sec = Cfg.Section("openid") Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock) Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index a8499e0ee8..57bcdf49f6 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -204,6 +204,14 @@ func reqToken() func(ctx *context.APIContext) { } } +func reqExploreSignIn() func(ctx *context.APIContext) { + return func(ctx *context.APIContext) { + if setting.Service.Explore.RequireSigninView && !ctx.IsSigned { + ctx.Error(http.StatusUnauthorized, "reqExploreSignIn", "you must be signed in to search for users") + } + } +} + func reqBasicAuth() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Context.IsBasicAuth { @@ -603,16 +611,16 @@ func Routes() *web.Route { // Users m.Group("/users", func() { - m.Get("/search", user.Search) + m.Get("/search", reqExploreSignIn(), user.Search) m.Group("/{username}", func() { - m.Get("", user.GetInfo) + m.Get("", reqExploreSignIn(), user.GetInfo) if setting.Service.EnableUserHeatmap { m.Get("/heatmap", user.GetUserHeatmapData) } - m.Get("/repos", user.ListUserRepos) + m.Get("/repos", reqExploreSignIn(), user.ListUserRepos) m.Group("/tokens", func() { m.Combo("").Get(user.ListAccessTokens). Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken) diff --git a/routers/home.go b/routers/home.go index 6505a4180d..9f54c7aa64 100644 --- a/routers/home.go +++ b/routers/home.go @@ -171,6 +171,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { // 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 @@ -247,6 +248,10 @@ func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplN // 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 @@ -263,6 +268,7 @@ func ExploreUsers(ctx *context.Context) { // 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 @@ -288,6 +294,7 @@ func ExploreCode(ctx *context.Context) { return } + ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["PageIsExplore"] = true diff --git a/routers/routes/web.go b/routers/routes/web.go index 22774b2cdc..08faa274a5 100644 --- a/routers/routes/web.go +++ b/routers/routes/web.go @@ -286,6 +286,7 @@ func goGet(ctx *context.Context) { func RegisterRoutes(m *web.Route) { reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true}) ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView}) + ignExploreSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView}) ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true}) reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true}) @@ -335,7 +336,7 @@ func RegisterRoutes(m *web.Route) { m.Get("/users", routers.ExploreUsers) m.Get("/organizations", routers.ExploreOrganizations) m.Get("/code", routers.ExploreCode) - }, ignSignIn) + }, ignExploreSignIn) m.Get("/issues", reqSignIn, user.Issues) m.Get("/pulls", reqSignIn, user.Pulls) m.Get("/milestones", reqSignIn, reqMilestonesDashboardPageEnabled, user.Milestones) diff --git a/templates/explore/navbar.tmpl b/templates/explore/navbar.tmpl index 93810dcf4a..5b1e6b5d06 100644 --- a/templates/explore/navbar.tmpl +++ b/templates/explore/navbar.tmpl @@ -2,9 +2,11 @@ {{svg "octicon-repo"}} {{.i18n.Tr "explore.repos"}} - - {{svg "octicon-person"}} {{.i18n.Tr "explore.users"}} - + {{if not .UsersIsDisabled}} + + {{svg "octicon-person"}} {{.i18n.Tr "explore.users"}} + + {{end}} {{svg "octicon-organization"}} {{.i18n.Tr "explore.organizations"}}