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 }