-
Notifications
You must be signed in to change notification settings - Fork 1
/
user.go
149 lines (118 loc) · 3.75 KB
/
user.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package models
import (
"fmt"
"os"
"strings"
"time"
jwt "github.com/dgrijalva/jwt-go"
"github.com/jinzhu/gorm"
"golang.org/x/crypto/bcrypt"
"github.com/andela-sjames/go-bucketlist-api/utils"
)
// User field (Model) defined
type User struct {
gorm.Model
Email string `json:"email"`
Password string `json:"password"`
Token string `json:"token"`
Bucketlist []Bucketlist `json:"bucketlist,omitempty"`
}
// Token JWT claims struct
type Token struct {
UserID uint
Email string
jwt.StandardClaims
}
// Validate incoming user details...
func (user *User) Validate() (map[string]interface{}, bool) {
if !strings.Contains(user.Email, "@") {
return utils.Message(false, "Email address is required"), false
}
if len(user.Password) < 6 {
return utils.Message(false, "Password is required"), false
}
//Email must be unique
temp := &User{}
//check for errors and duplicate emails
err := GetDB().Table("users").Where("email = ?", user.Email).First(temp).Error
if err != nil && err != gorm.ErrRecordNotFound {
return utils.Message(false, "Connection error. Please retry"), false
}
if temp.Email != "" {
return utils.Message(false, "Email address already in use by another user."), false
}
return utils.Message(false, "Requirement passed"), true
}
// Create a user object
func (user *User) Create() map[string]interface{} {
fmt.Println(user, "the user object")
if resp, ok := user.Validate(); !ok {
return resp
}
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
user.Password = string(hashedPassword)
GetDB().Create(user)
if user.ID <= 0 {
return utils.Message(false, "Failed to create user, connection error.")
}
//Create new JWT token for the newly registered user
claims := GenerateUserClaims(user.ID, user.Email)
token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), claims)
tokenString, _ := token.SignedString([]byte(os.Getenv("PASSPHRASE")))
user.Token = tokenString
user.Password = "" //delete password
response := utils.Message(true, "user has been created")
response["user"] = user
return response
}
// Login function defined
func Login(email, password string) map[string]interface{} {
user := &User{}
err := GetDB().Table("users").Where("email = ?", email).First(user).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return utils.Message(false, "Email address not found")
}
return utils.Message(false, "Connection error. Please retry")
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err != nil && err == bcrypt.ErrMismatchedHashAndPassword { //Password does not match!
return utils.Message(false, "Invalid login credentials. Please try again")
}
//Worked! Logged In
user.Password = ""
//Create JWT token
claims := GenerateUserClaims(user.ID, email)
token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), claims)
tokenString, _ := token.SignedString([]byte(os.Getenv("PASSPHRASE")))
user.Token = tokenString //Store the token in the response
resp := utils.Message(true, "Logged In")
resp["user"] = user
return resp
}
// GetUser function defined to retrieve a user by id
func GetUser(u uint) *User {
user := &User{}
GetDB().Table("users").Where("id = ?", u).First(user)
if user.Email == "" { //User not found!
return nil
}
user.Password = ""
return user
}
// GenerateUserClaims function defined get new claim
func GenerateUserClaims(user uint, email string) *Token {
//Create new JWT token for the newly registered user/returnin users
expirationTime := time.Now().Add(24 * time.Hour)
claims := &Token{
user,
email,
jwt.StandardClaims{
Audience: "devs",
IssuedAt: time.Now().Unix(),
ExpiresAt: expirationTime.Unix(),
Issuer: "gobucketlistapi",
},
}
return claims
}