github.com/serge-v/zero@v1.0.2-0.20220911142406-af4b6a19e68a/examples/how-to-user-registration/db.go (about) 1 package main 2 3 import ( 4 "crypto/rand" 5 "encoding/json" 6 "log" 7 "math/big" 8 "os" 9 ) 10 11 type user struct { 12 Email string 13 Password string 14 Confirmed bool 15 RandomHash string 16 } 17 18 type userDB struct { 19 fname string 20 Users []user 21 } 22 23 func loadDB(fname string) userDB { 24 db := userDB{fname: fname} 25 f, err := os.Open(fname) 26 if err != nil && os.IsNotExist(err) { 27 return db 28 } 29 defer f.Close() 30 31 dec := json.NewDecoder(f) 32 if err := dec.Decode(&db); err != nil { 33 log.Fatal(err) 34 } 35 36 return db 37 } 38 39 func (db *userDB) saveDB() error { 40 f, err := os.Create(db.fname) 41 if err != nil { 42 return err 43 } 44 defer f.Close() 45 enc := json.NewEncoder(f) 46 enc.SetIndent("", "\t") 47 if err := enc.Encode(db); err != nil { 48 return err 49 } 50 return nil 51 } 52 53 func (db *userDB) findUser(email string) (*user, bool) { 54 for _, u := range db.Users { 55 if u.Email == email { 56 return &u, true 57 } 58 } 59 return nil, false 60 } 61 62 func (db *userDB) createUser(email, password string) (*user, error) { 63 if u, found := db.findUser(email); found { 64 return u, nil 65 } 66 67 randomHash, err := generateRandomString(20) 68 if err != nil { 69 return nil, err 70 } 71 72 u := user{ 73 Email: email, 74 Password: password, 75 RandomHash: randomHash, 76 } 77 78 db.Users = append(db.Users, u) 79 if err := db.saveDB(); err != nil { 80 return nil, err 81 } 82 83 return &u, nil 84 } 85 86 func generateRandomString(n int) (string, error) { 87 const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 88 ret := make([]byte, n) 89 for i := 0; i < n; i++ { 90 num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) 91 if err != nil { 92 return "", err 93 } 94 ret[i] = letters[num.Int64()] 95 } 96 97 return string(ret), nil 98 }