keeping track of my children's money since 2013
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package allowances
  2. import (
  3. "encoding/json"
  4. "os"
  5. "sync"
  6. "golang.org/x/crypto/bcrypt"
  7. "mcquay.me/fs"
  8. )
  9. var dbMutex sync.RWMutex
  10. func GetHashes(filename string) (Passes, bool, error) {
  11. r := []string{}
  12. exists := false
  13. if !fs.Exists(filename) {
  14. return r, exists, nil
  15. }
  16. exists = true
  17. f, err := os.Open(filename)
  18. if err != nil {
  19. return nil, exists, err
  20. }
  21. err = json.NewDecoder(f).Decode(&r)
  22. if err != nil {
  23. return nil, exists, err
  24. }
  25. return r, exists, nil
  26. }
  27. func AddPassword(filename, pw string) error {
  28. curPasses, _, err := GetHashes(filename)
  29. if err != nil {
  30. return err
  31. }
  32. hpass, err := bcrypt.GenerateFromPassword(
  33. []byte(pw), bcrypt.DefaultCost)
  34. curPasses = append(curPasses, string(hpass))
  35. f, err := os.Create(filename)
  36. if err != nil {
  37. return err
  38. }
  39. if err := json.NewEncoder(f).Encode(curPasses); err != nil {
  40. return err
  41. }
  42. return nil
  43. }
  44. type Passes []string
  45. func (p Passes) Check(attempt string) (bool, error) {
  46. // TODO: parallelize
  47. for _, hash := range p {
  48. err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(attempt))
  49. if err == nil {
  50. return true, err
  51. }
  52. }
  53. return false, nil
  54. }