feat: expire & prolong sessions

This commit is contained in:
efim 2023-12-01 04:09:17 +00:00
parent e0bd77fe3b
commit cc33c3f742
3 changed files with 34 additions and 6 deletions

View File

@ -34,6 +34,7 @@ func indexPageRoute(
) http.HandlerFunc { ) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session, err := getRequestSession(r, sessionSM) session, err := getRequestSession(r, sessionSM)
log.Printf("/ the session i got is %+v", session)
if err != nil { if err != nil {
log.Printf("/ session not found, means should render the login section %s", err) log.Printf("/ session not found, means should render the login section %s", err)
// TODO return error i guess // TODO return error i guess

View File

@ -71,7 +71,7 @@ func getRequestSession(r *http.Request,
if err != nil { if err != nil {
return sessions.SessionData{}, ErrAuthCookieValueInvalid return sessions.SessionData{}, ErrAuthCookieValueInvalid
} }
session := sessionsM.Get(sessionId) session := sessionsM.Get(r.Context(), sessionId)
if session == (sessions.SessionData{}) { if session == (sessions.SessionData{}) {
return sessions.SessionData{}, ErrAuthSessionNotFound return sessions.SessionData{}, ErrAuthSessionNotFound
} }
@ -177,6 +177,7 @@ func createRoomHandler(templateFs *embed.FS,
// todo return error notice somehow // todo return error notice somehow
} }
newSession, err := sessionSM.Save(r.Context(), newRoom.Name, person.Id) newSession, err := sessionSM.Save(r.Context(), newRoom.Name, person.Id)
log.Printf("saving session %v", newSession)
if err != nil { if err != nil {
log.Printf("what am i to do? error saving session %s", err) log.Printf("what am i to do? error saving session %s", err)
// todo return error notice somehow // todo return error notice somehow
@ -187,6 +188,7 @@ func createRoomHandler(templateFs *embed.FS,
Secure: true, Secure: true,
HttpOnly: true, HttpOnly: true,
Path: "/", Path: "/",
Expires: time.Now().Add(newSession.ExpireIn),
}) })
w.Header().Add("HX-Redirect", fmt.Sprintf("/room/%s", newRoom.Name)) w.Header().Add("HX-Redirect", fmt.Sprintf("/room/%s", newRoom.Name))
} }
@ -308,6 +310,7 @@ func joinRoomHandler(templateFs *embed.FS,
} }
newSession, err := sessionSM.Save(r.Context(), room.Name, person.Id) newSession, err := sessionSM.Save(r.Context(), room.Name, person.Id)
log.Printf("saving session %v", newSession)
if err != nil { if err != nil {
log.Printf("/login/submit > error saving session %s", err) log.Printf("/login/submit > error saving session %s", err)
} }
@ -317,6 +320,7 @@ func joinRoomHandler(templateFs *embed.FS,
Secure: true, Secure: true,
HttpOnly: true, HttpOnly: true,
Path: "/", Path: "/",
Expires: time.Now().Add(newSession.ExpireIn),
}) })
log.Printf("is is %+v. room things %s & %s, personal things %s and %s. \n found room %+v", log.Printf("is is %+v. room things %s & %s, personal things %s and %s. \n found room %+v",
newSession, roomName, roomPass, personName, personPass, room, newSession, roomName, roomPass, personName, personPass, room,

View File

@ -16,15 +16,18 @@ type SessionData struct {
SessionId int `redis:"session_id"` SessionId int `redis:"session_id"`
RoomId string `redis:"room_id"` RoomId string `redis:"room_id"`
PersonId rooms.PersonId `redis:"person_id"` PersonId rooms.PersonId `redis:"person_id"`
ExpireIn time.Duration `redis:"-"`
} }
type SessionManagement interface { type SessionManagement interface {
Get(sessionId int) SessionData Get(ctx context.Context, sessionId int) SessionData
Save(ctx context.Context, roomName string, personId rooms.PersonId) (SessionData, error) Save(ctx context.Context, roomName string, personId rooms.PersonId) (SessionData, error)
Remove(ctx context.Context, sessionId int) error Remove(ctx context.Context, sessionId int) error
} }
const sessionPrefix = "session" const sessionPrefix = "session"
const SessionTtl = 3 * time.Hour
const SessionProlongationWindow = time.Hour
func sessionIdToKey(sessionId int) string { func sessionIdToKey(sessionId int) string {
return fmt.Sprintf("%s:%d", sessionPrefix, sessionId) return fmt.Sprintf("%s:%d", sessionPrefix, sessionId)
@ -34,15 +37,34 @@ type RedisSM struct {
Rdb *redis.Client Rdb *redis.Client
} }
func (redisSM RedisSM) Get(sessionId int) SessionData { func (redisSM RedisSM) Get(ctx context.Context, sessionId int) SessionData {
var foundSession SessionData var foundSession SessionData
redisKey := sessionIdToKey(sessionId) redisKey := sessionIdToKey(sessionId)
err := redisSM.Rdb.HGetAll(context.TODO(), redisKey).Scan(&foundSession) err := redisSM.Rdb.HGetAll(ctx, redisKey).Scan(&foundSession)
if err != nil { if err != nil {
log.Printf("> error reading %s : %s", redisKey, err) log.Printf("> error reading %s : %s", redisKey, err)
return SessionData{} return SessionData{}
} }
log.Printf("> successfully found %d %+v", sessionId, foundSession) log.Printf("> successfully found %d %+v", sessionId, foundSession)
ttl, err := redisSM.Rdb.TTL(ctx, redisKey).Result()
if err != nil {
log.Printf("> error getting ttl for session %+v", foundSession)
return foundSession
}
if ttl == -2 {
log.Printf("> ttl indicates session doesn't exist for session %+v", foundSession)
return SessionData{}
}
if ttl < SessionProlongationWindow {
err = redisSM.Rdb.Expire(ctx, redisKey, SessionTtl).Err()
if err != nil {
log.Printf("> error updating ttl for session %+v", foundSession)
return foundSession
} else {
ttl = SessionTtl
}
}
foundSession.ExpireIn = ttl
return foundSession return foundSession
} }
func (redisSM RedisSM) Save(ctx context.Context, roomName string, personId rooms.PersonId) (SessionData, error) { func (redisSM RedisSM) Save(ctx context.Context, roomName string, personId rooms.PersonId) (SessionData, error) {
@ -51,9 +73,10 @@ func (redisSM RedisSM) Save(ctx context.Context, roomName string, personId rooms
SessionId: randId, SessionId: randId,
RoomId: roomName, RoomId: roomName,
PersonId: personId, PersonId: personId,
ExpireIn: SessionTtl,
} }
err := redisSM.Rdb.HSet(ctx, sessionIdToKey(randId), newSession).Err() err := redisSM.Rdb.HSet(ctx, sessionIdToKey(randId), newSession).Err()
redisSM.Rdb.Expire(ctx, sessionIdToKey(randId), 24 * time.Hour) redisSM.Rdb.Expire(ctx, sessionIdToKey(randId), SessionTtl)
if err != nil { if err != nil {
log.Printf("> error! saving session %+v %s", newSession, err) log.Printf("> error! saving session %+v %s", newSession, err)
@ -69,7 +92,7 @@ func (redisSM RedisSM) Remove(ctx context.Context, sessionId int) error {
type DummySM struct{} type DummySM struct{}
func (d DummySM) Get(sessionId int) SessionData { func (d DummySM) Get(ctx context.Context, sessionId int) SessionData {
log.Printf("get dummy session by %d", sessionId) log.Printf("get dummy session by %d", sessionId)
return SessionData{} return SessionData{}
} }