/
account.go
99 lines (88 loc) · 2.3 KB
/
account.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
package postgres
import (
"context"
_ "github.com/lib/pq"
"go.opentelemetry.io/otel"
"github.com/dmartzol/hmm/internal/hmm"
)
// Account fetches an account by id
func (db *DB) Account(id int64) (*hmm.Account, error) {
var a hmm.Account
sqlStatement := `select * from accounts a where a.id = $1`
err := db.Get(&a, sqlStatement, id)
if err != nil {
return nil, err
}
return &a, nil
}
// Accounts returns all accounts in the db
func (db *DB) Accounts() (hmm.Accounts, error) {
var accs []*hmm.Account
sqlStatement := `select * from accounts a`
err := db.Select(&accs, sqlStatement)
if err != nil {
return nil, err
}
return accs, nil
}
// AccountWithCredentials returns an account if the email and password provided match an (email,password) pair in the db
func (db *DB) AccountWithCredentials(email, allegedPassword string) (*hmm.Account, error) {
var a hmm.Account
sqlStatement := `select * from accounts a where a.email = $1 and a.passhash = crypt($2, a.passhash)`
err := db.Get(&a, sqlStatement, email, allegedPassword)
if err != nil {
return nil, err
}
return &a, nil
}
// CreateAccount creates a new account in the db and a confirmation code for the new registered email
func (db *DB) CreateAccount(ctx context.Context, a *hmm.Account, password, confirmationCode string) (*hmm.Account, *hmm.Confirmation, error) {
_, span := otel.Tracer("db").Start(ctx, "DB.CreateAccount")
defer span.End()
tx, err := db.Beginx()
if err != nil {
return nil, nil, err
}
var newAccount hmm.Account
sqlStatement := `
INSERT INTO accounts (
first_name,
last_name,
dob,
gender,
phone_number,
email,
passhash
) values ($1, $2, $3, $4, $5, $6, crypt($7, gen_salt('bf', 8))) returning *
`
err = tx.Get(
&newAccount,
sqlStatement,
a.FirstName,
a.LastName,
a.DOB,
a.Gender,
a.PhoneNumber,
a.Email,
password,
)
if err != nil {
_ = tx.Rollback()
return nil, nil, err
}
var confirmation hmm.Confirmation
sqlStatement = `
INSERT INTO confirmations (
type,
account_id,
key,
confirmation_target
) values ($1, $2, $3, $4) returning *
`
err = tx.Get(&confirmation, sqlStatement, hmm.ConfirmationTypeEmail, newAccount.ID, confirmationCode, newAccount.Email)
if err != nil {
_ = tx.Rollback()
return nil, nil, err
}
return &newAccount, &confirmation, tx.Commit()
}