package web import ( "errors" "net/http" "time" "git.ulra.eu/adro/miniwol/config" "github.com/google/uuid" "github.com/labstack/echo/v4" "golang.org/x/crypto/bcrypt" ) var sessions map[string]time.Time func init() { sessions = make(map[string]time.Time) } func checkAuth(token string) error { for sToken, expiree := range sessions { // Expire old sessions if time.Now().After(expiree) { delete(sessions, sToken) continue } // Check for valid session of token if token == sToken { return nil } } return errors.New("this token is not associated with a valid session") } func withAuth(handler echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { session, err := c.Cookie("session") // Redirect to login if session expired/invalid if err != nil || checkAuth(session.Value) != nil { return c.Redirect(http.StatusSeeOther, "/") } // Refresh session sessions[session.Value] = time.Now().Add(time.Second * time.Duration(config.Config.SessionTTL*60)) return handler(c) } } // Handlers func auth(c echo.Context) error { password := c.FormValue("Password") if bcrypt.CompareHashAndPassword([]byte(config.Config.PassHash), []byte(password)) != nil { return c.String(401, "Wrong Password") } token := uuid.New().String() sessions[token] = time.Now().Add(time.Second * time.Duration(config.Config.SessionTTL*60)) c.SetCookie(&http.Cookie{ Name: "session", Value: token, Path: "/", Secure: true, HttpOnly: true, SameSite: http.SameSiteStrictMode, }) return c.Redirect(http.StatusSeeOther, "/") } func deauth(c echo.Context) error { session, err := c.Cookie("session") if err != nil { return err } delete(sessions, session.Value) return c.Redirect(http.StatusSeeOther, "/") }