96 lines
2.0 KiB
Go
96 lines
2.0 KiB
Go
package session
|
|
|
|
import (
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
|
|
"astraltech.xyz/accountmanager/src/logging"
|
|
)
|
|
|
|
const SessionCookieName = "session_token"
|
|
|
|
type SessionManager struct {
|
|
store SessionStore
|
|
}
|
|
|
|
var instance *SessionManager
|
|
var once sync.Once
|
|
|
|
type StoreType int
|
|
|
|
const (
|
|
InMemory StoreType = iota
|
|
)
|
|
|
|
func GetSessionManager() *SessionManager {
|
|
once.Do(func() {
|
|
instance = &SessionManager{}
|
|
})
|
|
return instance
|
|
}
|
|
|
|
func (manager *SessionManager) SetStoreType(storeType StoreType) {
|
|
logging.Infof("Changing session manager store type")
|
|
switch storeType {
|
|
case InMemory:
|
|
{
|
|
manager.store = NewMemoryStore()
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func (manager *SessionManager) CreateSession(userID string) (cookie *http.Cookie, err error) {
|
|
logging.Debugf("Creating a new session for %s", userID)
|
|
token, err := GenerateSessionToken(32) // Use crypto/rand for this
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
CSRFToken, err := GenerateSessionToken(32)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
newSessionData := SessionData{
|
|
UserID: userID,
|
|
CSRFToken: CSRFToken,
|
|
ExpiresAt: time.Now().Add(time.Hour),
|
|
}
|
|
err = manager.store.Create(token, &newSessionData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
newCookie := &http.Cookie{
|
|
Name: SessionCookieName,
|
|
Value: token,
|
|
Path: "/",
|
|
HttpOnly: true, // Essential: prevents JS access
|
|
Secure: true, // Set to TRUE in production (HTTPS)
|
|
SameSite: http.SameSiteLaxMode,
|
|
MaxAge: 3600, // 1 hour
|
|
}
|
|
return newCookie, nil
|
|
}
|
|
|
|
func (manager *SessionManager) GetSession(r *http.Request) (*SessionData, error) {
|
|
logging.Debug("Validating session from request")
|
|
cookie, err := r.Cookie(SessionCookieName)
|
|
if err != nil {
|
|
return nil, ErrSessionNotFound
|
|
}
|
|
token := cookie.Value
|
|
if token == "" {
|
|
return nil, ErrSessionNotFound
|
|
}
|
|
data, err := manager.store.Get(token)
|
|
if err != nil {
|
|
return nil, ErrSessionNotFound
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
func (manager *SessionManager) DeleteSession(sessionId string) error {
|
|
return manager.store.Delete(sessionId)
|
|
}
|