diff options
| author | Alexander Kavon <me+git@alexkavon.com> | 2024-01-22 00:37:21 -0500 |
|---|---|---|
| committer | Alexander Kavon <me+git@alexkavon.com> | 2024-01-22 00:37:21 -0500 |
| commit | b3c1584ec4a5bcba84a10cd9b6501d0e978c2457 (patch) | |
| tree | 87fa8e9f21fd07b1a679a2ed05a3c931a85212cb | |
| parent | d6fdb3a460eb228d7b1cd7870b7ef6c8c7391f0b (diff) | |
update db adapter, server, routes, and user model to be sqlboiler compatible
| -rw-r--r-- | src/db/db.go | 47 | ||||
| -rw-r--r-- | src/server/server.go | 4 | ||||
| -rw-r--r-- | src/user/routes.go | 26 | ||||
| -rw-r--r-- | src/user/secret.go (renamed from src/user/user.go) | 45 |
4 files changed, 40 insertions, 82 deletions
diff --git a/src/db/db.go b/src/db/db.go index d74c874..198b2be 100644 --- a/src/db/db.go +++ b/src/db/db.go @@ -2,23 +2,20 @@ package db import ( "context" - "fmt" + "database/sql" "log" - "strings" - "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" + "github.com/jackc/pgx/v5/stdlib" "gitlab.com/alexkavon/newsstand/src/conf" ) -type Database struct { - p *pgxpool.Pool +type Db struct { + pool *pgxpool.Pool } -type DbValues pgx.NamedArgs - -func NewDb(config *conf.Conf) *Database { +func NewDb(config *conf.Conf) *Db { pool, err := pgxpool.New(context.Background(), config.Db.Url) if err != nil { log.Fatal(err) @@ -30,36 +27,18 @@ func NewDb(config *conf.Conf) *Database { log.Fatal(err) } log.Println("Database connection pool created.", testquery) - return &Database{ - p: pool, - } + return &Db{pool} + } -func (d *Database) InsertTable(table string, columns []string, values DbValues) error { - columnstr := stringifyColumns(columns, "") - valuesstr := stringifyColumns(columns, "@") - query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s) RETURNING *", table, columnstr, valuesstr) - log.Println(query, values) - // Convert DbValues to pgx.NamedArgs type to use NamedArgs type features - namedArgs := pgx.NamedArgs(values) - // TODO Use r.Context() from HTTP Request? - ctx := context.Background() - row, err := d.p.Exec(ctx, query, namedArgs) - if err != nil { - return err - } - log.Println("Row", row) - return nil +func (d *Db) Conn() *pgxpool.Pool { + return d.pool } -func (d *Database) Close() { - d.p.Close() +func (d *Db) ToSqlDb() *sql.DB { + return stdlib.OpenDBFromPool(d.pool) } -func stringifyColumns(columns []string, prefix string) string { - ncolumns := []string{} - for _, v := range columns { - ncolumns = append(ncolumns, fmt.Sprintf("%s%s", prefix, v)) - } - return strings.Join(ncolumns, ", ") +func (d *Db) Close() { + d.pool.Close() } diff --git a/src/server/server.go b/src/server/server.go index d883d3f..cd3e6b6 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -10,12 +10,12 @@ import ( type Server struct { Router *chi.Mux - Db *db.Database + Db *db.Db Config *conf.Conf Ui Ui } -func NewServer(config *conf.Conf, database *db.Database) *Server { +func NewServer(config *conf.Conf, database *db.Db) *Server { return &Server{ Router: NewRouter(config), Db: database, diff --git a/src/user/routes.go b/src/user/routes.go index d8c8d43..b163fb7 100644 --- a/src/user/routes.go +++ b/src/user/routes.go @@ -5,6 +5,8 @@ import ( "net/http" "github.com/go-playground/validator/v10" + "github.com/volatiletech/sqlboiler/v4/boil" + "gitlab.com/alexkavon/newsstand/src/models" "gitlab.com/alexkavon/newsstand/src/server" "gitlab.com/alexkavon/newsstand/src/sessions" ) @@ -64,33 +66,33 @@ func Store(s *server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { r.ParseForm() - user := &User{ - Db: s.Db, - Username: r.PostFormValue("username"), - Secret: r.PostFormValue("secret"), - Email: r.PostFormValue("email"), - } + var user models.User + user.Username = r.PostFormValue("username") + user.Secret = r.PostFormValue("secret") + user.Email = r.PostFormValue("email") // Validate User Input v := validator.New() err := v.Struct(user) if err != nil { - log.Println("Validator failed", err.(validator.ValidationErrors)) + log.Fatal("Validator failed", err.(validator.ValidationErrors)) } // Hash secret - err = user.HashSecret() + secret := &Secret{Raw: user.Secret} + err = secret.HashSecret() if err != nil { - log.Println("Hash failure", err) + log.Fatal("Hash failure", err) } + user.Secret = secret.Hash() // Store user - err = user.Insert() + err = user.Insert(r.Context(), s.Db.ToSqlDb(), boil.Infer()) if err != nil { - log.Println("Insert Error", err) + log.Fatal("Insert Error", err) } // Send email validation // Create cookie session - sessions.NewSession(w, sessions.SessionValues{"uid": user.Id, "username": user.Username}) + sessions.NewSession(w, sessions.SessionValues{"uid": user.ID, "username": user.Username}) // Redirect to user profile http.Redirect(w, r, "/u/me", http.StatusSeeOther) } diff --git a/src/user/user.go b/src/user/secret.go index d9fca6b..55b8bc6 100644 --- a/src/user/user.go +++ b/src/user/secret.go @@ -4,43 +4,16 @@ import ( "crypto/rand" "encoding/base64" "fmt" - "time" - "gitlab.com/alexkavon/newsstand/src/db" "golang.org/x/crypto/argon2" ) -type User struct { - Id int64 - Username string `validate:"required,max=50"` - Secret string `validate:"required,min=8,max=128"` - Email string `validate:"required,email"` - Karma uint64 - UpdatedAt time.Time - CreatedAt time.Time - hash string - Db *db.Database +type Secret struct { + Raw string + hash string } -func NewUser(d *db.Database) *User { - return &User{ - Db: d, - } -} - -func (u *User) Insert() error { - err := u.Db.InsertTable( - "users", - []string{"username", "secret", "email"}, - db.DbValues{"username": u.Username, "secret": string(u.hash), "email": u.Email}, - ) - if err != nil { - return err - } - return nil -} - -func (u *User) HashSecret() error { +func (s Secret) HashSecret() error { hashconf := &struct { memory uint32 iterations uint32 @@ -55,7 +28,7 @@ func (u *User) HashSecret() error { } hash := argon2.IDKey( - []byte(u.Secret), + []byte(s.Raw), salt, hashconf.iterations, hashconf.memory, @@ -73,6 +46,10 @@ func (u *User) HashSecret() error { b64Salt, b64Hash, ) - u.hash = encodedHash - return nil + s.hash = encodedHash + return err +} + +func (s *Secret) Hash() string { + return s.hash } |
