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 <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
tokarchuk/v1.17
zeripath 4 years ago committed by GitHub
parent bc423a1e84
commit c8e5c79cfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      docs/content/doc/advanced/config-cheat-sheet.en-us.md
  2. 5
      docs/content/doc/advanced/config-cheat-sheet.zh-cn.md
  3. 11
      modules/setting/service.go
  4. 14
      routers/api/v1/api.go
  5. 7
      routers/home.go
  6. 3
      routers/routes/web.go
  7. 2
      templates/explore/navbar.tmpl

@ -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. 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. - `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`) ## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`)
Define allowed algorithms and their minimum key length (use -1 to disable a type): Define allowed algorithms and their minimum key length (use -1 to disable a type):

@ -135,6 +135,11 @@ menu:
- `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: 允许通过反向认证做自动注册。 - `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: 允许通过反向认证做自动注册。
- `ENABLE_CAPTCHA`: 注册时使用图片验证码。 - `ENABLE_CAPTCHA`: 注册时使用图片验证码。
### Service - Expore (`service.explore`)
- `REQUIRE_SIGNIN_VIEW`: **false**: 仅允许已登录的用户查看探索页面。
- `DISABLE_USERS_PAGE`: **false**: 不显示用户探索页面。
## Webhook (`webhook`) ## Webhook (`webhook`)
- `QUEUE_LENGTH`: 说明: Hook 任务队列长度。 - `QUEUE_LENGTH`: 说明: Hook 任务队列长度。

@ -8,6 +8,7 @@ import (
"regexp" "regexp"
"time" "time"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
) )
@ -59,6 +60,12 @@ var Service struct {
EnableOpenIDSignUp bool EnableOpenIDSignUp bool
OpenIDWhitelist []*regexp.Regexp OpenIDWhitelist []*regexp.Regexp
OpenIDBlacklist []*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() { func newService() {
@ -108,6 +115,10 @@ func newService() {
Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool() Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool()
Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0) 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") sec = Cfg.Section("openid")
Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock) Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock)
Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn) Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn)

@ -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) { func reqBasicAuth() func(ctx *context.APIContext) {
return func(ctx *context.APIContext) { return func(ctx *context.APIContext) {
if !ctx.Context.IsBasicAuth { if !ctx.Context.IsBasicAuth {
@ -603,16 +611,16 @@ func Routes() *web.Route {
// Users // Users
m.Group("/users", func() { m.Group("/users", func() {
m.Get("/search", user.Search) m.Get("/search", reqExploreSignIn(), user.Search)
m.Group("/{username}", func() { m.Group("/{username}", func() {
m.Get("", user.GetInfo) m.Get("", reqExploreSignIn(), user.GetInfo)
if setting.Service.EnableUserHeatmap { if setting.Service.EnableUserHeatmap {
m.Get("/heatmap", user.GetUserHeatmapData) m.Get("/heatmap", user.GetUserHeatmapData)
} }
m.Get("/repos", user.ListUserRepos) m.Get("/repos", reqExploreSignIn(), user.ListUserRepos)
m.Group("/tokens", func() { m.Group("/tokens", func() {
m.Combo("").Get(user.ListAccessTokens). m.Combo("").Get(user.ListAccessTokens).
Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken) Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken)

@ -171,6 +171,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
// ExploreRepos render explore repositories page // ExploreRepos render explore repositories page
func ExploreRepos(ctx *context.Context) { func ExploreRepos(ctx *context.Context) {
ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true ctx.Data["PageIsExplore"] = true
ctx.Data["PageIsExploreRepositories"] = true ctx.Data["PageIsExploreRepositories"] = true
@ -247,6 +248,10 @@ func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplN
// ExploreUsers render explore users page // ExploreUsers render explore users page
func ExploreUsers(ctx *context.Context) { 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["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true ctx.Data["PageIsExplore"] = true
ctx.Data["PageIsExploreUsers"] = true ctx.Data["PageIsExploreUsers"] = true
@ -263,6 +268,7 @@ func ExploreUsers(ctx *context.Context) {
// ExploreOrganizations render explore organizations page // ExploreOrganizations render explore organizations page
func ExploreOrganizations(ctx *context.Context) { func ExploreOrganizations(ctx *context.Context) {
ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true ctx.Data["PageIsExplore"] = true
ctx.Data["PageIsExploreOrganizations"] = true ctx.Data["PageIsExploreOrganizations"] = true
@ -288,6 +294,7 @@ func ExploreCode(ctx *context.Context) {
return return
} }
ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["Title"] = ctx.Tr("explore") ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true ctx.Data["PageIsExplore"] = true

@ -286,6 +286,7 @@ func goGet(ctx *context.Context) {
func RegisterRoutes(m *web.Route) { func RegisterRoutes(m *web.Route) {
reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true}) reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView}) 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}) ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true})
reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true}) reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true})
@ -335,7 +336,7 @@ func RegisterRoutes(m *web.Route) {
m.Get("/users", routers.ExploreUsers) m.Get("/users", routers.ExploreUsers)
m.Get("/organizations", routers.ExploreOrganizations) m.Get("/organizations", routers.ExploreOrganizations)
m.Get("/code", routers.ExploreCode) m.Get("/code", routers.ExploreCode)
}, ignSignIn) }, ignExploreSignIn)
m.Get("/issues", reqSignIn, user.Issues) m.Get("/issues", reqSignIn, user.Issues)
m.Get("/pulls", reqSignIn, user.Pulls) m.Get("/pulls", reqSignIn, user.Pulls)
m.Get("/milestones", reqSignIn, reqMilestonesDashboardPageEnabled, user.Milestones) m.Get("/milestones", reqSignIn, reqMilestonesDashboardPageEnabled, user.Milestones)

@ -2,9 +2,11 @@
<a class="{{if .PageIsExploreRepositories}}active{{end}} item" href="{{AppSubUrl}}/explore/repos"> <a class="{{if .PageIsExploreRepositories}}active{{end}} item" href="{{AppSubUrl}}/explore/repos">
{{svg "octicon-repo"}} {{.i18n.Tr "explore.repos"}} {{svg "octicon-repo"}} {{.i18n.Tr "explore.repos"}}
</a> </a>
{{if not .UsersIsDisabled}}
<a class="{{if .PageIsExploreUsers}}active{{end}} item" href="{{AppSubUrl}}/explore/users"> <a class="{{if .PageIsExploreUsers}}active{{end}} item" href="{{AppSubUrl}}/explore/users">
{{svg "octicon-person"}} {{.i18n.Tr "explore.users"}} {{svg "octicon-person"}} {{.i18n.Tr "explore.users"}}
</a> </a>
{{end}}
<a class="{{if .PageIsExploreOrganizations}}active{{end}} item" href="{{AppSubUrl}}/explore/organizations"> <a class="{{if .PageIsExploreOrganizations}}active{{end}} item" href="{{AppSubUrl}}/explore/organizations">
{{svg "octicon-organization"}} {{.i18n.Tr "explore.organizations"}} {{svg "octicon-organization"}} {{.i18n.Tr "explore.organizations"}}
</a> </a>

Loading…
Cancel
Save