From 61265f790e3c32accb3ce844422bb6b23db7fe8a Mon Sep 17 00:00:00 2001
From: sinanmohd <sinan@sinanmohd.com>
Date: Sat, 16 Mar 2024 11:32:54 +0530
Subject: validator: init

---
 api/login.go  | 15 +++++++++++----
 db/account.go | 33 ++++++++++++++++++++++++++-------
 db/main.go    |  5 ++++-
 go.mod        | 10 +++++++++-
 go.sum        | 30 ++++++++++++++++++++++++++++--
 5 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/api/login.go b/api/login.go
index ef2195e..ef43304 100644
--- a/api/login.go
+++ b/api/login.go
@@ -4,17 +4,19 @@ import (
 	"encoding/json"
 	"net/http"
 
+	"github.com/go-playground/validator/v10"
 	redqdb "sinanmohd.com/redq/db"
 )
 
 type loginAPI struct {
-	db   *redqdb.SafeDB
-	req  *RequestLogin
-	resp *ResponseLogin
+	db       *redqdb.SafeDB
+	validate *validator.Validate
+	req      *RequestLogin
+	resp     *ResponseLogin
 }
 
 type RequestLogin struct {
-	Account *redqdb.Account
+	Account *redqdb.Account `validate:"required"`
 }
 
 type ResponseLogin struct {
@@ -24,6 +26,7 @@ type ResponseLogin struct {
 func newLogin(db *redqdb.SafeDB) *loginAPI {
 	a := &loginAPI{}
 	a.db = db
+	a.validate = validator.New(validator.WithRequiredStructEnabled())
 
 	return a
 }
@@ -31,7 +34,11 @@ func newLogin(db *redqdb.SafeDB) *loginAPI {
 func (a *loginAPI) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
 	a.req = &RequestLogin{}
 	a.resp = &ResponseLogin{}
+
 	err := unmarshal(r.Body, a.req)
+	if err == nil {
+		err = a.validate.Struct(a.req)
+	}
 	if err != nil {
 		handleError(err, rw, http.StatusUnprocessableEntity)
 		return
diff --git a/db/account.go b/db/account.go
index c7f76bf..507060e 100644
--- a/db/account.go
+++ b/db/account.go
@@ -1,18 +1,22 @@
 package db
 
-import "errors"
+import (
+	"errors"
+	"fmt"
+	"log"
+)
 
 type Account struct {
-	UserName string
-	PassHash string `json:",omitempty"`
+	UserName string `validate:"required,alphanum,max=64"`
+	PassHash string `json:",omitempty" validate:"required,min=10,max=128"`
 
 	Info *Login
 }
 
 type Login struct {
 	id                  uint
-	Level               uint
-	FirstName, LastName string
+	Level               uint   `validate:"gte=0,lte=100"`
+	FirstName, LastName string `validate:"required,alphanumunicode"`
 	Bearer              *Bearer
 }
 
@@ -29,10 +33,18 @@ func (ac *Account) CreateAccount(safe *SafeDB) error {
 		VALUES (NULL, ?, ?, ?, ?, ?);
 	`
 
+	err := safe.validate.Struct(ac)
+	if err == nil {
+		err = safe.validate.Struct(ac.Login)
+	}
+	if err != nil {
+		return err
+	}
+
 	safe.mu.Lock()
 	defer safe.mu.Unlock()
 
-	_, err := safe.db.Exec(
+	_, err = safe.db.Exec(
 		sqlStatement,
 		ac.UserName,
 		ToBlake3(ac.PassHash),
@@ -52,6 +64,13 @@ func (ac *Account) Login(safe *SafeDB) error {
 		WHERE Accounts.UserName = ?
 	`
 
+	err := safe.validate.Struct(ac)
+	fmt.Println(ac.PassHash, ac.UserName)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+
 	ac.Info = &Login{}
 	ac.Info.Bearer = &Bearer{}
 	safe.mu.Lock()
@@ -59,7 +78,7 @@ func (ac *Account) Login(safe *SafeDB) error {
 	safe.mu.Unlock()
 
 	var PassHash string
-	err := row.Scan(
+	err = row.Scan(
 		&ac.Info.id,
 		&PassHash,
 		&ac.Info.FirstName,
diff --git a/db/main.go b/db/main.go
index 801cb65..fcfbf11 100644
--- a/db/main.go
+++ b/db/main.go
@@ -6,11 +6,13 @@ import (
 	"path/filepath"
 	"sync"
 
+	"github.com/go-playground/validator/v10"
 	_ "github.com/mattn/go-sqlite3"
 )
 
 type SafeDB struct {
-	mu sync.Mutex
+	mu       sync.Mutex
+	validate *validator.Validate
 
 	path string
 	db   *sql.DB
@@ -70,5 +72,6 @@ func NewSafeDB() (*SafeDB, error) {
 		return nil, err
 	}
 
+	safe.validate = validator.New(validator.WithRequiredStructEnabled())
 	return safe, nil
 }
diff --git a/go.mod b/go.mod
index c18c5e2..e856572 100644
--- a/go.mod
+++ b/go.mod
@@ -3,11 +3,19 @@ module sinanmohd.com/redq
 go 1.22.0
 
 require (
+	github.com/go-playground/validator/v10 v10.19.0
 	github.com/mattn/go-sqlite3 v1.14.22
 	lukechampine.com/blake3 v1.2.1
 )
 
 require (
+	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
 	github.com/klauspost/cpuid/v2 v2.2.4 // indirect
-	golang.org/x/sys v0.8.0 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	golang.org/x/crypto v0.19.0 // indirect
+	golang.org/x/net v0.21.0 // indirect
+	golang.org/x/sys v0.17.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
 )
diff --git a/go.sum b/go.sum
index b2786bb..62ae8ea 100644
--- a/go.sum
+++ b/go.sum
@@ -1,9 +1,35 @@
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
+github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
 github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
 github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
 github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
 lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
-- 
cgit v1.2.3