229 lines
4.5 KiB
Go
229 lines
4.5 KiB
Go
package session
|
|
|
|
import (
|
|
"dk/internal/cookies"
|
|
"dk/internal/router"
|
|
"time"
|
|
)
|
|
|
|
const SessionCookieName = "dk_session"
|
|
|
|
var Manager *SessionManager
|
|
|
|
type SessionManager struct {
|
|
store *Store
|
|
}
|
|
|
|
func Init(sessionsFilePath string) {
|
|
if Manager != nil {
|
|
panic("session manager already initialized")
|
|
}
|
|
Manager = &SessionManager{
|
|
store: NewStore(sessionsFilePath),
|
|
}
|
|
}
|
|
|
|
func GetManager() *SessionManager {
|
|
if Manager == nil {
|
|
panic("session manager not initialized")
|
|
}
|
|
return Manager
|
|
}
|
|
|
|
func (sm *SessionManager) Create(userID int, username, email string) *Session {
|
|
sess := New(userID, username, email)
|
|
sm.store.Save(sess)
|
|
return sess
|
|
}
|
|
|
|
func (sm *SessionManager) Get(sessionID string) (*Session, bool) {
|
|
return sm.store.Get(sessionID)
|
|
}
|
|
|
|
func (sm *SessionManager) GetFromContext(ctx router.Ctx) (*Session, bool) {
|
|
sessionID := cookies.GetCookie(ctx, SessionCookieName)
|
|
if sessionID == "" {
|
|
return nil, false
|
|
}
|
|
return sm.Get(sessionID)
|
|
}
|
|
|
|
func (sm *SessionManager) Update(sessionID string) bool {
|
|
sess, exists := sm.store.Get(sessionID)
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
sess.Touch()
|
|
sm.store.Save(sess)
|
|
return true
|
|
}
|
|
|
|
func (sm *SessionManager) Delete(sessionID string) {
|
|
sm.store.Delete(sessionID)
|
|
}
|
|
|
|
func (sm *SessionManager) SetSessionCookie(ctx router.Ctx, sessionID string) {
|
|
cookies.SetSecureCookie(ctx, cookies.CookieOptions{
|
|
Name: SessionCookieName,
|
|
Value: sessionID,
|
|
Path: "/",
|
|
Expires: time.Now().Add(DefaultExpiration),
|
|
HTTPOnly: true,
|
|
Secure: cookies.IsHTTPS(ctx),
|
|
SameSite: "lax",
|
|
})
|
|
}
|
|
|
|
func (sm *SessionManager) DeleteSessionCookie(ctx router.Ctx) {
|
|
cookies.DeleteCookie(ctx, SessionCookieName)
|
|
}
|
|
|
|
func (sm *SessionManager) SetFlashMessage(ctx router.Ctx, msgType, message string) bool {
|
|
sess, exists := sm.GetFromContext(ctx)
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
sess.SetFlash("message", FlashMessage{
|
|
Type: msgType,
|
|
Message: message,
|
|
})
|
|
sm.store.Save(sess)
|
|
return true
|
|
}
|
|
|
|
func (sm *SessionManager) GetFlashMessage(ctx router.Ctx) *FlashMessage {
|
|
sess, exists := sm.GetFromContext(ctx)
|
|
if !exists {
|
|
return nil
|
|
}
|
|
|
|
value, exists := sess.GetFlash("message")
|
|
if !exists {
|
|
return nil
|
|
}
|
|
|
|
sm.store.Save(sess)
|
|
|
|
if msg, ok := value.(FlashMessage); ok {
|
|
return &msg
|
|
}
|
|
|
|
if msgMap, ok := value.(map[string]interface{}); ok {
|
|
msg := &FlashMessage{}
|
|
if t, ok := msgMap["type"].(string); ok {
|
|
msg.Type = t
|
|
}
|
|
if m, ok := msgMap["message"].(string); ok {
|
|
msg.Message = m
|
|
}
|
|
return msg
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (sm *SessionManager) SetFormData(ctx router.Ctx, data map[string]string) bool {
|
|
sess, exists := sm.GetFromContext(ctx)
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
sess.Set("form_data", data)
|
|
sm.store.Save(sess)
|
|
return true
|
|
}
|
|
|
|
func (sm *SessionManager) GetFormData(ctx router.Ctx) map[string]string {
|
|
sess, exists := sm.GetFromContext(ctx)
|
|
if !exists {
|
|
return nil
|
|
}
|
|
|
|
value, exists := sess.Get("form_data")
|
|
if !exists {
|
|
return nil
|
|
}
|
|
|
|
sess.Delete("form_data")
|
|
sm.store.Save(sess)
|
|
|
|
if formData, ok := value.(map[string]string); ok {
|
|
return formData
|
|
}
|
|
|
|
if formMap, ok := value.(map[string]interface{}); ok {
|
|
result := make(map[string]string)
|
|
for k, v := range formMap {
|
|
if str, ok := v.(string); ok {
|
|
result[k] = str
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (sm *SessionManager) Stats() (total, active int) {
|
|
return sm.store.Stats()
|
|
}
|
|
|
|
func (sm *SessionManager) Close() error {
|
|
return sm.store.Close()
|
|
}
|
|
|
|
// Package-level convenience functions that use the global Manager
|
|
|
|
func Create(userID int, username, email string) *Session {
|
|
return Manager.Create(userID, username, email)
|
|
}
|
|
|
|
func Get(sessionID string) (*Session, bool) {
|
|
return Manager.Get(sessionID)
|
|
}
|
|
|
|
func GetFromContext(ctx router.Ctx) (*Session, bool) {
|
|
return Manager.GetFromContext(ctx)
|
|
}
|
|
|
|
func Update(sessionID string) bool {
|
|
return Manager.Update(sessionID)
|
|
}
|
|
|
|
func Delete(sessionID string) {
|
|
Manager.Delete(sessionID)
|
|
}
|
|
|
|
func SetSessionCookie(ctx router.Ctx, sessionID string) {
|
|
Manager.SetSessionCookie(ctx, sessionID)
|
|
}
|
|
|
|
func DeleteSessionCookie(ctx router.Ctx) {
|
|
Manager.DeleteSessionCookie(ctx)
|
|
}
|
|
|
|
func SetFlashMessage(ctx router.Ctx, msgType, message string) bool {
|
|
return Manager.SetFlashMessage(ctx, msgType, message)
|
|
}
|
|
|
|
func GetFlashMessage(ctx router.Ctx) *FlashMessage {
|
|
return Manager.GetFlashMessage(ctx)
|
|
}
|
|
|
|
func SetFormData(ctx router.Ctx, data map[string]string) bool {
|
|
return Manager.SetFormData(ctx, data)
|
|
}
|
|
|
|
func GetFormData(ctx router.Ctx) map[string]string {
|
|
return Manager.GetFormData(ctx)
|
|
}
|
|
|
|
func Stats() (total, active int) {
|
|
return Manager.Stats()
|
|
}
|
|
|
|
func Close() error {
|
|
return Manager.Close()
|
|
} |