~netlandish/links

f6d4ec7d0b28276688953274cc433a6d0148ba97 — Peter Sanchez a month ago efac942
Adding base rate limiter config and rate limiting to registration handlers
2 files changed, 30 insertions(+), 4 deletions(-)

M accounts/routes.go
M helpers.go
M accounts/routes.go => accounts/routes.go +6 -4
@@ 12,6 12,7 @@ import (
	"git.sr.ht/~emersion/gqlclient"
	sq "github.com/Masterminds/squirrel"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"netlandish.com/x/gobwebs"
	formguard "netlandish.com/x/gobwebs-formguard"
	"netlandish.com/x/gobwebs/accounts"


@@ 33,12 34,13 @@ type Service struct {

// RegisterRoutes ...
func (s *Service) RegisterRoutes() {
	rlConfig := links.RLConfig
	s.Group.GET("/register", s.Register).Name = s.RouteName("register")
	s.Group.POST("/register", s.Register).Name = s.RouteName("register_post")
	s.Group.POST("/register", s.Register, middleware.RateLimiterWithConfig(rlConfig)).Name = s.RouteName("register_post")
	s.Group.GET("/register/:key", s.Register).Name = s.RouteName("register_invitation")
	s.Group.POST("/register/:key", s.Register).Name = s.RouteName("register_invitation_post")
	s.Group.POST("/register/:key", s.Register, middleware.RateLimiterWithConfig(rlConfig)).Name = s.RouteName("register_invitation_post")
	s.Group.GET("/register/confirm", s.CompleteRegister).Name = s.RouteName("complete_register")
	s.Group.POST("/register/confirm", s.CompleteRegister).Name = s.RouteName("complete_register_post")
	s.Group.POST("/register/confirm", s.CompleteRegister, middleware.RateLimiterWithConfig(rlConfig)).Name = s.RouteName("complete_register_post")

	// Register default routes from gobwebs
	gservice := accounts.NewService(s.Group, s.Name, s.fetch, s.RenderFunc)


@@ 330,7 332,7 @@ func (s *Service) CompleteRegister(c echo.Context) error {
			}
			return err
		}
		messages.Success(c, lt.Translate("Register Completed"))
		messages.Success(c, lt.Translate("Registration Completed"))
		return c.Redirect(http.StatusMovedPermanently, c.Echo().Reverse("accounts:login"))

	}

M helpers.go => helpers.go +24 -0
@@ 26,11 26,13 @@ import (
	"github.com/99designs/gqlgen/graphql"
	sq "github.com/Masterminds/squirrel"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"github.com/segmentio/ksuid"
	"github.com/shopspring/decimal"
	"golang.org/x/net/html"
	"golang.org/x/text/cases"
	"golang.org/x/text/language"
	"golang.org/x/time/rate"
	"netlandish.com/x/gobwebs"
	"netlandish.com/x/gobwebs/config"
	"netlandish.com/x/gobwebs/core"


@@ 1028,3 1030,25 @@ func GetSEOData(c echo.Context) *SEOData {
	seoData.RssURL = url.String()
	return seoData
}

// RLConfig is a base rate limit config struct that can be used and altered
// in handlers as needed.
var RLConfig = middleware.RateLimiterConfig{
	Skipper: func(c echo.Context) bool {
		gctx := c.(*server.Context)
		if gctx.User.IsAuthenticated() && gctx.User.IsSuperUser() {
			return true
		}
		return false
	},
	Store: middleware.NewRateLimiterMemoryStoreWithConfig(
		middleware.RateLimiterMemoryStoreConfig{
			Rate:      rate.Limit(3),
			Burst:     5,
			ExpiresIn: 3 * time.Minute,
		},
	),
	IdentifierExtractor: func(c echo.Context) (string, error) {
		return c.RealIP(), nil
	},
}