added cookie login

This commit is contained in:
2025-10-04 12:49:04 -06:00
parent f728eb21b0
commit 3ef8d6b9a6
7 changed files with 172 additions and 15 deletions
+29 -2
View File
@@ -14,7 +14,9 @@ import (
"bytes"
"net/http"
"strconv"
"time"
"git.erbosoft.com/amy/amsterdam/config"
"git.erbosoft.com/amy/amsterdam/database"
"github.com/CloudyKit/jet/v6"
"github.com/gorilla/sessions"
@@ -25,6 +27,7 @@ import (
// AmContext is the interface for Amsterdam's wrapper context that exposes the required functionality.
type AmContext interface {
ClearLoginCookie()
ClearSession()
CurrentUser() *database.User
CurrentUserId() int32
@@ -39,6 +42,7 @@ type AmContext interface {
ReplaceUser(*database.User)
SaveSession() error
SubRender(string) ([]byte, error)
SetLoginCookie(string)
SetOutputType(string)
SetRC(int)
GetScratch(string) any
@@ -57,12 +61,22 @@ type amContext struct {
session *sessions.Session
}
// ClearLoginCookie overwrites and removes the login cookie.
func (c *amContext) ClearLoginCookie() {
cookie := new(http.Cookie)
cookie.Name = config.GlobalConfig.Site.LoginCookieName
cookie.Value = ""
cookie.Path = "/"
cookie.Expires = time.Now()
c.echoContext.SetCookie(cookie)
}
// ClearSession clears the current session.
func (c *amContext) ClearSession() {
for k := range c.session.Values {
delete(c.session.Values, k)
}
SetupAmSession(c.session)
setupAmSession(c.session)
}
// CurrentUser returns the current user from the session.
@@ -191,6 +205,19 @@ func (c *amContext) SubRender(name string) ([]byte, error) {
return buf.Bytes(), err
}
/* SetLoginCookie adds the login cookie to the result output.
* Parameters:
* auth - The auth string to set.
*/
func (c *amContext) SetLoginCookie(auth string) {
cookie := new(http.Cookie)
cookie.Name = config.GlobalConfig.Site.LoginCookieName
cookie.Value = auth
cookie.Path = "/"
cookie.Expires = time.Now().AddDate(0, 0, config.GlobalConfig.Site.LoginCookieAge)
c.echoContext.SetCookie(cookie)
}
// SetOutputType sets the MIME output type for the current operation.
func (c *amContext) SetOutputType(typ string) {
c.outputType = typ
@@ -253,7 +280,7 @@ func NewAmContext(ctxt echo.Context) (AmContext, error) {
rc.session = sess
sess.Options = defoptions
if sess.IsNew {
SetupAmSession(sess)
setupAmSession(sess)
} else {
log.Debugf("took the not-new-session path")
}
+31
View File
@@ -14,8 +14,10 @@ import (
"fmt"
"net/http"
"git.erbosoft.com/amy/amsterdam/config"
"git.erbosoft.com/amy/amsterdam/database"
"github.com/labstack/echo/v4"
"github.com/labstack/gommon/log"
)
func sendPageData(ctxt echo.Context, amctxt AmContext, command string, data any) error {
@@ -63,11 +65,14 @@ func ErrorPage(ctxt AmContext, input_err error) (string, any, error) {
*/
func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc {
return func(ctxt echo.Context) error {
// Create the AmContext.
amctxt, aerr := NewAmContext(ctxt)
if aerr != nil {
ctxt.Logger().Errorf("Session creation error: %v", aerr)
return aerr
}
// Check IP banning.
banmsg, banerr := database.AmTestIPBan(ctxt.RealIP())
if banerr != nil {
ctxt.Logger().Warnf("address %s could not be tested: %v", ctxt.RealIP(), banerr)
@@ -75,8 +80,33 @@ func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc {
} else if banmsg != "" {
amctxt.VarMap().Set("amsterdam_pageTitle", "IP Address Banned")
amctxt.VarMap().Set("message", banmsg)
amctxt.SetRC(http.StatusForbidden)
return sendPageData(ctxt, amctxt, "framed_template", "ipban.jet")
}
// Check for cookie login.
if amctxt.CurrentUser().IsAnon {
cookie, cerr := ctxt.Cookie(config.GlobalConfig.Site.LoginCookieName)
if cerr == nil {
var user *database.User
user, cerr = database.AmAuthenticateUserByToken(cookie.Value, ctxt.RealIP())
if cerr == nil {
// log the user in and rotate login cookie
amctxt.ReplaceUser(user)
var newToken string
if newToken, cerr = user.NewAuthToken(); cerr == nil {
amctxt.SetLoginCookie(newToken)
} else {
log.Warnf("unable to rotate login cookie: %v", cerr)
}
} else {
log.Errorf("login cookie bogus, do not use: %v", cerr)
amctxt.ClearLoginCookie()
}
}
}
// Exec the wrapped function.
what, rc, err := myfunc(amctxt)
if err == nil {
if err = amctxt.SaveSession(); err != nil {
@@ -90,6 +120,7 @@ func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc {
} else {
ctxt.Logger().Errorf("Page function error: %v", err)
_, rc, _ = ErrorPage(amctxt, err)
amctxt.SetRC(http.StatusInternalServerError)
newerr := sendPageData(ctxt, amctxt, "framed_template", rc)
err = newerr
}
+2 -2
View File
@@ -26,8 +26,8 @@ func SetupSessionManager() {
SessionStore = memstore.NewMemStore([]byte(config.GlobalConfig.Rendering.CookieKey))
}
// SetupAmSession sets up a newly created Amsterdam session.
func SetupAmSession(session *sessions.Session) {
// setupAmSession sets up a newly created Amsterdam session.
func setupAmSession(session *sessions.Session) {
u, err := database.AmGetAnonUser()
if err == nil {
session.Values["user_id"] = u.Uid