db.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package paneldb
  2. import (
  3. "fmt"
  4. "github.com/go-pg/pg"
  5. "github.com/pkg/errors"
  6. "golang.org/x/crypto/bcrypt"
  7. )
  8. // An User represents a user of the application.
  9. type User struct {
  10. ID string `sql:"uid"`
  11. Name string `sql:"username"`
  12. Email string `sql:"email"`
  13. DateCreated string `sql:"date_created"`
  14. PasswordHash string `sql:"password"`
  15. }
  16. func (u User) String() string {
  17. return fmt.Sprintf("{User: %s <%s>}", u.Name, u.Email)
  18. }
  19. // DB represents the application database. It provides high-level methods to get and manipulate objects.
  20. type DB struct {
  21. PgDB *pg.DB
  22. Schema string
  23. }
  24. // Setup will create schemas and tables as appropriate
  25. func (db *DB) Setup() error {
  26. _, err := db.PgDB.Exec(`CREATE SCHEMA IF NOT EXISTS users`)
  27. if err != nil {
  28. return errors.Wrap(err, "Error creating schema")
  29. }
  30. fmt.Println("schema created")
  31. _, err = db.PgDB.Exec(`CREATE TABLE IF NOT EXISTS users.users (
  32. uid UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  33. username varchar(64) UNIQUE NOT NULL,
  34. email varchar(100) UNIQUE NOT NULL,
  35. date_created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  36. password varchar(256) NOT NULL
  37. )`)
  38. if err != nil {
  39. return errors.Wrap(err, "Error creating users table")
  40. }
  41. fmt.Println("table created")
  42. return nil
  43. }
  44. // UserAdd will add a user to the database
  45. func (db *DB) UserAdd(username, email, pwd string) error {
  46. stmt, err := db.PgDB.Prepare("INSERT INTO users.users (username, email, password) VALUES ($1, $2, $3)")
  47. if err != nil {
  48. return errors.Wrap(err, "Error preparing insert statement")
  49. }
  50. pwhash, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
  51. if err != nil {
  52. return errors.Wrap(err, "Error deriving password (with bcrypt)")
  53. }
  54. _, err = stmt.Exec(username, email, string(pwhash))
  55. if err != nil {
  56. return errors.Wrapf(err, "Error adding user `%s`", username)
  57. }
  58. return nil
  59. }
  60. // GetUsers returns an array of Users
  61. func (db *DB) GetUsers() ([]User, error) {
  62. var users []User
  63. _, err := db.PgDB.Query(&users, "SELECT * FROM users.users")
  64. if err != nil {
  65. return users, errors.Wrap(err, "User enumeration failed")
  66. }
  67. return users, err
  68. }
  69. // GetUserByName Search for exact username
  70. func (db *DB) GetUserByName(username string) (User, error) {
  71. var user User
  72. _, err := db.PgDB.QueryOne(&user, `SELECT * FROM users.users WHERE username = ?`, username)
  73. if err != nil {
  74. return user, errors.Wrap(err, "User fetch failed")
  75. }
  76. return user, nil
  77. }
  78. // GetUserByEmail searches for exact email
  79. func (db *DB) GetUserByEmail(email string) (User, error) {
  80. var user User
  81. _, err := db.PgDB.QueryOne(&user, "SELECT * FROM users.users WHERE email = ?", email)
  82. if err != nil {
  83. return user, errors.Wrap(err, "User fetch failed")
  84. }
  85. return user, nil
  86. }
  87. // GetUserByID search for exact uid
  88. func (db *DB) GetUserByID(uid string) (User, error) {
  89. var user User
  90. _, err := db.PgDB.QueryOne(&user, "SELECT * FROM users.users WHERE uid=$1", uid)
  91. if err != nil {
  92. return user, errors.Wrap(err, "User fetch failed")
  93. }
  94. return user, nil
  95. }