From 3c145d66af5ba845839fef907e34ae623abe2881 Mon Sep 17 00:00:00 2001 From: James Tombleson Date: Thu, 21 Mar 2024 22:41:52 -0700 Subject: [PATCH] the table accepts my record and I can rebuild it without a ORM! --- api/repositories/users.go | 74 +++++++++++++++++++++++++++++----- api/repositories/users_test.go | 41 +++++++++++++++++-- 2 files changed, 100 insertions(+), 15 deletions(-) diff --git a/api/repositories/users.go b/api/repositories/users.go index c629fcc..8d52e30 100644 --- a/api/repositories/users.go +++ b/api/repositories/users.go @@ -2,9 +2,9 @@ package repositories import ( "database/sql" - "go-cook/api/models" - "errors" "fmt" + "go-cook/api/models" + "time" "github.com/huandu/go-sqlbuilder" "golang.org/x/crypto/bcrypt" @@ -25,25 +25,77 @@ func (ur UserRepository) GetByName(name string) (models.UserModel, error) { builder := sqlbuilder.NewSelectBuilder() builder.Select("*").From("users").Where( builder.E("Name", name), - ); + ) + query, args := builder.Build() + rows, err := ur.connection.Query(query, args...) + if err != nil { + return models.UserModel{}, err + } - return models.UserModel{}, errors.New("user was not found") + return ur.processRows(rows)[0], nil } -func (ur UserRepository) NewUser(name string, password string) (int, error) { +func (ur UserRepository) NewUser(name, password string) (int64, error) { passwordBytes := []byte(password) hash, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost) if err != nil { return 0, err } - fmt.Println(hash) - query := sqlbuilder.NewInsertBuilder() - query.InsertInto("users") - query.Cols("name", "hash") - query.Values(name, string(hash)) - ur.connection.Query(query.Build()) + dt := time.Now() + queryBuilder := sqlbuilder.NewInsertBuilder() + queryBuilder.InsertInto("users") + queryBuilder.Cols("Name", "Hash", "LastUpdated", "CreatedAt") + queryBuilder.Values(name, string(hash), dt, dt) + query, args := queryBuilder.Build() + + _, err = ur.connection.Exec(query, args...) + if err != nil { + return 0, err + } return 1, nil } + +// If the hash matches what we have in the database, an error will not be returned. +// If the user does not exist or the hash does not match, an error will be returned +func (ur UserRepository) CheckUserHash(name, password string) error { + record, err := ur.GetByName(name) + if err != nil { + return err + } + + err = bcrypt.CompareHashAndPassword([]byte(record.Hash), []byte(password)) + if err != nil { + return err + } + + return nil +} + +func (ur UserRepository) processRows(rows *sql.Rows) []models.UserModel { + items := []models.UserModel{} + + for rows.Next() { + var id int + var name string + var hash string + var createdAt time.Time + var lastUpdated time.Time + err := rows.Scan(&id, &name, &hash, &createdAt, &lastUpdated) + if err != nil { + fmt.Println(err) + } + + items = append(items, models.UserModel{ + Id: id, + Name: name, + Hash: hash, + CreatedAt: createdAt, + LastUpdated: lastUpdated, + }) + } + + return items +} diff --git a/api/repositories/users_test.go b/api/repositories/users_test.go index f72d491..c86cd89 100644 --- a/api/repositories/users_test.go +++ b/api/repositories/users_test.go @@ -1,7 +1,40 @@ package repositories_test -import "testing" +import ( + "database/sql" + "go-cook/api/repositories" + "log" + "testing" -func TestNewUser(t *testing.T) { - -} \ No newline at end of file + _ "github.com/glebarez/go-sqlite" +) + +func TestCanCreateNewUser(t *testing.T) { + db, err := sql.Open("sqlite", "../../gocook.db") + if err != nil { + log.Println("unable to open connection") + t.FailNow() + } + defer db.Close() + + repo := repositories.NewUserRepository(db) + updated, err := repo.NewUser("testing", "NotSecure") + if err != nil { + log.Println(err) + t.FailNow() + } + log.Println(updated) +} + +func TestCanFindUserInTable(t *testing.T) { + db, err := sql.Open("sqlite", "../../gocook.db") + if err != nil { + log.Println("unable to open connection") + t.FailNow() + } + defer db.Close() + + repo := repositories.NewUserRepository(db) + repo.GetByName("testing") + +}