64 lines
1.1 KiB
Go
64 lines
1.1 KiB
Go
package allowances
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"sync"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
"mcquay.me/fs"
|
|
)
|
|
|
|
var dbMutex sync.RWMutex
|
|
|
|
func GetHashes(filename string) (Passes, bool, error) {
|
|
r := []string{}
|
|
exists := false
|
|
if !fs.Exists(filename) {
|
|
return r, exists, nil
|
|
}
|
|
exists = true
|
|
f, err := os.Open(filename)
|
|
if err != nil {
|
|
return nil, exists, err
|
|
}
|
|
err = json.NewDecoder(f).Decode(&r)
|
|
if err != nil {
|
|
return nil, exists, err
|
|
}
|
|
return r, exists, nil
|
|
}
|
|
|
|
func AddPassword(filename, pw string) error {
|
|
curPasses, _, err := GetHashes(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
hpass, err := bcrypt.GenerateFromPassword(
|
|
[]byte(pw), bcrypt.DefaultCost)
|
|
curPasses = append(curPasses, string(hpass))
|
|
|
|
f, err := os.Create(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := json.NewEncoder(f).Encode(curPasses); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type Passes []string
|
|
|
|
func (p Passes) Check(attempt string) (bool, error) {
|
|
// TODO: parallelize
|
|
for _, hash := range p {
|
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(attempt))
|
|
if err == nil {
|
|
return true, err
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|