/
users.go
361 lines (318 loc) · 8.47 KB
/
users.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
package database
import (
"database/sql"
"errors"
"log"
)
// GetRegisteredUsers retrieves the registered users from db
func (d *Database) GetRegisteredUsers(Limit int, Offset int) []*User {
var users = make([]*User, 0)
rows, err := d.db.Query(
`
SELECT id, name, email, type, avatar, verified, country, company, job_title
FROM users
WHERE email IS NOT NULL
ORDER BY created_date
LIMIT $1
OFFSET $2
`,
Limit,
Offset,
)
if err == nil {
defer rows.Close()
for rows.Next() {
var w User
var UserEmail sql.NullString
var UserCountry sql.NullString
var UserCompany sql.NullString
var UserJobTitle sql.NullString
if err := rows.Scan(
&w.UserID,
&w.UserName,
&UserEmail,
&w.UserType,
&w.UserAvatar,
&w.Verified,
&UserCountry,
&UserCompany,
&UserJobTitle,
); err != nil {
log.Println(err)
} else {
w.UserEmail = UserEmail.String
w.Country = UserCountry.String
w.Company = UserCompany.String
w.JobTitle = UserJobTitle.String
users = append(users, &w)
}
}
} else {
log.Println(err)
}
return users
}
// GetUser gets a user from db by ID
func (d *Database) GetUser(UserID string) (*User, error) {
var w User
var UserEmail sql.NullString
var UserCountry sql.NullString
var UserLocale sql.NullString
var UserCompany sql.NullString
var UserJobTitle sql.NullString
e := d.db.QueryRow(
"SELECT id, name, email, type, avatar, verified, notifications_enabled, country, locale, company, job_title FROM users WHERE id = $1",
UserID,
).Scan(
&w.UserID,
&w.UserName,
&UserEmail,
&w.UserType,
&w.UserAvatar,
&w.Verified,
&w.NotificationsEnabled,
&UserCountry,
&UserLocale,
&UserCompany,
&UserJobTitle,
)
if e != nil {
log.Println(e)
return nil, errors.New("user not found")
}
w.UserEmail = UserEmail.String
w.Country = UserCountry.String
w.Locale = UserLocale.String
w.Company = UserCompany.String
w.JobTitle = UserJobTitle.String
return &w, nil
}
// GetUserByEmail gets the user by email
func (d *Database) GetUserByEmail(UserEmail string) (*User, error) {
var w User
e := d.db.QueryRow(
"SELECT id, name, email, type, verified FROM users WHERE email = $1",
UserEmail,
).Scan(
&w.UserID,
&w.UserName,
&w.UserEmail,
&w.UserType,
&w.Verified,
)
if e != nil {
log.Println(e)
return nil, errors.New("user email not found")
}
return &w, nil
}
// AuthUser attempts to authenticate the user
func (d *Database) AuthUser(UserEmail string, UserPassword string) (*User, error) {
var w User
var passHash string
var UserLocale sql.NullString
e := d.db.QueryRow(
`SELECT id, name, email, type, password, avatar, verified, notifications_enabled, locale FROM users WHERE email = $1`,
UserEmail,
).Scan(
&w.UserID,
&w.UserName,
&w.UserEmail,
&w.UserType,
&passHash,
&w.UserAvatar,
&w.Verified,
&w.NotificationsEnabled,
&UserLocale,
)
if e != nil {
log.Println(e)
return nil, errors.New("user not found")
}
if !ComparePasswords(passHash, []byte(UserPassword)) {
return nil, errors.New("password invalid")
}
w.Locale = UserLocale.String
return &w, nil
}
// CreateUserGuest adds a new guest user to the db
func (d *Database) CreateUserGuest(UserName string) (*User, error) {
var UserID string
e := d.db.QueryRow(`INSERT INTO users (name) VALUES ($1) RETURNING id`, UserName).Scan(&UserID)
if e != nil {
log.Println(e)
return nil, errors.New("unable to create new user")
}
return &User{UserID: UserID, UserName: UserName, UserAvatar: "identicon", NotificationsEnabled: true, Locale: "en"}, nil
}
// CreateUserRegistered adds a new registered user to the db
func (d *Database) CreateUserRegistered(UserName string, UserEmail string, UserPassword string, ActiveUserID string) (NewUser *User, VerifyID string, RegisterErr error) {
hashedPassword, hashErr := HashAndSalt([]byte(UserPassword))
if hashErr != nil {
return nil, "", hashErr
}
var UserID string
var verifyID string
UserType := "CORPORAL"
UserAvatar := "identicon"
if ActiveUserID != "" {
e := d.db.QueryRow(
`SELECT userId, verifyId FROM register_existing_user($1, $2, $3, $4, $5);`,
ActiveUserID,
UserName,
UserEmail,
hashedPassword,
UserType,
).Scan(&UserID, &verifyID)
if e != nil {
log.Println(e)
return nil, "", errors.New("a user with that email already exists")
}
} else {
e := d.db.QueryRow(
`SELECT userId, verifyId FROM register_user($1, $2, $3, $4);`,
UserName,
UserEmail,
hashedPassword,
UserType,
).Scan(&UserID, &verifyID)
if e != nil {
log.Println(e)
return nil, "", errors.New("a user with that email already exists")
}
}
return &User{UserID: UserID, UserName: UserName, UserEmail: UserEmail, UserType: UserType, UserAvatar: UserAvatar}, verifyID, nil
}
// UpdateUserProfile attempts to update the users profile
func (d *Database) UpdateUserProfile(UserID string, UserName string, UserAvatar string, NotificationsEnabled bool, Country string, Locale string, Company string, JobTitle string) error {
if UserAvatar == "" {
UserAvatar = "identicon"
}
if _, err := d.db.Exec(
`call user_profile_update($1, $2, $3, $4, $5, $6, $7, $8);`,
UserID,
UserName,
UserAvatar,
NotificationsEnabled,
Country,
Locale,
Company,
JobTitle,
); err != nil {
log.Println(err)
return errors.New("error attempting to update users profile")
}
return nil
}
// UserResetRequest inserts a new user reset request
func (d *Database) UserResetRequest(UserEmail string) (resetID string, UserName string, resetErr error) {
var ResetID sql.NullString
var UserID sql.NullString
var name sql.NullString
e := d.db.QueryRow(`
SELECT resetId, userId, userName FROM insert_user_reset($1);
`,
UserEmail,
).Scan(&ResetID, &UserID, &name)
if e != nil {
log.Println("Unable to reset user: ", e)
return "", "", e
}
return ResetID.String, name.String, nil
}
// UserResetPassword attempts to reset a users password
func (d *Database) UserResetPassword(ResetID string, UserPassword string) (UserName string, UserEmail string, resetErr error) {
var name sql.NullString
var email sql.NullString
hashedPassword, hashErr := HashAndSalt([]byte(UserPassword))
if hashErr != nil {
return "", "", hashErr
}
UserErr := d.db.QueryRow(`
SELECT
w.name, w.email
FROM user_reset wr
LEFT JOIN users w ON w.id = wr.user_id
WHERE wr.reset_id = $1;
`,
ResetID,
).Scan(&name, &email)
if UserErr != nil {
log.Println("Unable to get user for password reset confirmation email: ", UserErr)
return "", "", UserErr
}
if _, err := d.db.Exec(
`call reset_user_password($1, $2)`, ResetID, hashedPassword); err != nil {
return "", "", err
}
return name.String, email.String, nil
}
// UserUpdatePassword attempts to update a users password
func (d *Database) UserUpdatePassword(UserID string, UserPassword string) (Name string, Email string, resetErr error) {
var UserName sql.NullString
var UserEmail sql.NullString
UserErr := d.db.QueryRow(`
SELECT
w.name, w.email
FROM users w
WHERE w.id = $1;
`,
UserID,
).Scan(&UserName, &UserEmail)
if UserErr != nil {
log.Println("Unable to get user for password update: ", UserErr)
return "", "", UserErr
}
hashedPassword, hashErr := HashAndSalt([]byte(UserPassword))
if hashErr != nil {
return "", "", hashErr
}
if _, err := d.db.Exec(
`call update_user_password($1, $2)`, UserID, hashedPassword); err != nil {
return "", "", err
}
return UserName.String, UserEmail.String, nil
}
// VerifyUserAccount attempts to verify a users account email
func (d *Database) VerifyUserAccount(VerifyID string) error {
if _, err := d.db.Exec(
`call verify_user_account($1)`, VerifyID); err != nil {
return err
}
return nil
}
// UpdateUserProfile attempts to delete a user
func (d *Database) DeleteUser(UserID string) error {
if _, err := d.db.Exec(
`call delete_user($1);`,
UserID,
); err != nil {
log.Println(err)
return errors.New("error attempting to delete user")
}
return nil
}
// GetActiveCountries gets a list of user countries
func (d *Database) GetActiveCountries() ([]string, error) {
var countries = make([]string, 0)
rows, err := d.db.Query(`SELECT * FROM countries_active();`)
if err == nil {
defer rows.Close()
for rows.Next() {
var country sql.NullString
if err := rows.Scan(
&country,
); err != nil {
log.Println(err)
} else {
if country.String != "" {
countries = append(countries, country.String)
}
}
}
} else {
log.Println(err)
return nil, errors.New("error attempting to get active countries")
}
return countries, nil
}