11package models
22
33import (
4+ "fmt"
45 "errors"
56 "github.com/go-redis/redis"
67 "golang.org/x/crypto/bcrypt"
@@ -11,18 +12,65 @@ var (
1112 ErrInvalidLogin = errors .New ("invalid login" )
1213)
1314
14- func AuthenticateUser (username , password string ) error {
15- hash , err := client .Get ("user:" + username ).Bytes ()
16- if err == redis .Nil {
17- return ErrUserNotFound
18- } else if err != nil {
15+ type User struct {
16+ key string
17+ }
18+
19+ func NewUser (username string , hash []byte ) (* User , error ) {
20+ id , err := client .Incr ("user:next-id" ).Result ()
21+ if err != nil {
22+ return nil , err
23+ }
24+ key := fmt .Sprintf ("user:%d" , id )
25+ pipe := client .Pipeline ()
26+ pipe .HSet (key , "id" , id )
27+ pipe .HSet (key , "username" , username )
28+ pipe .HSet (key , "hash" , hash )
29+ pipe .HSet ("user:by-username" , username , id )
30+ _ , err = pipe .Exec ()
31+ if err != nil {
32+ return nil , err
33+ }
34+ return & User {key }, nil
35+ }
36+
37+ func (user * User ) GetUsername () (string , error ) {
38+ return client .HGet (user .key , "username" ).Result ()
39+ }
40+
41+ func (user * User ) GetHash () ([]byte , error ) {
42+ return client .HGet (user .key , "hash" ).Bytes ()
43+ }
44+
45+ func (user * User ) Authenticate (password string ) error {
46+ hash , err := user .GetHash ()
47+ if err != nil {
1948 return err
2049 }
2150 err = bcrypt .CompareHashAndPassword (hash , []byte (password ))
22- if err != nil {
51+ if err == bcrypt . ErrMismatchedHashAndPassword {
2352 return ErrInvalidLogin
2453 }
25- return nil
54+ return err
55+ }
56+
57+ func GetUserByUsername (username string ) (* User , error ) {
58+ id , err := client .HGet ("user:by-username" , username ).Int64 ()
59+ if err == redis .Nil {
60+ return nil , ErrUserNotFound
61+ } else if err != nil {
62+ return nil , err
63+ }
64+ key := fmt .Sprintf ("user:%d" , id )
65+ return & User {key }, nil
66+ }
67+
68+ func AuthenticateUser (username , password string ) error {
69+ user , err := GetUserByUsername (username )
70+ if err != nil {
71+ return err
72+ }
73+ return user .Authenticate (password )
2674}
2775
2876func RegisterUser (username , password string ) error {
@@ -31,5 +79,6 @@ func RegisterUser(username, password string) error {
3179 if err != nil {
3280 return err
3381 }
34- return client .Set ("user:" + username , hash , 0 ).Err ()
82+ _ , err = NewUser (username , hash )
83+ return err
3584}
0 commit comments