control: Generalize cookie and csrf handling

This commit is contained in:
Tom Wiesing 2023-01-05 15:59:24 +01:00
parent eb17dbe33f
commit 34bdb3cf24
No known key found for this signature in database
15 changed files with 122 additions and 44 deletions

View file

@ -18,28 +18,38 @@ func (control *Control) Server(ctx context.Context, progress io.Writer) (http.Ha
// create a new mux
mux := http.NewServeMux()
// add all the servable routes!
// create a csrf protector
csrfProtector := control.CSRF()
// iterate over all the handler
for _, s := range control.Dependencies.Routeables {
for _, route := range s.Routes() {
zerolog.Ctx(ctx).Info().Str("component", s.Name()).Str("route", route).Msg("mounting route")
handler, err := s.HandleRoute(ctx, route)
routes := s.Routes()
zerolog.Ctx(ctx).Info().Str("component", s.Name()).Strs("paths", routes.Paths).Bool("csrf", routes.CSRF).Bool("decorator", routes.Decorator != nil).Msg("mounting route")
for _, path := range routes.Paths {
handler, err := s.HandleRoute(ctx, path)
if err != nil {
return nil, err
}
mux.Handle(route, handler)
mux.Handle(path, routes.Decorate(handler, csrfProtector))
}
}
return func(handler http.HandlerFunc) http.Handler {
// setup a csrf protector for everything with POST
var opts []csrf.Option
if !control.Config.HTTPSEnabled() {
opts = append(opts, csrf.Secure(false))
}
opts = append(opts, csrf.SameSite(csrf.SameSiteStrictMode))
return csrf.Protect(control.Config.CSRFSecret(), opts...)(handler)
}(func(w http.ResponseWriter, r *http.Request) {
// apply the given context function
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r = r.WithContext(cancel.ValuesOf(r.Context(), ctx))
mux.ServeHTTP(w, r)
}), nil
}
// CSRF returns a CSRF handler for the given function
func (control *Control) CSRF() func(http.Handler) http.Handler {
var opts []csrf.Option
if !control.Config.HTTPSEnabled() {
opts = append(opts, csrf.Secure(false))
}
opts = append(opts, csrf.SameSite(csrf.SameSiteStrictMode))
opts = append(opts, csrf.CookieName(CSRFCookie))
opts = append(opts, csrf.FieldName(CSRFCookieField))
return csrf.Protect(control.Config.CSRFSecret(), opts...)
}