refac: article reads, story delete, no leaks, stored SEO status, rate limit, cleanup (%site%, article repo split, old lang repos, one default per site rule to domain)
This commit is contained in:
1 parent
9d284e65a9
commit
7c15206170
85 files changed
+1788
-593
No files matched your search
+20
-4
@@ -55,6 +55,9 @@ const (
|
||||
apiKeyMaxRequests = 120
|
||||
apiKeyWindow = time.Minute
|
||||
|
||||
publicReadMaxRequests = apiKeyMaxRequests
|
||||
publicReadWindow = apiKeyWindow
|
||||
|
||||
emailChangeMaxRequests = 5
|
||||
emailChangeWindow = 15 * time.Minute
|
||||
|
||||
@@ -71,6 +74,17 @@ func (c *UseCases) apiKeyAuth() func(http.Handler) http.Handler {
|
||||
return c.apiKeyAuthMiddleware
|
||||
}
|
||||
|
||||
func (c *UseCases) publicReadLimit(trustedProxies []string) func(http.Handler) http.Handler {
|
||||
c.publicReadLimitOnce.Do(func() {
|
||||
realIP := middleware.TrustedProxyRealIP(trustedProxies)
|
||||
limiter := middleware.NewRateLimiter(publicReadMaxRequests, publicReadWindow)
|
||||
c.publicReadLimitMiddleware = func(next http.Handler) http.Handler {
|
||||
return realIP(limiter(next))
|
||||
}
|
||||
})
|
||||
return c.publicReadLimitMiddleware
|
||||
}
|
||||
|
||||
func (c *UseCases) require(key string) func(http.Handler) http.Handler {
|
||||
return middleware.RequirePermission(c.GetUserUseCase, c.CheckPermissionUseCase, key)
|
||||
}
|
||||
@@ -121,8 +135,9 @@ func NewArticleRouter(container *UseCases, trustedProxies []string) http.Handler
|
||||
return r
|
||||
}
|
||||
|
||||
func NewPublicRouter(container *UseCases) http.Handler {
|
||||
func NewPublicRouter(container *UseCases, trustedProxies []string) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
r.Use(container.publicReadLimit(trustedProxies))
|
||||
|
||||
publicHandler := article.NewPublicHandler(container.ResolvePublicArticleUseCase)
|
||||
|
||||
@@ -136,13 +151,14 @@ func NewStoryRouter(container *UseCases, trustedProxies []string) http.Handler {
|
||||
r.Use(container.apiKeyAuth())
|
||||
r.Use(middleware.AuditContext(container.GetUserUseCase, trustedProxies))
|
||||
|
||||
storyHandler := story.NewHandler(container.MoveStoryUseCase)
|
||||
storyHandler := story.NewHandler(container.MoveStoryUseCase, container.DeleteStoryUseCase)
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(authtoken.Authenticator)
|
||||
r.Use(middleware.RequireCurrentToken(container.GetUserUseCase))
|
||||
r.Use(middleware.RequireVerifiedUser(container.GetUserUseCase))
|
||||
r.With(container.requireArticle(role.KeyContentUpdate)).Post("/{story_id}/move", storyHandler.Move)
|
||||
r.With(container.requireArticle(role.KeyContentDelete)).Delete("/{story_id}", storyHandler.Delete)
|
||||
})
|
||||
return r
|
||||
}
|
||||
@@ -328,7 +344,7 @@ func NewSiteRouter(container *UseCases, trustedProxies []string) http.Handler {
|
||||
|
||||
ownershipHandler := ownership.NewHandler(container.TransferOwnershipUseCase)
|
||||
|
||||
r.Get("/{key}/sitemap", sitemapHandler.Sitemap)
|
||||
r.With(container.publicReadLimit(trustedProxies)).Get("/{key}/sitemap", sitemapHandler.Sitemap)
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(authtoken.Verifier(container.Token))
|
||||
r.Use(container.apiKeyAuth())
|
||||
@@ -637,7 +653,7 @@ func InitBackendRoutes(container *UseCases, settings config.Settings) *chi.Mux {
|
||||
r.Mount("/article", NewArticleRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/story", NewStoryRouter(container, settings.TrustedProxies))
|
||||
})
|
||||
r.Mount("/public", NewPublicRouter(container))
|
||||
r.Mount("/public", NewPublicRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/user", NewUserRouter(container, settings.IsProduction(), settings.AuthRateLimit, settings.TrustedProxies))
|
||||
r.Mount("/settings", NewSettingsRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/site", NewSiteRouter(container, settings.TrustedProxies))
|
||||
|
||||
Reference in new issue
Block a user