diff --git a/config/default.yaml b/config/default.yaml index 290e7e8..80b8325 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -10,7 +10,7 @@ site: title: "Amsterdam Web Communities System" database: driver: "mysql" - dsn: "amsdb:x00yes2k@tcp(localhost)/amsterdam" + dsn: "amsdb:x00yes2k@tcp(localhost)/amsterdam?parseTime=true&loc=Local" rendering: templatedir: custom_templates cookiekey: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz diff --git a/database/user.go b/database/user.go index b6e9042..4285450 100644 --- a/database/user.go +++ b/database/user.go @@ -10,38 +10,63 @@ package database import ( + "encoding/gob" "fmt" "time" ) // User represents a user in the Amsterdam database. type User struct { - Uid int32 `db:"uid"` - Username string `db:"username"` - Passhash string `db:"passhash"` - Tokenauth string `db:"tokenauth"` - ContactID int32 `db:"contactid"` - IsAnon bool `db:"is_anon"` - VerifyEMail bool `db:"verify_email"` - Lockout bool `db:"lockout"` - AccessTries int16 `db:"access_tries"` - EmailConfNum int32 `db:"email_confnum"` - BaseLevel uint16 `db:"base_lvl"` - Created time.Time `db:"created"` - LastAccess time.Time `db:"lastaccess"` - PassReminder string `db:"passreminder"` - Description string `db:"description"` - DOB time.Time `db:"dob"` + Uid int32 `db:"uid"` + Username string `db:"username"` + Passhash string `db:"passhash"` + Tokenauth *string `db:"tokenauth"` + ContactID int32 `db:"contactid"` + IsAnon bool `db:"is_anon"` + VerifyEMail bool `db:"verify_email"` + Lockout bool `db:"lockout"` + AccessTries int16 `db:"access_tries"` + EmailConfNum int32 `db:"email_confnum"` + BaseLevel uint16 `db:"base_lvl"` + Created time.Time `db:"created"` + LastAccess *time.Time `db:"lastaccess"` + PassReminder string `db:"passreminder"` + Description *string `db:"description"` + DOB *time.Time `db:"dob"` +} + +// init registers data types from this module. +func init() { + gob.Register(User{}) +} + +/* AmGetUser returns a reference to the specified user. + * Parameters: + * uid - The UID of the user. + * Returns: + * Pointer to User containing user data, or nil + * Standard Go error status + */ +func AmGetUser(uid int32) (*User, error) { + var rc []User + err := amdb.Select(&rc, "SELECT * from users WHERE uid = ?", uid) + if err != nil { + return nil, err + } + if len(rc) > 1 { + return nil, fmt.Errorf("AmGetUser(%d): too many responses(%d)", uid, len(rc)) + } + return &(rc[0]), err } /* AmGetAmonUser returns a reference to the anonymous user. * Returns: - * Pointer to User containing anonymous user data + * Pointer to User containing anonymous user data, or nil * Standard Go error status */ func AmGetAnonUser() (*User, error) { var rc []User - err := amdb.Select(&rc, "SELECT * from users WHERE uid = 1") + err := amdb.Select(&rc, "SELECT * from users WHERE is_anon = 1") if err != nil { return nil, err } diff --git a/go.mod b/go.mod index 2812388..d604e58 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/labstack/echo-contrib v0.17.4 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect golang.org/x/crypto v0.38.0 // indirect diff --git a/go.sum b/go.sum index 68e1ef2..b68c8f5 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b h1:aUNXCGgukb4gtY99imuIeoh8Vr0GSwAlYxPAhqZrpFc= +github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/logging.go b/logging.go index 97ea51c..5ad737a 100644 --- a/logging.go +++ b/logging.go @@ -25,7 +25,7 @@ func init() { FullTimestamp: true, TimestampFormat: "2006-01-02 15:04:05", }) - log.SetLevel(log.InfoLevel) + log.SetLevel(log.DebugLevel) } /* toglog converts a Logrus logging level to a glog one. diff --git a/ui/amcontext.go b/ui/amcontext.go index 8e0ff6c..e93de89 100644 --- a/ui/amcontext.go +++ b/ui/amcontext.go @@ -14,14 +14,17 @@ import ( "bytes" "net/http" + "git.erbosoft.com/amy/amsterdam/database" "github.com/CloudyKit/jet/v6" "github.com/gorilla/sessions" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" ) // AmContext is the interface for Amsterdam's wapper context that exposes the required functionality. type AmContext interface { + CurrentUser() *database.User RC() int OutputType() string Render(string) error @@ -44,6 +47,11 @@ type amContext struct { session *sessions.Session } +// CurrentUser returns the current user from the session. +func (c *amContext) CurrentUser() *database.User { + return c.session.Values["user"].(*database.User) +} + // RC returns the HTTP result code for the current operation. func (c *amContext) RC() int { return c.httprc @@ -143,6 +151,8 @@ func NewAmContext(ctxt echo.Context) (AmContext, error) { sess.Options = defoptions if sess.IsNew { SetupAmSession(sess) + } else { + log.Debugf("took the not-new-session path") } } return &rc, err diff --git a/ui/session_mgr.go b/ui/session_mgr.go index 6fa3897..90be4da 100644 --- a/ui/session_mgr.go +++ b/ui/session_mgr.go @@ -14,6 +14,7 @@ import ( "git.erbosoft.com/amy/amsterdam/config" "git.erbosoft.com/amy/amsterdam/database" "github.com/gorilla/sessions" + "github.com/quasoft/memstore" log "github.com/sirupsen/logrus" ) @@ -22,8 +23,7 @@ var SessionStore sessions.Store // SetupSessionManager sets up the session manager. func SetupSessionManager() { - log.Infof("Cookie key is %s", config.GlobalConfig.Rendering.CookieKey) - SessionStore = sessions.NewCookieStore([]byte(config.GlobalConfig.Rendering.CookieKey)) + SessionStore = memstore.NewMemStore([]byte(config.GlobalConfig.Rendering.CookieKey)) } // SetupAmSession sets up a newly created Amsterdam session. diff --git a/ui/views/frame.jet b/ui/views/frame.jet index e0ff981..47203dd 100644 --- a/ui/views/frame.jet +++ b/ui/views/frame.jet @@ -24,7 +24,7 @@