From c261597b9adb827bfa16de8f21ce47ac63bec138 Mon Sep 17 00:00:00 2001
From: Alexander NeonXP Kiryukhin <i@neonxp.ru>
Date: Mon, 29 Jul 2024 02:46:54 +0300
Subject: Сессии в отдельном подпакете
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 middleware/context.go         |  8 ++--
 middleware/session.go         | 89 ----------------------------------------
 middleware/session/bbolt.go   |  2 +-
 middleware/session/session.go | 94 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 99 insertions(+), 94 deletions(-)
 delete mode 100644 middleware/session.go
 create mode 100644 middleware/session/session.go

diff --git a/middleware/context.go b/middleware/context.go
index b9ad45f..a76bca0 100644
--- a/middleware/context.go
+++ b/middleware/context.go
@@ -4,8 +4,8 @@ type ctxKey int
 
 const (
 	requestIDKey ctxKey = iota
-	sessionIDKey
-	sessionValueKey
-	sessionConfigKey
-	sessionStorerKey
+	SessionIDKey
+	SessionValueKey
+	SessionConfigKey
+	SessionStorerKey
 )
diff --git a/middleware/session.go b/middleware/session.go
deleted file mode 100644
index 838e088..0000000
--- a/middleware/session.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package middleware
-
-import (
-	"context"
-	"errors"
-	"net/http"
-
-	"go.neonxp.ru/mux"
-	"go.neonxp.ru/mux/middleware/session"
-	"go.neonxp.ru/objectid"
-)
-
-type SessionConfig struct {
-	SessionCookie string
-	Path          string
-	Domain        string
-	Secure        bool
-	HttpOnly      bool
-	MaxAge        int
-}
-
-var DefaultSessionConfig SessionConfig = SessionConfig{
-	SessionCookie: "_session",
-	Path:          "/",
-	Domain:        "",
-	Secure:        false,
-	HttpOnly:      true,
-	MaxAge:        30 * 3600,
-}
-
-func Session(config SessionConfig, storer session.Store) mux.Middleware {
-	return func(h http.Handler) http.Handler {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			var (
-				sessionID string
-				values    session.Value
-			)
-			cookie, err := r.Cookie(config.SessionCookie)
-			switch {
-			case err == nil:
-				sessionID = cookie.Value
-				values = storer.Load(r.Context(), sessionID)
-			case errors.Is(err, http.ErrNoCookie):
-				sessionID = objectid.New().String()
-				values = session.Value{}
-			}
-
-			http.SetCookie(w, &http.Cookie{
-				Name:     config.SessionCookie,
-				Value:    sessionID,
-				Path:     config.Path,
-				Domain:   config.Domain,
-				Secure:   config.Secure,
-				HttpOnly: config.HttpOnly,
-				MaxAge:   config.MaxAge,
-			})
-
-			ctx := context.WithValue(r.Context(), sessionValueKey, &values)
-			ctx = context.WithValue(ctx, sessionIDKey, sessionID)
-			ctx = context.WithValue(ctx, sessionConfigKey, config)
-			ctx = context.WithValue(ctx, sessionStorerKey, storer)
-
-			h.ServeHTTP(w, r.WithContext(ctx))
-
-			storer.Save(r.Context(), sessionID, values)
-
-		})
-	}
-}
-
-func SessionFromRequest(r *http.Request) *session.Value {
-	return r.Context().Value(sessionValueKey).(*session.Value)
-}
-
-func ClearSession(w http.ResponseWriter, r *http.Request) {
-	storer := r.Context().Value(sessionStorerKey).(session.Store)
-	sessionID := r.Context().Value(sessionIDKey).(string)
-	storer.Remove(r.Context(), sessionID)
-	config := r.Context().Value(sessionConfigKey).(SessionConfig)
-	http.SetCookie(w, &http.Cookie{
-		Name:     config.SessionCookie,
-		Value:    sessionID,
-		Path:     config.Path,
-		Domain:   config.Domain,
-		Secure:   config.Secure,
-		HttpOnly: config.HttpOnly,
-		MaxAge:   -1,
-	})
-}
diff --git a/middleware/session/bbolt.go b/middleware/session/bbolt.go
index 1068ed8..be484d7 100644
--- a/middleware/session/bbolt.go
+++ b/middleware/session/bbolt.go
@@ -9,7 +9,7 @@ import (
 	"go.etcd.io/bbolt"
 )
 
