mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-28 16:55:32 +00:00
101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
package middleware
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
|
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers/collections"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
)
|
|
|
|
var SESSION_CACHE = collections.NewUserSessionCache(1000, 5*time.Minute)
|
|
var deact_cookie = &http.Cookie{
|
|
Name: dbmodels.SESSION_COOKIE_NAME,
|
|
MaxAge: -1,
|
|
Path: "/",
|
|
}
|
|
|
|
func Authenticated(app core.App) func(*core.RequestEvent) error {
|
|
return func(e *core.RequestEvent) error {
|
|
if strings.HasPrefix(e.Request.URL.Path, "/assets") ||
|
|
strings.HasPrefix(e.Request.URL.Path, "/api") ||
|
|
strings.HasPrefix(e.Request.URL.Path, "/_") {
|
|
return e.Next()
|
|
}
|
|
|
|
cookie, err := e.Request.Cookie(dbmodels.SESSION_COOKIE_NAME)
|
|
if err != nil {
|
|
return e.Next()
|
|
}
|
|
|
|
user, session, loaded := SESSION_CACHE.Get(cookie.Value)
|
|
if !loaded {
|
|
s, err := dbmodels.Sessions_Token(app, cookie.Value)
|
|
if err != nil {
|
|
e.SetCookie(deact_cookie)
|
|
e.Response.Header().Set("Clear-Site-Data", "\"cookies\"")
|
|
return e.Next()
|
|
}
|
|
|
|
slog.Debug("Session loaded from database", "session", s.Id, "user", s.User())
|
|
u, err := dbmodels.Users_ID(app, s.User())
|
|
if err != nil {
|
|
e.SetCookie(deact_cookie)
|
|
e.Response.Header().Set("Clear-Site-Data", "\"cookies\"")
|
|
return e.Next()
|
|
}
|
|
user, session = SESSION_CACHE.Set(u, s)
|
|
}
|
|
|
|
slog.Debug("User session detected", "user", user.Id, "name", user.Name, "session", session.ID)
|
|
|
|
if session.IsExpired() || user.Deactivated {
|
|
// TODO: (Maybe) less rigid handling here: for creation or update of items forgive shortly
|
|
// expired tokens, if CSRF and everything else is a match.
|
|
slog.Warn("Session expired", "user", user.Id, "name", user.Name, "session", session.ID)
|
|
SESSION_CACHE.Delete(cookie.Value)
|
|
go func() {
|
|
r, err := dbmodels.Sessions_ID(app, session.ID)
|
|
if err == nil {
|
|
r.SetStatus(dbmodels.TOKEN_STATUS_VALUES[1])
|
|
if err := app.Save(r); err != nil {
|
|
app.Logger().Error("Failed to save session status", "session", session.ID, "error", err)
|
|
}
|
|
}
|
|
e.SetCookie(deact_cookie)
|
|
e.Response.Header().Set("Clear-Site-Data", "\"cookies\"")
|
|
}()
|
|
return e.Next()
|
|
}
|
|
|
|
e.Set("user", user)
|
|
e.Set("session", session)
|
|
|
|
token := e.Request.URL.Query().Get("token")
|
|
if token != "" {
|
|
a, err := dbmodels.AccessTokens_Token(app, token)
|
|
if err != nil {
|
|
slog.Error("Failed to find access token", "token", token, "error", err)
|
|
return e.Next()
|
|
}
|
|
|
|
if a.User() != "" {
|
|
u, err := dbmodels.Users_ID(app, a.User())
|
|
if err != nil {
|
|
slog.Error("Failed to find access token user", "user", a.User(), "error", err)
|
|
return e.Next()
|
|
}
|
|
|
|
e.Set("access_token_user", u.Fixed())
|
|
}
|
|
|
|
e.Set("access_token", a.Fixed())
|
|
}
|
|
|
|
return e.Next()
|
|
}
|
|
}
|