-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.go
103 lines (86 loc) · 2.03 KB
/
db.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
package models
import (
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
"golang.org/x/crypto/bcrypt"
)
type AppDb interface {
DbStore() *sqlx.DB
Close() error
NewUser(string, string) (User, error)
Authenticate(string, string) (User, error)
}
type appDb struct {
db *sqlx.DB
}
func (db *appDb) DbStore() *sqlx.DB {
return db.db
}
func (db *appDb) Close() error {
return db.db.Close()
}
// TODO: Add better error messages. See Authenticate()
func (db *appDb) NewUser(name string, password string) (user User, err error) {
stmt, err := db.db.Preparex(
`INSERT INTO user(name, password_hash) ` +
`VALUES (?, ?);`,
)
if err != nil {
return
}
hash, err := bcrypt.GenerateFromPassword([]byte(password), 5)
if err != nil {
return
}
_, err = stmt.Exec(name, string(hash))
if err != nil {
return
}
user, err = db.findUser(name)
return
}
func (db *appDb) Authenticate(name string, password string) (User, error) {
user, err := db.findUser(name)
if err != nil {
return user, UserAuthenticationError{"user not found"}
}
if bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)) != nil {
err = UserAuthenticationError{"wrong password"}
user = User{}
}
return user, err
}
func (db *appDb) findUser(name string) (User, error) {
user := User{}
err := db.db.Get(&user, "SELECT * FROM user WHERE name=?", name)
return user, err
}
type User struct {
Name string `form:"name" json:"name"`
PasswordHash string `db:"password_hash"`
}
type UserAuthenticationError struct {
Msg string
}
func (e UserAuthenticationError) Error() string {
return e.Msg
}
func CreateDb(conn string) (*appDb, error) {
db, err := sqlx.Open("sqlite3", conn)
a := new(appDb)
a.db = db
if err != nil {
return a, err
}
err = a.createUserTable()
return a, err
}
func (db *appDb) createUserTable() (err error) {
_, err = db.db.Exec(
`CREATE TABLE user (` +
`name string NOT NULL, ` +
`password_hash string NOT NULL); ` +
`CREATE UNIQUE INDEX user_idx ON user (name);`,
)
return err
}