Skip to content

Commit

Permalink
extend storage testing, fix user storage
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmasek committed Jan 19, 2025
1 parent 89d107e commit dec6b8c
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 5 deletions.
27 changes: 22 additions & 5 deletions storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
_ "embed"
"encoding/json"
"errors"
"fmt"
"log"
"os"
"path/filepath"
Expand All @@ -17,6 +18,8 @@ import (
//go:embed create.sql
var CREATE_TABLE_QUERY string

const DUMMY_HASH = "$argon2id$v=19$m=65536,t=1,p=1$3/5E2tseeHN7AkROAl3Gvw$9a3DHFWwhpyuQp9/2t1VCESFVR/vxty/nQ1G55eeATA"

// Data needed to persist a new HealthCheck
type HealthCheckInput struct {
ServiceId string
Expand Down Expand Up @@ -156,6 +159,9 @@ func (s *SQLStorage) LatestTaskLog(taskName string) (*Task, error) {
}

func (s *SQLStorage) CreateUser(email string, password string) error {
if password == "" {
return fmt.Errorf("cannot create user with empty password")
}
hashedPassword, err := GenerateFromPassword(password)
if err != nil {
return err
Expand All @@ -167,21 +173,32 @@ func (s *SQLStorage) CreateUser(email string, password string) error {
return err
}

func (s *SQLStorage) ValidateUser(email string, password string) (*User, error) {
func (s *SQLStorage) ValidateUser(email string, inputPassword string) (*User, error) {
query := `SELECT password_hash FROM users WHERE email = ?`

// QueryRow is used because we expect at most one result
row := s.db.QueryRow(query, email)

var passwordHash string
err := row.Scan(&passwordHash)
var referenceHash string
err := row.Scan(&referenceHash)
if err != nil {
if err == sql.ErrNoRows {
// no user found
return nil, nil
// no user found, do a comparison to simulate same timing
// as if user found
_, err = ComparePasswordAndHash(inputPassword, DUMMY_HASH)
// typically nil,nil
return nil, err
}
return nil, err
}

match, err := ComparePasswordAndHash(inputPassword, referenceHash)
if err != nil {
return nil, err
}
if !match {
return nil, nil
}
return &User{email: email}, nil
}

Expand Down
64 changes: 64 additions & 0 deletions storage/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,67 @@ func TestTaskLog(t *testing.T) {
require.WithinDuration(t, now, gotTask.Timestamp, time.Second)
require.Equal(t, newStatus, gotTask.Status)
}

// Operations on empty database work.
func TestEmptyDb(t *testing.T) {
db := NewTestDb(t)
defer db.Close()

hash, _ := GenerateFromPassword("not-relevant")
t.Log(hash)
t.Log("--------------")

out, err := db.GetLatestHeartbeats("service", 10)
require.NoError(t, err)
require.Len(t, out, 0)

healthCheck, err := db.LatestHealthCheck("service")
require.NoError(t, err)
require.Nil(t, healthCheck)

healthChecks, err := db.LatestHealthChecks("service", 10)
require.NoError(t, err)
require.Len(t, healthChecks, 0)

task, err := db.LatestTaskLog("task")
require.NoError(t, err)
require.Nil(t, task)

task, err = db.LatestTaskLogWithStatus("task", "status")
require.NoError(t, err)
require.Nil(t, task)

services, err := db.ListServices()
require.NoError(t, err)
require.Len(t, services, 0)

user, err := db.ValidateUser("email", "password")
require.NoError(t, err)
require.Nil(t, user)
}

func TestUserFlow(t *testing.T) {
db := NewTestDb(t)
defer db.Close()

// happy path
err := db.CreateUser("cj@google.com", "h4xor")
require.NoError(t, err)
user, err := db.ValidateUser("cj@google.com", "h4xor")
require.NoError(t, err)
require.NotNil(t, user)
require.Equal(t, "cj@google.com", user.email)

// with invalid password
user, err = db.ValidateUser("cj@google.com", "idk")
require.NoError(t, err)
require.Nil(t, user)

// already existing email
err = db.CreateUser("cj@google.com", "any")
require.Error(t, err)

// empty password
err = db.CreateUser("don.john.von.lon@google.com", "")
require.Error(t, err)
}

0 comments on commit dec6b8c

Please sign in to comment.