aboutsummaryrefslogtreecommitdiffhomepage
path: root/backend/auth/session.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/auth/session.go')
-rw-r--r--backend/auth/session.go94
1 files changed, 94 insertions, 0 deletions
diff --git a/backend/auth/session.go b/backend/auth/session.go
new file mode 100644
index 0000000..f480bff
--- /dev/null
+++ b/backend/auth/session.go
@@ -0,0 +1,94 @@
+package auth
+
+import (
+ "errors"
+ "net/http"
+ "os"
+
+ "github.com/gorilla/sessions"
+ "github.com/labstack/echo-contrib/session"
+ "github.com/labstack/echo/v4"
+)
+
+const (
+ sessionName = "feedaka_session"
+ sessionUserIDKey = "user_id"
+ // Session duration: 7 days
+ sessionMaxAge = 7 * 24 * 60 * 60
+)
+
+var (
+ ErrNoSession = errors.New("no session found")
+ ErrNoUserIDInSession = errors.New("no user_id in session")
+ ErrNoSessionSecretEnvVar = errors.New("FEEDAKA_SESSION_SECRET environment variable is not set")
+)
+
+type SessionConfig struct {
+ store *sessions.CookieStore
+}
+
+func NewSessionConfig() (*SessionConfig, error) {
+ secret := os.Getenv("FEEDAKA_SESSION_SECRET")
+ if secret == "" {
+ return nil, ErrNoSessionSecretEnvVar
+ }
+ useNonSecureCookie := os.Getenv("FEEDAKA_DEV_NON_SECURE_COOKIE") == "1"
+
+ store := sessions.NewCookieStore([]byte(secret))
+ store.Options = &sessions.Options{
+ Path: "/",
+ MaxAge: sessionMaxAge,
+ HttpOnly: true,
+ Secure: !useNonSecureCookie,
+ SameSite: http.SameSiteDefaultMode,
+ }
+
+ return &SessionConfig{
+ store: store,
+ }, nil
+}
+
+func (c *SessionConfig) GetStore() *sessions.CookieStore {
+ return c.store
+}
+
+func (c *SessionConfig) SetUserID(ctx echo.Context, userID int64) error {
+ sess, err := session.Get(sessionName, ctx)
+ if err != nil {
+ return err
+ }
+
+ sess.Values[sessionUserIDKey] = userID
+ return sess.Save(ctx.Request(), ctx.Response())
+}
+
+func (c *SessionConfig) GetUserID(ctx echo.Context) (int64, error) {
+ sess, err := session.Get(sessionName, ctx)
+ if err != nil {
+ return 0, ErrNoSession
+ }
+
+ userIDVal, ok := sess.Values[sessionUserIDKey]
+ if !ok {
+ return 0, ErrNoUserIDInSession
+ }
+
+ userID, ok := userIDVal.(int64)
+ if !ok {
+ return 0, ErrNoUserIDInSession
+ }
+
+ return userID, nil
+}
+
+func (c *SessionConfig) DestroySession(ctx echo.Context) error {
+ sess, err := session.Get(sessionName, ctx)
+ if err != nil {
+ // If there's no session, nothing to destroy
+ return nil
+ }
+
+ // Set MaxAge to -1 to delete the session
+ sess.Options.MaxAge = -1
+ return sess.Save(ctx.Request(), ctx.Response())
+}