From 4cce7b7454d0bab860ee5f6f5dbb607cb72f163d Mon Sep 17 00:00:00 2001 From: Gregory Wells Date: Mon, 8 Jun 2026 19:21:08 -0400 Subject: [PATCH] have user data persist between restarts in redis session --- src/main/login.go | 13 ++++++++++--- src/main/main.go | 27 ++++++++++++++------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main/login.go b/src/main/login.go index 8e4afa5..5b913f7 100644 --- a/src/main/login.go +++ b/src/main/login.go @@ -6,6 +6,7 @@ import ( "strings" "astraltech.xyz/accountmanager/src/logging" + "astraltech.xyz/accountmanager/src/store" ) type LoginPageData struct { @@ -32,9 +33,15 @@ func loginHandler(w http.ResponseWriter, r *http.Request) { logging.Infof("New Login request for %s\n", username) newUserData, err := authenticateUser(username, password) - userDataMutex.Lock() - userData[username] = newUserData - userDataMutex.Unlock() + + userDataErr := userData.Create(username, newUserData) + if userDataErr == store.ErrKeyAlreadyExists { + userData.Update(username, newUserData) + } else if userDataErr != nil { + logging.Error(userDataErr.Error()) + return + } + if err == ErrPasswordExpired { http.Redirect(w, r, "/reset-password?token=this_is_the_only_token_that_works", http.StatusFound) } else if err != nil { diff --git a/src/main/main.go b/src/main/main.go index a78e223..f3a0751 100644 --- a/src/main/main.go +++ b/src/main/main.go @@ -7,7 +7,6 @@ import ( "log" "net/http" "strings" - "sync" "astraltech.xyz/accountmanager/src/components" "astraltech.xyz/accountmanager/src/email" @@ -15,6 +14,7 @@ import ( "astraltech.xyz/accountmanager/src/ldap" "astraltech.xyz/accountmanager/src/logging" "astraltech.xyz/accountmanager/src/session" + "astraltech.xyz/accountmanager/src/store" ) var ( @@ -31,8 +31,7 @@ type UserData struct { } var ( - userData = make(map[string]*UserData) - userDataMutex sync.RWMutex + userData store.KeyValueStore[*UserData] ) var ErrPasswordExpired = errors.New("Password expired") @@ -94,25 +93,22 @@ func profileHandler(w http.ResponseWriter, r *http.Request) { return } - _, exists := userData[sessionData.UserID] - - if !exists { - logging.Error("Session id exists but user does not exist") + data, err := userData.Get(sessionData.UserID) + if err != nil { + logging.Error(err.Error()) http.Redirect(w, r, "/login", http.StatusSeeOther) return } if r.Method == http.MethodGet { tmpl := template.Must(template.ParseFiles("src/pages/profile_page.html")) - userDataMutex.RLock() tmpl.Execute(w, ProfileData{ Username: sessionData.UserID, - Email: userData[sessionData.UserID].Email, - DisplayName: userData[sessionData.UserID].DisplayName, + Email: data.Email, + DisplayName: data.DisplayName, CSRFToken: sessionData.CSRFToken, }) - userDataMutex.RUnlock() return } } @@ -207,8 +203,10 @@ func changePasswordHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte(`{"success": true}`)) + user_data, err := userData.Get(sessionData.UserID) + data := map[string]any{ - "Username": userData[sessionData.UserID].DisplayName, + "Username": user_data.DisplayName, "ServiceName": "Astral Tech", } @@ -216,7 +214,7 @@ func changePasswordHandler(w http.ResponseWriter, r *http.Request) { if err != nil { 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() { @@ -231,11 +229,14 @@ func main() { sessionManager = session.GetSessionManager() if serverConfig.WebserverConfig.SessionStore == "in_memory" { sessionManager.SetStoreType(session.InMemory) + userData = store.NewMemoryStore[*UserData]() } else if serverConfig.WebserverConfig.SessionStore == "redis" { 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 { logging.Warnf("'%s' is an unknown session store type defaulting to in memory", serverConfig.WebserverConfig.SessionStore) sessionManager.SetStoreType(session.InMemory) + userData = store.NewMemoryStore[*UserData]() } noReplyEmail = email.CreateEmailAccount(email.EmailAccountData{