89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package auth
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestSessionPersistsAcrossReopen(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "sessions.db")
|
|
|
|
store, err := NewSessionStore(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
token, err := store.Create("urania")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Reopen the same file: a fresh process must still see the session.
|
|
reopened, err := NewSessionStore(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sess, ok := reopened.GetByToken(token)
|
|
if !ok || sess.Username != "urania" {
|
|
t.Fatalf("session lost after reopen: got %+v ok=%v", sess, ok)
|
|
}
|
|
}
|
|
|
|
func TestExpiredSessionRejected(t *testing.T) {
|
|
store, err := NewSessionStore(filepath.Join(t.TempDir(), "sessions.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Write a row that expired an hour ago, bypassing Create's TTL.
|
|
_, err = store.db.Exec(
|
|
`INSERT INTO sessions (token, username, expires_at) VALUES (?, ?, ?)`,
|
|
"stale", "urania", time.Now().Add(-time.Hour).Unix(),
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := store.GetByToken("stale"); ok {
|
|
t.Fatal("expired session was accepted")
|
|
}
|
|
// Lazy cleanup should have deleted the row.
|
|
var n int
|
|
store.db.QueryRow(`SELECT count(*) FROM sessions WHERE token = ?`, "stale").Scan(&n)
|
|
if n != 0 {
|
|
t.Fatalf("expired row not cleaned up: %d rows remain", n)
|
|
}
|
|
}
|
|
|
|
func TestDeleteInvalidatesSession(t *testing.T) {
|
|
store, err := NewSessionStore(filepath.Join(t.TempDir(), "sessions.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
token, err := store.Create("urania")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := store.GetByToken(token); !ok {
|
|
t.Fatal("session should exist before logout")
|
|
}
|
|
if err := store.Delete(token); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := store.GetByToken(token); ok {
|
|
t.Fatal("session still valid after logout")
|
|
}
|
|
// Deleting an unknown/already-deleted token is a no-op, not an error.
|
|
if err := store.Delete(token); err != nil {
|
|
t.Errorf("deleting unknown token should be a no-op, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUnknownTokenRejected(t *testing.T) {
|
|
store, err := NewSessionStore(filepath.Join(t.TempDir(), "sessions.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := store.GetByToken("nope"); ok {
|
|
t.Fatal("unknown token was accepted")
|
|
}
|
|
}
|