From 715ea29c390546c2bdbccf761c2728ced5383d98 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 28 Sep 2025 16:29:24 -0600 Subject: [PATCH] implemented logout --- login.go | 22 ++++++++++++++++++++++ main.go | 1 + top.go | 2 +- ui/amcontext.go | 27 +++++++++++++++++++++------ ui/render_wrap.go | 2 +- ui/session_mgr.go | 1 - ui/views/frame.jet | 2 +- 7 files changed, 47 insertions(+), 10 deletions(-) diff --git a/login.go b/login.go index f9a1d6e..997f6bd 100644 --- a/login.go +++ b/login.go @@ -94,6 +94,28 @@ func Login(ctxt ui.AmContext) (string, any, error) { return ui.ErrorPage(ctxt, err) } +/* Logout handles logging out from Amsterdam. + * Parameters: + * ctxt - The AmContext for the request. + * Returns: + * Command string dictating what to be rendered. + * Data as a parameter for the command string. + * Standard Go error status. + */ +func Logout(ctxt ui.AmContext) (string, any, error) { + // Get target URI. + target := ctxt.Parameter("tgt") + if target == "" { + target = "/" + } + + if !ctxt.CurrentUser().IsAnon { + // TODO: erase login cookie + ctxt.ClearSession() + } + return "redirect", target, nil +} + /* NewAccountUserAgreement renders the Amsterdam user agreement for new accounts. * Parameters: * ctxt - The AmContext for the request. diff --git a/main.go b/main.go index 9a21210..71ee29c 100644 --- a/main.go +++ b/main.go @@ -44,6 +44,7 @@ func setupEcho() *echo.Echo { e.GET("/about", ui.AmWrap(AboutPage)) e.GET("/login", ui.AmWrap(LoginForm)) e.POST("/login", ui.AmWrap(Login)) + e.GET("/logout", ui.AmWrap(Logout)) e.GET("/newacct", ui.AmWrap(NewAccountUserAgreement)) e.GET("/newacct2", ui.AmWrap(NewAccountForm)) diff --git a/top.go b/top.go index a968170..6fd4494 100644 --- a/top.go +++ b/top.go @@ -125,7 +125,7 @@ func TopPage(ctxt ui.AmContext) (string, any, error) { ctxt.VarMap().Set("amsterdam_pageTitle", "My Front Page") // Retrieve the sideboxes and create the data to be presented. - uid := ctxt.Session().Values["user_id"].(int32) + uid := ctxt.CurrentUserId() sboxes, err := database.AmGetSideboxes(uid) if err != nil { return "string", "Unable to retrieve sideboxes", err diff --git a/ui/amcontext.go b/ui/amcontext.go index 9e6fbe1..048a0ee 100644 --- a/ui/amcontext.go +++ b/ui/amcontext.go @@ -25,7 +25,9 @@ import ( // AmContext is the interface for Amsterdam's wrapper context that exposes the required functionality. type AmContext interface { + ClearSession() CurrentUser() *database.User + CurrentUserId() int32 FormField(string) string FormFieldInt(string) (int, error) FormFieldIsSet(string) bool @@ -35,8 +37,8 @@ type AmContext interface { RemoteIP() string Render(string) error ReplaceUser(*database.User) + SaveSession() error SubRender(string) ([]byte, error) - Session() *sessions.Session SetOutputType(string) SetRC(int) GetScratch(string) any @@ -55,6 +57,14 @@ type amContext struct { session *sessions.Session } +// ClearSession clears the current session. +func (c *amContext) ClearSession() { + for k := range c.session.Values { + delete(c.session.Values, k) + } + SetupAmSession(c.session) +} + // CurrentUser returns the current user from the session. func (c *amContext) CurrentUser() *database.User { u, err := database.AmGetUser(c.session.Values["user_id"].(int32)) @@ -64,6 +74,11 @@ func (c *amContext) CurrentUser() *database.User { return u } +// CurrentUserId returns the current user ID. +func (c *amContext) CurrentUserId() int32 { + return c.session.Values["user_id"].(int32) +} + /* FormField returns the value of a form field from the request. * Parameters: * name - The name of the field to retrieve. @@ -146,6 +161,11 @@ func (c *amContext) ReplaceUser(u *database.User) { c.session.Values["user_id"] = u.Uid } +// SaveSession saves the session link to cookies. +func (c *amContext) SaveSession() error { + return c.session.Save(c.echoContext.Request(), c.echoContext.Response()) +} + // Scratchpad returns the per-request scratchpad for values. func (c *amContext) Scratchpad() map[string]any { if c.scratchpad == nil { @@ -171,11 +191,6 @@ func (c *amContext) SubRender(name string) ([]byte, error) { return buf.Bytes(), err } -// Session returns the HTTP session. -func (c *amContext) Session() *sessions.Session { - return c.session -} - // SetOutputType sets the MIME output type for the current operation. func (c *amContext) SetOutputType(typ string) { c.outputType = typ diff --git a/ui/render_wrap.go b/ui/render_wrap.go index 665b7ab..e8a4f94 100644 --- a/ui/render_wrap.go +++ b/ui/render_wrap.go @@ -79,7 +79,7 @@ func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc { } what, rc, err := myfunc(amctxt) if err == nil { - if err = amctxt.Session().Save(ctxt.Request(), ctxt.Response()); err != nil { + if err = amctxt.SaveSession(); err != nil { ctxt.Logger().Errorf("Session save error: %v", err) return err } diff --git a/ui/session_mgr.go b/ui/session_mgr.go index b301d5f..fd98356 100644 --- a/ui/session_mgr.go +++ b/ui/session_mgr.go @@ -28,7 +28,6 @@ func SetupSessionManager() { // SetupAmSession sets up a newly created Amsterdam session. func SetupAmSession(session *sessions.Session) { - session.Values["temp"] = "Active" u, err := database.AmGetAnonUser() if err == nil { session.Values["user_id"] = u.Uid diff --git a/ui/views/frame.jet b/ui/views/frame.jet index 998be83..ab3ed2b 100644 --- a/ui/views/frame.jet +++ b/ui/views/frame.jet @@ -65,7 +65,7 @@ {{ else }} You are logged in as {{ .CurrentUser().Username }} - - Log Out + Log Out | Profile {{ end }}