Skip to content

Commit 141f039

Browse files
committed
Play with session cache in memory
1 parent d761112 commit 141f039

File tree

2 files changed

+85
-17
lines changed

2 files changed

+85
-17
lines changed

internal/app/handlers/interface.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ type Handlers struct {
1212
DB *sql.DB
1313
}
1414

15-
// ServerInterfaceWrapper wraps Handlers to conform to the generated interface
1615
type ServerInterfaceWrapper struct {
1716
handlers *Handlers
1817
}
@@ -21,6 +20,16 @@ func NewServerInterfaceWrapper(handlers *Handlers) *ServerInterfaceWrapper {
2120
return &ServerInterfaceWrapper{handlers: handlers}
2221
}
2322

23+
type SessionServerInterfaceWrapper struct {
24+
sessionHandler *SessionHandler
25+
}
26+
27+
func NewSessionServerInterfaceWrapper(handlers *Handlers) *SessionServerInterfaceWrapper {
28+
return &SessionServerInterfaceWrapper{
29+
sessionHandler: NewSessionHandler(handlers),
30+
}
31+
}
32+
2433
func (siw *ServerInterfaceWrapper) ListGames(w http.ResponseWriter, r *http.Request) {
2534
siw.handlers.ListGames(w, r)
2635
}
@@ -41,16 +50,16 @@ func (siw *ServerInterfaceWrapper) UpdateGame(w http.ResponseWriter, r *http.Req
4150
siw.handlers.UpdateGame(w, r, id)
4251
}
4352

44-
func (siw *ServerInterfaceWrapper) PostApiV1AuthSignIn(w http.ResponseWriter, r *http.Request) {
45-
siw.handlers.PostApiV1AuthSignIn(w, r)
53+
func (siw *SessionServerInterfaceWrapper) PostApiV1AuthSignIn(w http.ResponseWriter, r *http.Request) {
54+
siw.sessionHandler.PostApiV1AuthSignIn(w, r)
4655
}
4756

48-
func (siw *ServerInterfaceWrapper) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request) {
49-
siw.handlers.PostApiV1AuthSignOut(w, r)
57+
func (siw *SessionServerInterfaceWrapper) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request) {
58+
siw.sessionHandler.PostApiV1AuthSignOut(w, r)
5059
}
5160

