89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
package allowances
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"sync"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func GetHashes(filename string) (Passes, bool, error) {
|
|
r := []string{}
|
|
exists := false
|
|
if !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
|
|
}
|
|
|
|
var dbMutex = sync.RWMutex{}
|
|
|
|
func loadChildren(filename string) (children map[string]int) {
|
|
dbMutex.RLock()
|
|
defer dbMutex.RUnlock()
|
|
b, err := ioutil.ReadFile(filename)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
err = json.Unmarshal(b, &children)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return
|
|
}
|
|
|
|
func dumpChildren(filename string, children map[string]int) {
|
|
dbMutex.Lock()
|
|
defer dbMutex.Unlock()
|
|
b, err := json.Marshal(children)
|
|
err = ioutil.WriteFile(filename, b, 0644)
|
|
if err != nil {
|
|
log.Fatal("serious issue writing children db file", err)
|
|
}
|
|
return
|
|
}
|