Files
Self-Service-Dashboard/src/main/session.go
2026-03-25 10:20:20 -04:00

107 lines
2.3 KiB
Go

package main
import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"net/http"
"sync"
"time"
"astraltech.xyz/accountmanager/src/logging"
)
type SessionData struct {
loggedIn bool
data *UserData
timeCreated time.Time
CSRFToken string
}
var (
sessions = make(map[string]SessionData)
sessionMutex sync.Mutex
)
func GenerateSessionToken(length int) (string, error) {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
return "", err
}
token := base64.RawURLEncoding.EncodeToString(b)
return token, nil
}
func createSession(userData *UserData) *http.Cookie {
logging.Debugf("Creating a new session for %s", userData.Username)
token, err := GenerateSessionToken(32) // Use crypto/rand for this
if err != nil {
logging.Error(err.Error())
return nil
}
CSRFToken, err := GenerateSessionToken(32)
if err != nil {
logging.Error(err.Error())
return nil
}
tokenEncoded := sha256.Sum256([]byte(token))
tokenEncodedString := string(tokenEncoded[:])
sessionMutex.Lock()
defer sessionMutex.Unlock()
loggedIn := false
if userData != nil {
loggedIn = true
}
sessions[tokenEncodedString] = SessionData{
data: userData,
timeCreated: time.Now(),
CSRFToken: CSRFToken,
loggedIn: loggedIn,
}
cookie := &http.Cookie{
Name: "session_token",
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 cookie
}
func validateSession(r *http.Request) (bool, *SessionData) {
logging.Debugf("Validating session")
cookie, err := r.Cookie("session_token")
if err != nil {
logging.Error(err.Error())
return false, &SessionData{}
}
token := cookie.Value
tokenEncoded := sha256.Sum256([]byte(token))
tokenEncodedString := string(tokenEncoded[:])
sessionMutex.Lock()
sessionData, exists := sessions[tokenEncodedString]
sessionMutex.Unlock()
if !exists || !sessionData.loggedIn {
return false, &SessionData{}
}
logging.Infof("Validated session for %s", sessionData.data.Username)
return true, &sessionData
}
func deleteSession(session_id string) {
sessionMutex.Lock()
tokenEncoded := sha256.Sum256([]byte(session_id))
tokenEncodedString := string(tokenEncoded[:])
delete(sessions, tokenEncodedString)
sessionMutex.Unlock()
}