86 lines
2.1 KiB
Go
86 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-contrib/sessions"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// Middleware injects form data from session into context for templates
|
|
func SessionHandlerMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
session := sessions.Default(c)
|
|
raw := session.Get("form_data")
|
|
|
|
form := map[string]string{}
|
|
if raw != nil {
|
|
if data, ok := raw.(string); ok {
|
|
_ = json.Unmarshal([]byte(data), &form)
|
|
}
|
|
// clear after first use
|
|
session.Delete("form_data")
|
|
_ = session.Save()
|
|
}
|
|
|
|
// make available in context
|
|
c.Set("form", form)
|
|
|
|
// Set message in context when there is one available in the session
|
|
message := session.Get("message")
|
|
c.Set("mes", message)
|
|
session.Delete("message")
|
|
|
|
_ = session.Save()
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// SaveForm stores submitted POST form data into the session
|
|
func SaveForm(c *gin.Context) {
|
|
session := sessions.Default(c)
|
|
form := map[string]string{}
|
|
for key, values := range c.Request.PostForm {
|
|
if len(values) > 0 {
|
|
form[key] = values[0]
|
|
}
|
|
}
|
|
|
|
if b, err := json.Marshal(form); err == nil {
|
|
session.Set("form_data", string(b))
|
|
_ = session.Save()
|
|
}
|
|
}
|
|
|
|
// SaveForm stores submitted POST form data into the session
|
|
func SetMessage(c *gin.Context, message string) {
|
|
session := sessions.Default(c)
|
|
session.Set("message", message)
|
|
_ = session.Save()
|
|
}
|
|
|
|
func setSessionCookie(c *gin.Context, token string) {
|
|
// Very long-lived cookie for one year
|
|
maxAge := 365 * 24 * 60 * 60
|
|
httpOnly := true
|
|
secure := strings.HasPrefix(baseURL, "https://")
|
|
sameSite := http.SameSiteLaxMode
|
|
c.SetCookie("session", token, maxAge, "/", cookieDomain, secure, httpOnly)
|
|
// Workaround to set SameSite explicitly via header
|
|
c.Header("Set-Cookie", (&http.Cookie{Name: "session", Value: token, Path: "/", Domain: cookieDomain, MaxAge: maxAge, Secure: secure, HttpOnly: httpOnly, SameSite: sameSite}).String())
|
|
}
|
|
|
|
func getSessionUser(c *gin.Context) *User {
|
|
cookie, err := c.Cookie("session")
|
|
if err != nil || cookie == "" {
|
|
return nil
|
|
}
|
|
var s Session
|
|
if err := db.Preload("User").Where("token = ?", cookie).First(&s).Error; err != nil {
|
|
return nil
|
|
}
|
|
return &s.User
|
|
}
|