123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- package web
- import (
- _ "embed"
- "fmt"
- "html/template"
- "net/http"
- "path/filepath"
- "time"
- "github.com/Masterminds/sprig/v3"
- "github.com/davecgh/go-spew/spew"
- "github.com/fgm/izidic"
- "github.com/gin-contrib/sessions"
- "github.com/gin-contrib/sessions/cookie"
- "github.com/gin-gonic/gin"
- "github.com/utrack/gin-csrf"
- "code.osinet.fr/fgm/sqs_demo/back/services"
- "code.osinet.fr/fgm/sqs_demo/back/services/redriver"
- "code.osinet.fr/fgm/sqs_demo/front"
- )
- func SetupRoutes(rd redriver.Redriver, ms redriver.MessageStore, renderer *template.Template, storeSecret, csrfSecret []byte) *gin.Engine {
- const assetsPrefix = "/assets/"
- r := gin.Default()
- r.SetHTMLTemplate(renderer)
- _ = r.SetTrustedProxies(nil)
- store := cookie.NewStore(storeSecret)
- r.Use(sessions.Sessions("defaultsession", store))
- mw := csrf.Middleware(csrf.Options{
- Secret: string(csrfSecret),
- ErrorFunc: func(c *gin.Context) {
- c.String(http.StatusBadRequest, "CSRF token does not match")
- c.Abort()
- },
- TokenGetter: nil,
- })
- // Done
- r.StaticFS(assetsPrefix, PrefixFileSystem(assetsPrefix, http.FS(front.Assets)))
- r.GET("/queue", gin.WrapH(http.RedirectHandler("/", http.StatusMovedPermanently)))
- r.GET("/queue/:name/confirm", mw, makeConfirmHandler()) // Needs mw to set token.
- // Back done, front WIP
- r.GET("/queue/:name", makeQueueHandler(rd, ms))
- // JSON done
- r.GET("/", makeHomeHandler(rd))
- // TODO
- r.POST("/queue/:name/delete", mw, makeDeleteHandler(rd)) // Needs mw to check token.
- r.POST("/queue/:name/purge", mw, makePurgeHandler(rd)) // Needs mw to check token.
- r.POST("/queue/:name/redrive", mw, makeRedriveHandler(rd)) // Needs mw to check token.
- return r
- }
- func HttpService(dic *izidic.Container) (any, error) {
- csrfSecret := dic.MustParam(services.PCSRFSecret).([]byte)
- storeSecret := dic.MustParam(services.PStoreSecret).([]byte)
- rd := dic.MustService(services.SvcRedriver).(redriver.Redriver)
- re := dic.MustService(services.SvcRenderer).(*template.Template)
- ms := dic.MustService(services.SvcMessageStore).(redriver.MessageStore)
- return SetupRoutes(rd, ms, re, storeSecret, csrfSecret), nil
- }
- func RendererService(_ *izidic.Container) (any, error) {
- var err error
- renderer := template.New("redriver").Funcs(template.FuncMap{
- "dump": func(args ...any) template.HTML {
- return "<pre>" + template.HTML(spew.Sdump(args...)) + "</pre>\n"
- },
- "timestamp": func(ts int64) time.Time {
- return time.Unix(ts, 0)
- },
- "nameFromARN": redriver.NameFromARNString,
- }).Funcs(sprig.FuncMap())
- for _, tpl := range []struct {
- name string
- value string
- }{
- {"confirm", front.Confirm},
- {"flashes", front.Flashes},
- {"home", front.Home},
- {"queue-get", front.QueueGet}, // Includes queue-item.
- {"500", front.Err500},
- } {
- renderer, err = renderer.New(tpl.name).Parse(tpl.value)
- if err != nil {
- return nil, fmt.Errorf("failed parsing %q template: %w", tpl.name, err)
- }
- }
- return renderer, nil
- }
- // PrefixFileSystem converts a http.FileSystem by serving it requests prefixed
- // by the passed prefix, allowing rooted static directories matching the name
- // of an embed.FS.
- func PrefixFileSystem(prefix string, ifs http.FileSystem) http.FileSystem {
- return &prefixedFS{
- prefix: prefix,
- ifs: ifs,
- }
- }
- type prefixedFS struct {
- prefix string
- ifs http.FileSystem
- }
- // Open implements http.FileSystem
- func (pfs *prefixedFS) Open(name string) (http.File, error) {
- return pfs.ifs.Open(filepath.Join(pfs.prefix, name))
- }
|