have user data persist between restarts in redis session

This commit is contained in:
Gregory Wells
2026-06-08 19:21:08 -04:00
parent 109199ea45
commit 4cce7b7454
2 changed files with 24 additions and 16 deletions
+10 -3
View File
@@ -6,6 +6,7 @@ import (
"strings" "strings"
"astraltech.xyz/accountmanager/src/logging" "astraltech.xyz/accountmanager/src/logging"
"astraltech.xyz/accountmanager/src/store"
) )
type LoginPageData struct { type LoginPageData struct {
@@ -32,9 +33,15 @@ func loginHandler(w http.ResponseWriter, r *http.Request) {
logging.Infof("New Login request for %s\n", username) logging.Infof("New Login request for %s\n", username)
newUserData, err := authenticateUser(username, password) newUserData, err := authenticateUser(username, password)
userDataMutex.Lock()
userData[username] = newUserData userDataErr := userData.Create(username, newUserData)
userDataMutex.Unlock() if userDataErr == store.ErrKeyAlreadyExists {
userData.Update(username, newUserData)
} else if userDataErr != nil {
logging.Error(userDataErr.Error())
return
}
if err == ErrPasswordExpired { if err == ErrPasswordExpired {
http.Redirect(w, r, "/reset-password?token=this_is_the_only_token_that_works", http.StatusFound) http.Redirect(w, r, "/reset-password?token=this_is_the_only_token_that_works", http.StatusFound)
} else if err != nil { } else if err != nil {
+14 -13
View File
@@ -7,7 +7,6 @@ import (
"log" "log"
"net/http" "net/http"
"strings" "strings"
"sync"
"astraltech.xyz/accountmanager/src/components" "astraltech.xyz/accountmanager/src/components"
"astraltech.xyz/accountmanager/src/email" "astraltech.xyz/accountmanager/src/email"
@@ -15,6 +14,7 @@ import (
"astraltech.xyz/accountmanager/src/ldap" "astraltech.xyz/accountmanager/src/ldap"
"astraltech.xyz/accountmanager/src/logging" "astraltech.xyz/accountmanager/src/logging"
"astraltech.xyz/accountmanager/src/session" "astraltech.xyz/accountmanager/src/session"
"astraltech.xyz/accountmanager/src/store"
) )
var ( var (
@@ -31,8 +31,7 @@ type UserData struct {
} }
var ( var (
userData = make(map[string]*UserData) userData store.KeyValueStore[*UserData]
userDataMutex sync.RWMutex
) )
var ErrPasswordExpired = errors.New("Password expired") var ErrPasswordExpired = errors.New("Password expired")
@@ -94,25 +93,22 @@ func profileHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
_, exists := userData[sessionData.UserID] data, err := userData.Get(sessionData.UserID)
if err != nil {
if !exists { logging.Error(err.Error())
logging.Error("Session id exists but user does not exist")
http.Redirect(w, r, "/login", http.StatusSeeOther) http.Redirect(w, r, "/login", http.StatusSeeOther)
return return
} }
if r.Method == http.MethodGet { if r.Method == http.MethodGet {
tmpl := template.Must(template.ParseFiles("src/pages/profile_page.html")) tmpl := template.Must(template.ParseFiles("src/pages/profile_page.html"))
userDataMutex.RLock()
tmpl.Execute(w, ProfileData{ tmpl.Execute(w, ProfileData{
Username: sessionData.UserID, Username: sessionData.UserID,
Email: userData[sessionData.UserID].Email, Email: data.Email,
DisplayName: userData[sessionData.UserID].DisplayName, DisplayName: data.DisplayName,
CSRFToken: sessionData.CSRFToken, CSRFToken: sessionData.CSRFToken,
}) })
userDataMutex.RUnlock()
return return
} }
} }
@@ -207,8 +203,10 @@ func changePasswordHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"success": true}`)) w.Write([]byte(`{"success": true}`))
user_data, err := userData.Get(sessionData.UserID)
data := map[string]any{ data := map[string]any{
"Username": userData[sessionData.UserID].DisplayName, "Username": user_data.DisplayName,
"ServiceName": "Astral Tech", "ServiceName": "Astral Tech",
} }
@@ -216,7 +214,7 @@ func changePasswordHandler(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
logging.Errorf("Failed to load email template: %s", err.Error()) logging.Errorf("Failed to load email template: %s", err.Error())
} }
noReplyEmail.SendEmail([]string{userData[sessionData.UserID].Email}, "Password expired", email_template) noReplyEmail.SendEmail([]string{user_data.Email}, "Password expired", email_template)
} }
func main() { func main() {
@@ -231,11 +229,14 @@ func main() {
sessionManager = session.GetSessionManager() sessionManager = session.GetSessionManager()
if serverConfig.WebserverConfig.SessionStore == "in_memory" { if serverConfig.WebserverConfig.SessionStore == "in_memory" {
sessionManager.SetStoreType(session.InMemory) sessionManager.SetStoreType(session.InMemory)
userData = store.NewMemoryStore[*UserData]()
} else if serverConfig.WebserverConfig.SessionStore == "redis" { } else if serverConfig.WebserverConfig.SessionStore == "redis" {
sessionManager.SetStoreType(session.Redis, serverConfig.WebserverConfig.RedisConfigInfo.RedisURL, serverConfig.WebserverConfig.RedisConfigInfo.Prefix) sessionManager.SetStoreType(session.Redis, serverConfig.WebserverConfig.RedisConfigInfo.RedisURL, serverConfig.WebserverConfig.RedisConfigInfo.Prefix)
userData = store.NewRedisStore[*UserData](serverConfig.WebserverConfig.RedisConfigInfo.RedisURL, serverConfig.WebserverConfig.RedisConfigInfo.Prefix)
} else { } else {
logging.Warnf("'%s' is an unknown session store type defaulting to in memory", serverConfig.WebserverConfig.SessionStore) logging.Warnf("'%s' is an unknown session store type defaulting to in memory", serverConfig.WebserverConfig.SessionStore)
sessionManager.SetStoreType(session.InMemory) sessionManager.SetStoreType(session.InMemory)
userData = store.NewMemoryStore[*UserData]()
} }
noReplyEmail = email.CreateEmailAccount(email.EmailAccountData{ noReplyEmail = email.CreateEmailAccount(email.EmailAccountData{