/
passwd.go
85 lines (71 loc) · 1.86 KB
/
passwd.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
package passwd
import (
"encoding/json"
"github.com/boltdb/bolt"
"golang.org/x/crypto/bcrypt"
)
type Entries []Entry
type Entry struct {
Comment string
PasswordHash []byte
Username string
}
// Add adds a new entry to the specified boltdb database.
// The supplied password is hashed using the bcrypt algorithm before storing
// in the database.
func Add(username, password, comment string, cost int, db *bolt.DB) error {
entry, err := NewEntry(username, password, comment, cost)
if err != nil {
return err
}
data, err := json.Marshal(entry)
if err != nil {
return err
}
err = db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("htpasswd"))
return b.Put([]byte(username), data)
})
return err
}
func NewEntry(username, password, comment string, cost int) (*Entry, error) {
passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), cost)
if err != nil {
return nil, err
}
return &Entry{comment, passwordHash, username}, nil
}
func Delete(username string, db *bolt.DB) error {
err := db.Update(func(tx *bolt.Tx) error {
return tx.Bucket([]byte("htpasswd")).Delete([]byte(username))
})
return err
}
func List(db *bolt.DB) (Entries, error) {
entries := make(Entries, 0)
err := db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("htpasswd"))
c := b.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
var e Entry
if err := json.Unmarshal(v, &e); err != nil {
return err
}
entries = append(entries, e)
}
return nil
})
return entries, err
}
func Verify(username, password string, db *bolt.DB) error {
err := db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("htpasswd"))
rawEntry := b.Get([]byte(username))
var e Entry
if err := json.Unmarshal(rawEntry, &e); err != nil {
return err
}
return bcrypt.CompareHashAndPassword(e.PasswordHash, []byte(password))
})
return err
}