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>
This commit is contained in:
		
							parent
							
								
									bc423a1e84
								
							
						
					
					
						commit
						c8e5c79cfd
					
				| @ -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> | ||||||
| 	<a class="{{if .PageIsExploreUsers}}active{{end}} item" href="{{AppSubUrl}}/explore/users"> | 	{{if not .UsersIsDisabled}} | ||||||
| 		{{svg "octicon-person"}} {{.i18n.Tr "explore.users"}} | 		<a class="{{if .PageIsExploreUsers}}active{{end}} item" href="{{AppSubUrl}}/explore/users"> | ||||||
| 	</a> | 			{{svg "octicon-person"}} {{.i18n.Tr "explore.users"}} | ||||||
|  | 		</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…
	
		Reference in New Issue
	
	Block a user