From aa7c3eb23c31fa6051ee0caaebea47c8225d55a4 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 29 Apr 2023 01:11:04 -0500 Subject: add endpoint.go --- db/session.go | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 db/session.go (limited to 'db/session.go') diff --git a/db/session.go b/db/session.go new file mode 100644 index 0000000..bddedda --- /dev/null +++ b/db/session.go @@ -0,0 +1,127 @@ +package db + +import ( + "database/sql" + "crypto/rand" + "encoding/base64" + "errors" + "time" +) + + +func (p *Phlox) CreateSession(user User) (Session, error) { + bytes := make([]byte, 32) + _, err := rand.Read(bytes) + if err != nil { + return Session{}, err + } + + sessionid := base64.StdEncoding.EncodeToString(bytes) + userid := user.Id + now := time.Now().UTC() + nowStr := now.Format(time.RFC3339) + + _, err = p.db.Exec( + "insert into sessions (sessionid, userid, created, modified) values (?, ?, ?, ?);", + sessionid, + userid, + nowStr, nowStr, + ) + if err != nil { + return Session{}, err + } + + return Session{ + Id: sessionid, + UserId: userid, + Created: now, + Modified: now, + }, nil +} + + +func (p *Phlox) DeleteSession(session Session) error { + _, err := p.db.Exec("delete from sessions where sessionid = ?;", session.Id) + return err +} + + +func extractSession(s Scanner) (Session, error) { + var ( + session Session + createdStr string + modifiedStr string + ) + + // scan + err := s.Scan(&session.Id, &session.UserId, &createdStr, &modifiedStr) + if err != nil { + return Session{}, err + } + + // parse times + session.Created, err = time.Parse(time.RFC3339, createdStr) + if err != nil { + return Session{}, err + } + session.Modified, err = time.Parse(time.RFC3339, modifiedStr) + if err != nil { + return Session{}, err + } + + return session, nil +} + + +func (p *Phlox) CheckSession(session Session) (bool, error) { + row := p.db.QueryRow("select * from sessions where sessionid = ?", session.Id) + session, err := extractSession(row) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + // no row returned, so invalid session + return false, nil + } else { + // some other error + return false, err + } + } + + return true, nil +} + + +func (p *Phlox) TouchSession(session Session) error { + now := time.Now().UTC().Format(time.RFC3339) + _, err := p.db.Exec( + "update sessions set modified = ? where sessionid = ?;", + now, session.Id, + ) + return err +} + + +func (p *Phlox) CleanSessions(maxIdle time.Duration) error { + expire := time.Now().UTC().Add(-maxIdle).Format(time.RFC3339) + _, err := p.db.Exec("delete from sessions where modified < ?;", expire) + return err +} + + +func (p *Phlox) AllSessions() ([]Session, error) { + sessions := make([]Session, 0) + rows, err := p.db.Query("select * from sessions;") + if err != nil { + return sessions, err + } + defer rows.Close() + + for rows.Next() { + session, err := extractSession(rows) + if err != nil { + return sessions, err + } + sessions = append(sessions, session) + } + + return sessions, nil +} -- cgit v1.2.1