db.go 3.1 KB

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