Enha: use of sql sessions
This commit is contained in:
@ -5,6 +5,7 @@
|
|||||||
{{template "linklogin" .LinkLogin}}
|
{{template "linklogin" .LinkLogin}}
|
||||||
{{ else if eq .State.RoomID "" }}
|
{{ else if eq .State.RoomID "" }}
|
||||||
<div id="hello-user">
|
<div id="hello-user">
|
||||||
|
<p>data: {{.}} {{.State}} {{.Room}}</p>
|
||||||
<p>Hello {{.State.Username}}</p>
|
<p>Hello {{.State.Username}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="create-room" class="create-room-div">
|
<div id="create-room" class="create-room-div">
|
||||||
|
BIN
gralias.db
BIN
gralias.db
Binary file not shown.
@ -130,10 +130,10 @@ func notifyBotIfNeeded(room *models.Room) {
|
|||||||
func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) {
|
func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) {
|
||||||
resp := &models.FullInfo{}
|
resp := &models.FullInfo{}
|
||||||
// state, err := getStateByCtx(ctx)
|
// state, err := getStateByCtx(ctx)
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
state, err := getPlayerByCtx(ctx)
|
state, err := getPlayerByCtx(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
resp.State = state
|
resp.State = state
|
||||||
if state.RoomID == "" {
|
if state.RoomID == "" {
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func abortWithError(w http.ResponseWriter, msg string) {
|
func abortWithError(w http.ResponseWriter, msg string) {
|
||||||
@ -144,9 +146,10 @@ func makeCookie(username string, remote string) (*http.Cookie, error) {
|
|||||||
// expiresAt := time.Now().Add(time.Duration(cfg.SessionLifetime) * time.Second)
|
// expiresAt := time.Now().Add(time.Duration(cfg.SessionLifetime) * time.Second)
|
||||||
// Set the token in the session map, along with the session information
|
// Set the token in the session map, along with the session information
|
||||||
session := &models.Session{
|
session := &models.Session{
|
||||||
Username: username,
|
Username: username,
|
||||||
CookieToken: sessionToken,
|
TokenKey: sessionToken,
|
||||||
Lifetime: uint32(cfg.SessionLifetime / 60),
|
UpdatedAt: time.Now(),
|
||||||
|
Lifetime: uint32(cfg.SessionLifetime / 60),
|
||||||
}
|
}
|
||||||
cookieName := "session_token"
|
cookieName := "session_token"
|
||||||
// hmac to protect cookies
|
// hmac to protect cookies
|
||||||
@ -173,6 +176,9 @@ func makeCookie(username string, remote string) (*http.Cookie, error) {
|
|||||||
log.Info("changing cookie domain", "domain", cookie.Domain)
|
log.Info("changing cookie domain", "domain", cookie.Domain)
|
||||||
}
|
}
|
||||||
// set ctx?
|
// set ctx?
|
||||||
|
if err := repo.SessionCreate(context.Background(), session); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
// set user in session
|
// set user in session
|
||||||
if err := cacheSetSession(sessionToken, session); err != nil {
|
if err := cacheSetSession(sessionToken, session); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -48,7 +48,10 @@ func HandleHome(w http.ResponseWriter, r *http.Request) {
|
|||||||
abortWithError(w, err.Error())
|
abortWithError(w, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fi, _ := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
}
|
||||||
if fi != nil && fi.Room != nil && fi.State != nil {
|
if fi != nil && fi.Room != nil && fi.State != nil {
|
||||||
fi.Room.UpdateCounter()
|
fi.Room.UpdateCounter()
|
||||||
if fi.State.Role == "mime" {
|
if fi.State.Role == "mime" {
|
||||||
|
@ -61,12 +61,12 @@ func GetSession(next http.Handler) http.Handler {
|
|||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userSession, err := cacheGetSession(sessionToken)
|
userSession, err := repo.SessionByToken(r.Context(), sessionToken)
|
||||||
|
// userSession, err := cacheGetSession(sessionToken)
|
||||||
// log.Debug("userSession from cache", "us", userSession)
|
// log.Debug("userSession from cache", "us", userSession)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// msg := "auth failed; session does not exists"
|
msg := "auth failed; session does not exists"
|
||||||
// err = errors.New(msg)
|
log.Debug(msg, "error", err, "key", sessionToken)
|
||||||
// log.Debug(msg, "error", err)
|
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ CREATE TABLE sessions(
|
|||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
lifetime INTEGER NOT NULL DEFAULT 3600,
|
lifetime INTEGER NOT NULL DEFAULT 3600,
|
||||||
cookie_token TEXT NOT NULL DEFAULT '', -- encoded value
|
token_key TEXT NOT NULL DEFAULT '' UNIQUE, -- encoded value
|
||||||
username TEXT NOT NULL,
|
username TEXT NOT NULL,
|
||||||
FOREIGN KEY (username) REFERENCES players(username)
|
FOREIGN KEY (username) REFERENCES players(username)
|
||||||
);
|
);
|
||||||
|
@ -6,19 +6,19 @@ import (
|
|||||||
|
|
||||||
// each session contains the username of the user and the time at which it expires
|
// each session contains the username of the user and the time at which it expires
|
||||||
type Session struct {
|
type Session struct {
|
||||||
ID uint32
|
ID uint32 `db:"id"`
|
||||||
// CurrentRoom string
|
// CurrentRoom string
|
||||||
// Expiry time.Time
|
// Expiry time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
Lifetime uint32 // minutes
|
Lifetime uint32 `db:"lifetime"` // minutes
|
||||||
CookieToken string
|
TokenKey string `db:"token_key"`
|
||||||
Username string // username is playerid
|
Username string `db:"username"` // username is playerid
|
||||||
}
|
}
|
||||||
|
|
||||||
// we'll use this method later to determine if the session has expired
|
// we'll use this method later to determine if the session has expired
|
||||||
func (s Session) IsExpired() bool {
|
func (s Session) IsExpired() bool {
|
||||||
return time.Now().After(s.UpdatedAt.Add(time.Minute * time.Duration(s.Lifetime)))
|
// return time.Now().After(s.UpdatedAt.Add(time.Minute * time.Duration(s.Lifetime)))
|
||||||
// return s.Expiry.Before(time.Now())
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// func ListUsernames(ss map[string]*Session) []string {
|
// func ListUsernames(ss map[string]*Session) []string {
|
||||||
|
@ -19,7 +19,7 @@ func (p *RepoProvider) SessionByToken(ctx context.Context, token string) (*model
|
|||||||
db := getDB(ctx, p.DB)
|
db := getDB(ctx, p.DB)
|
||||||
session := &models.Session{}
|
session := &models.Session{}
|
||||||
// The lifetime in the DB is in seconds, but in the model it is in minutes.
|
// The lifetime in the DB is in seconds, but in the model it is in minutes.
|
||||||
err := sqlx.GetContext(ctx, db, session, `SELECT id, updated_at, lifetime / 60 as lifetime, cookie_token, username FROM sessions WHERE cookie_token = ?`, token)
|
err := sqlx.GetContext(ctx, db, session, `SELECT id, updated_at, lifetime / 60 as lifetime, token_key, username FROM sessions WHERE token_key = ? LIMIT 1;`, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -29,21 +29,21 @@ func (p *RepoProvider) SessionByToken(ctx context.Context, token string) (*model
|
|||||||
func (p *RepoProvider) SessionCreate(ctx context.Context, session *models.Session) error {
|
func (p *RepoProvider) SessionCreate(ctx context.Context, session *models.Session) error {
|
||||||
db := getDB(ctx, p.DB)
|
db := getDB(ctx, p.DB)
|
||||||
// The lifetime in the model is in minutes, but in the DB it is in seconds.
|
// The lifetime in the model is in minutes, but in the DB it is in seconds.
|
||||||
_, err := db.ExecContext(ctx, `INSERT INTO sessions (updated_at, lifetime, cookie_token, username) VALUES (?, ?, ?, ?)`,
|
_, err := db.ExecContext(ctx, `INSERT INTO sessions (updated_at, lifetime, token_key, username) VALUES (?, ?, ?, ?) ON CONFLICT (token_key) DO UPDATE SET updated_at=CURRENT_TIMESTAMP, lifetime=excluded.lifetime;`,
|
||||||
time.Now(), session.Lifetime*60, session.CookieToken, session.Username)
|
time.Now(), session.Lifetime*60, session.TokenKey, session.Username)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RepoProvider) SessionUpdate(ctx context.Context, session *models.Session) error {
|
func (p *RepoProvider) SessionUpdate(ctx context.Context, session *models.Session) error {
|
||||||
db := getDB(ctx, p.DB)
|
db := getDB(ctx, p.DB)
|
||||||
// The lifetime in the model is in minutes, but in the DB it is in seconds.
|
// The lifetime in the model is in minutes, but in the DB it is in seconds.
|
||||||
_, err := db.ExecContext(ctx, `UPDATE sessions SET updated_at = ?, lifetime = ? WHERE cookie_token = ?`,
|
_, err := db.ExecContext(ctx, `UPDATE sessions SET updated_at = ?, lifetime = ? WHERE token_key = ?`,
|
||||||
time.Now(), session.Lifetime*60, session.CookieToken)
|
time.Now(), session.Lifetime*60, session.TokenKey)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RepoProvider) SessionDelete(ctx context.Context, token string) error {
|
func (p *RepoProvider) SessionDelete(ctx context.Context, token string) error {
|
||||||
db := getDB(ctx, p.DB)
|
db := getDB(ctx, p.DB)
|
||||||
_, err := db.ExecContext(ctx, `DELETE FROM sessions WHERE cookie_token = ?`, token)
|
_, err := db.ExecContext(ctx, `DELETE FROM sessions WHERE token_key = ?`, token)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
1
todos.md
1
todos.md
@ -30,6 +30,7 @@
|
|||||||
- clear indication that model (llm) is thinking / answered;
|
- clear indication that model (llm) is thinking / answered;
|
||||||
- possibly turn markings into parts of names of users (first three letters?);
|
- possibly turn markings into parts of names of users (first three letters?);
|
||||||
- at game creation list languages and support them at backend;
|
- at game creation list languages and support them at backend;
|
||||||
|
- sql ping goroutine with reconnect on fail;
|
||||||
|
|
||||||
#### sse points
|
#### sse points
|
||||||
- clue sse update;
|
- clue sse update;
|
||||||
|
Reference in New Issue
Block a user