52-
func (siw *ServerInterfaceWrapper) ValidateSession(w http.ResponseWriter, r *http.Request) {
53-
siw.handlers.ValidateSession(w, r)
61+
func (siw *SessionServerInterfaceWrapper) ValidateSession(w http.ResponseWriter, r *http.Request) {
62+
siw.sessionHandler.ValidateSession(w, r)
5463
}
5564

5665
func (siw *ServerInterfaceWrapper) ListResults(w http.ResponseWriter, r *http.Request) {

internal/app/handlers/sessions.go

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,55 @@
11
package handlers
22

33
import (
4-
"encoding/json"
5-
"log/slog"
6-
"net/http"
7-
84
"ctf01d/internal/app/repository"
95
"ctf01d/internal/app/server"
106
api_helpers "ctf01d/internal/app/utils"
11-
"ctf01d/internal/app/view"
7+
"encoding/json"
8+
"log/slog"
9+
"net/http"
10+
"sync"
1211

12+
"github.com/google/uuid"
1313
openapi_types "github.com/oapi-codegen/runtime/types"
1414
)
1515

16-
func (h *Handlers) PostApiV1AuthSignIn(w http.ResponseWriter, r *http.Request) {
16+
type SessionCache struct {
17+
cache sync.Map
18+
}
19+
20+
func NewSessionCache() *SessionCache {
21+
return &SessionCache{}
22+
}
23+
24+
func (sc *SessionCache) GetSession(sessionID string) (openapi_types.UUID, bool) {
25+
val, ok := sc.cache.Load(sessionID)
26+
if !ok {
27+
return uuid.Nil, false
28+
}
29+
return val.(openapi_types.UUID), true
30+
}
31+
32+
func (sc *SessionCache) SetSession(sessionID string, userID uuid.UUID) {
33+
sc.cache.Store(sessionID, userID)
34+
}
35+
36+
func (sc *SessionCache) DeleteSession(sessionID string) {
37+
sc.cache.Delete(sessionID)
38+
}
39+
40+
type SessionHandler struct {
41+
*Handlers
42+
SessionCache *SessionCache
43+
}
44+
45+
func NewSessionHandler(handlers *Handlers) *SessionHandler {
46+
return &SessionHandler{
47+
Handlers: handlers,
48+
SessionCache: NewSessionCache(),
49+
}
50+
}
51+
52+
func (h *SessionHandler) PostApiV1AuthSignIn(w http.ResponseWriter, r *http.Request) {
1753
var req server.PostApiV1AuthSignInJSONBody
1854
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
1955
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignIn")
@@ -38,6 +74,9 @@ func (h *Handlers) PostApiV1AuthSignIn(w http.ResponseWriter, r *http.Request) {
3874
return
3975
}
4076

77+
// Добавляем сессию в кэш
78+
h.SessionCache.SetSession(sessionId, user.Id)
79+
4180
http.SetCookie(w, &http.Cookie{
4281
Name: "session_id",
4382
HttpOnly: true,
@@ -49,7 +88,7 @@ func (h *Handlers) PostApiV1AuthSignIn(w http.ResponseWriter, r *http.Request) {
4988
api_helpers.RespondWithJSON(w, http.StatusOK, map[string]string{"data": "User logged in"})
5089
}
5190

52-
func (h *Handlers) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request) {
91+
func (h *Handler) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request) {
5392
cookie, err := r.Cookie("session_id")
5493
if err != nil {
5594
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignOut")
@@ -63,6 +102,10 @@ func (h *Handlers) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request)
63102
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Failed to delete session"})
64103
return
65104
}
105+
106+
// Удаляем сессию из кэша
107+
h.SessionCache.DeleteSession(cookie.Value)
108+
66109
http.SetCookie(w, &http.Cookie{
67110
Name: "session_id",
68111
Value: "",
@@ -72,13 +115,20 @@ func (h *Handlers) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request)
72115
api_helpers.RespondWithJSON(w, http.StatusOK, map[string]string{"data": "User logout successful"})
73116
}
74117

75-
func (h *Handlers) ValidateSession(w http.ResponseWriter, r *http.Request) {
118+
func (h *SessionHandler) ValidateSession(w http.ResponseWriter, r *http.Request) {
76119
cookie, err := r.Cookie("session_id")
77120
if err != nil {
78121
slog.Warn(err.Error(), "handler", "ValidateSession")
79122
api_helpers.RespondWithJSON(w, http.StatusUnauthorized, map[string]string{"error": "No session found"})
80123
return
81124
}
125+
126+
if userId, ok := h.SessionCache.GetSession(cookie.Value); ok {
127+
slog.Debug("ValidateSession user.Id " + openapi_types.UUID(userId).String())
128+
h.respondWithUserDetails(w, r, userId)
129+
return
130+
}
131+
82132
slog.Debug("cookie.Value, " + cookie.Value)
83133
repo := repository.NewSessionRepository(h.DB)
84134
var userId openapi_types.UUID
@@ -88,14 +138,23 @@ func (h *Handlers) ValidateSession(w http.ResponseWriter, r *http.Request) {
88138
api_helpers.RespondWithJSON(w, http.StatusUnauthorized, map[string]string{"error": "No user or session found"})
89139
return
90140
}
141+
142+
h.SessionCache.SetSession(cookie.Value, userId)
91143
slog.Debug("ValidateSession user.Id " + openapi_types.UUID(userId).String())
144+
h.respondWithUserDetails(w, r, userId)
145+
}
92146

147+
func (h *SessionHandler) respondWithUserDetails(w http.ResponseWriter, r *http.Request, userId openapi_types.UUID) {
93148
userRepo := repository.NewUserRepository(h.DB)
94149
user, err := userRepo.GetById(r.Context(), userId)
95150
if err != nil {
96-
slog.Warn(err.Error(), "handler", "ValidateSession")
151+
slog.Warn(err.Error(), "handler", "respondWithUserDetails")
97152
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Could not find user by user id"})
98153
return
99154
}
100-
api_helpers.RespondWithJSON(w, http.StatusOK, view.NewSessionFromModel(user))
155+
var res = make(map[string]string)
156+
res["name"] = user.DisplayName
157+
res["role"] = api_helpers.ConvertUserRequestRoleToString(user.Role)
158+
159+
api_helpers.RespondWithJSON(w, http.StatusOK, res)
101160
}

0 commit comments

Comments
 (0)