Skip to content

Commit 939eaab

Browse files
committed
Play with session cache in memory
1 parent d761112 commit 939eaab

File tree

2 files changed

+82
-13
lines changed

2 files changed

+82
-13
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: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,53 @@ import (
44
"encoding/json"
55
"log/slog"
66
"net/http"
7+
"sync"
78

89
"ctf01d/internal/app/repository"
910
"ctf01d/internal/app/server"
1011
api_helpers "ctf01d/internal/app/utils"
11-
"ctf01d/internal/app/view"
1212

13+
"github.com/google/uuid"
1314
openapi_types "github.com/oapi-codegen/runtime/types"
1415
)
1516

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

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

52-
func (h *Handlers) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request) {
92+
func (h *Handler) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request) {
5393
cookie, err := r.Cookie("session_id")
5494
if err != nil {
5595
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignOut")
@@ -63,6 +103,10 @@ func (h *Handlers) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request)
63103
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Failed to delete session"})
64104
return
65105
}
106+
107+
// Удаляем сессию из кэша
108+
h.SessionCache.DeleteSession(cookie.Value)
109+
66110
http.SetCookie(w, &http.Cookie{
67111
Name: "session_id",
68112
Value: "",
@@ -72,13 +116,20 @@ func (h *Handlers) PostApiV1AuthSignOut(w http.ResponseWriter, r *http.Request)
72116
api_helpers.RespondWithJSON(w, http.StatusOK, map[string]string{"data": "User logout successful"})
73117
}
74118

75-
func (h *Handlers) ValidateSession(w http.ResponseWriter, r *http.Request) {
119+
func (h *SessionHandler) ValidateSession(w http.ResponseWriter, r *http.Request) {
76120
cookie, err := r.Cookie("session_id")
77121
if err != nil {
78122
slog.Warn(err.Error(), "handler", "ValidateSession")
79123
api_helpers.RespondWithJSON(w, http.StatusUnauthorized, map[string]string{"error": "No session found"})
80124
return
81125
}
126+
127+
if userId, ok := h.SessionCache.GetSession(cookie.Value); ok {
128+
slog.Debug("ValidateSession user.Id " + openapi_types.UUID(userId).String())
129+
h.respondWithUserDetails(w, r, userId)
130+
return
131+
}
132+
82133
slog.Debug("cookie.Value, " + cookie.Value)
83134
repo := repository.NewSessionRepository(h.DB)
84135
var userId openapi_types.UUID
@@ -88,14 +139,23 @@ func (h *Handlers) ValidateSession(w http.ResponseWriter, r *http.Request) {
88139
api_helpers.RespondWithJSON(w, http.StatusUnauthorized, map[string]string{"error": "No user or session found"})
89140
return
90141
}
142+
143+
h.SessionCache.SetSession(cookie.Value, userId)
91144
slog.Debug("ValidateSession user.Id " + openapi_types.UUID(userId).String())
145+
h.respondWithUserDetails(w, r, userId)
146+
}
92147

148+
func (h *SessionHandler) respondWithUserDetails(w http.ResponseWriter, r *http.Request, userId openapi_types.UUID) {
93149
userRepo := repository.NewUserRepository(h.DB)
94150
user, err := userRepo.GetById(r.Context(), userId)
95151
if err != nil {
96-
slog.Warn(err.Error(), "handler", "ValidateSession")
152+
slog.Warn(err.Error(), "handler", "respondWithUserDetails")
97153
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Could not find user by user id"})
98154
return
99155
}
100-
api_helpers.RespondWithJSON(w, http.StatusOK, view.NewSessionFromModel(user))
156+
res := make(map[string]string)
157+
res["name"] = user.DisplayName
158+
res["role"] = api_helpers.ConvertUserRequestRoleToString(user.Role)
159+
160+
api_helpers.RespondWithJSON(w, http.StatusOK, res)
101161
}

0 commit comments

Comments
 (0)