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 }}