package main import ( "database/sql" "testing" _ "github.com/mattn/go-sqlite3" "golang.org/x/crypto/bcrypt" ) var passwords = []struct { description string username string password string }{ {"basic", "testuser", "mypassword"}, {"password-characterset", "testuser", "mypSDFäÖ$🚧"}, {"user-characterset", "mypSDFäÖ$🚧", "mypassword"}, } func TestRegister(t *testing.T) { for _, p := range passwords { t.Run(p.description, func(t *testing.T) { db, _ := emptyDB(t) err := MigrateToLatest(db) if err != nil { t.Fatalf("Could not migrate test database: %v", err) } err = Transaction(db, func(tx *sql.Tx) error { return Register(tx, p.username, p.password) }) if err != nil { t.Fatalf("Could not register user: %v", err) } row := db.QueryRow( `SELECT password_bcrypt FROM users WHERE username=?;`, p.username, ) var hash []byte err = row.Scan(&hash) if err != nil { t.Fatalf("Could not scan for password: %v", err) } err = bcrypt.CompareHashAndPassword(hash, []byte(p.password)) if err != nil { t.Fatalf("Password not valid after registration: %v", err) } err = bcrypt.CompareHashAndPassword(hash, []byte("")) if err == nil { t.Fatalf("Empty password is valid after registration.") } }) } } func TestAuthenticate(t *testing.T) { for _, p := range passwords { t.Run(p.description, func(t *testing.T) { db, _ := emptyDB(t) err := MigrateToLatest(db) if err != nil { t.Fatalf("Could not execute function to test: %v", err) } hash, err := bcrypt.GenerateFromPassword([]byte(p.password), bcryptCost) if err != nil { t.Fatalf("Failed to generate test password hash: %v", err) } _, err = db.Exec( `INSERT INTO users (username, password_bcrypt) VALUES(?, ?);`, p.username, hash, ) if err != nil { t.Fatalf("Failed to insert password hash: %v", err) } err = Transaction(db, func(tx *sql.Tx) error { return Authenticate(tx, p.username, p.password) }) if err != nil { t.Fatalf("Failed to authenticate: %v", err) } }) } } func TestRegisterAuthenticate(t *testing.T) { for _, p := range passwords { t.Run(p.description, func(t *testing.T) { db, _ := emptyDB(t) err := MigrateToLatest(db) if err != nil { t.Fatalf("Could not execute function to test: %v", err) } err = Transaction(db, func(tx *sql.Tx) error { return Register(tx, p.username, p.password) }) if err != nil { t.Fatalf("Could not register user: %v", err) } err = Transaction(db, func(tx *sql.Tx) error { return Authenticate(tx, p.username, p.password) }) if err != nil { t.Fatalf("Failed to authenticate: %v", err) } }) } }