-func New(db *bbolt.DB, bucketName []byte) Store {
+func NewBoltStore(db *bbolt.DB, bucketName []byte) Store {
 	return &BoltStore{
 		db:         db,
 		bucketName: bucketName,
diff --git a/middleware/session/session.go b/middleware/session/session.go
new file mode 100644
index 0000000..4d02bf1
--- /dev/null
+++ b/middleware/session/session.go
@@ -0,0 +1,94 @@
+package session
+
+import (
+	"context"
+	"errors"
+	"net/http"
+	"sync"
+
+	"go.neonxp.ru/mux"
+	"go.neonxp.ru/mux/middleware"
+	"go.neonxp.ru/objectid"
+)
+
+type Config struct {
+	SessionCookie string
+	Path          string
+	Domain        string
+	Secure        bool
+	HttpOnly      bool
+	MaxAge        int
+}
+
+var DefaultConfig Config = Config{
+	SessionCookie: "_session",
+	Path:          "/",
+	Domain:        "",
+	Secure:        false,
+	HttpOnly:      true,
+	MaxAge:        30 * 3600,
+}
+
+func Middleware(config Config, storer Store) mux.Middleware {
+	if storer == nil {
+		storer = &MemoryStore{store: sync.Map{}}
+	}
+
+	return func(h http.Handler) http.Handler {
+		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+			var (
+				sessionID string
+				values    Value
+			)
+			cookie, err := r.Cookie(config.SessionCookie)
+			switch {
+			case err == nil:
+				sessionID = cookie.Value
+				values = storer.Load(r.Context(), sessionID)
+			case errors.Is(err, http.ErrNoCookie):
+				sessionID = objectid.New().String()
+				values = Value{}
+			}
+
+			http.SetCookie(w, &http.Cookie{
+				Name:     config.SessionCookie,
+				Value:    sessionID,
+				Path:     config.Path,
+				Domain:   config.Domain,
+				Secure:   config.Secure,
+				HttpOnly: config.HttpOnly,
+				MaxAge:   config.MaxAge,
+			})
+
+			ctx := context.WithValue(r.Context(), middleware.SessionValueKey, &values)
+			ctx = context.WithValue(ctx, middleware.SessionIDKey, sessionID)
+			ctx = context.WithValue(ctx, middleware.SessionConfigKey, config)
+			ctx = context.WithValue(ctx, middleware.SessionStorerKey, storer)
+
+			h.ServeHTTP(w, r.WithContext(ctx))
+
+			storer.Save(r.Context(), sessionID, values)
+
+		})
+	}
+}
+
+func FromRequest(r *http.Request) *Value {
+	return r.Context().Value(middleware.SessionValueKey).(*Value)
+}
+
+func Clear(w http.ResponseWriter, r *http.Request) {
+	storer := r.Context().Value(middleware.SessionStorerKey).(Store)
+	sessionID := r.Context().Value(middleware.SessionIDKey).(string)
+	storer.Remove(r.Context(), sessionID)
+	config := r.Context().Value(middleware.SessionConfigKey).(Config)
+	http.SetCookie(w, &http.Cookie{
+		Name:     config.SessionCookie,
+		Value:    sessionID,
+		Path:     config.Path,
+		Domain:   config.Domain,
+		Secure:   config.Secure,
+		HttpOnly: config.HttpOnly,
+		MaxAge:   -1,
+	})
+}
-- 
cgit v1.2.3