diff options
Diffstat (limited to 'src/user/user.go')
| -rw-r--r-- | src/user/user.go | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/src/user/user.go b/src/user/user.go index 83e39e3..e35c7c5 100644 --- a/src/user/user.go +++ b/src/user/user.go @@ -1,18 +1,73 @@ package user import ( - "errors" + "crypto/rand" + "encoding/base64" + "fmt" "time" + + "github.com/jackc/pgx/v5" + "gitlab.com/alexkavon/newsstand/src/db" + "golang.org/x/crypto/argon2" ) type User struct { Id int64 - Username string + 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 +} + +func (u *User) Insert() error { + err := u.Db.InsertTable( + "users", + []string{"username", "secret", "email"}, + pgx.NamedArgs{"username": u.Username, "secret": string(u.hash), "email": u.Email}, + ) + if err != nil { + return err + } + return nil } -func NewUser(username, secret string) error { - return errors.New("Not Implemented") +func (u *User) HashSecret() error { + hashconf := &struct { + memory uint32 + iterations uint32 + parallelism uint8 + keyLength uint32 + saltLength uint32 + }{64 * 1024, 3, 2, 12, 16} + salt := make([]byte, hashconf.saltLength) + _, err := rand.Read(salt) + if err != nil { + return err + } + + hash := argon2.IDKey( + []byte(u.Secret), + salt, + hashconf.iterations, + hashconf.memory, + hashconf.parallelism, + hashconf.keyLength, + ) + b64Salt := base64.RawStdEncoding.EncodeToString(salt) + b64Hash := base64.RawStdEncoding.EncodeToString(hash) + encodedHash := fmt.Sprintf( + "$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", + argon2.Version, + hashconf.memory, + hashconf.iterations, + hashconf.parallelism, + b64Salt, + b64Hash, + ) + u.hash = encodedHash + return nil } |
