You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.0 KiB

  1. package usersrv
  2. import (
  3. "errors"
  4. "time"
  5. "github.com/arnaucube/gogame/database"
  6. "github.com/arnaucube/gogame/models"
  7. jwt "github.com/dgrijalva/jwt-go"
  8. "golang.org/x/crypto/bcrypt"
  9. "gopkg.in/mgo.v2/bson"
  10. )
  11. type Service struct {
  12. db *database.Db
  13. }
  14. func New(db *database.Db) *Service {
  15. return &Service{
  16. db,
  17. }
  18. }
  19. func hashPassword(password string) (string, error) {
  20. hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.MinCost)
  21. return string(hash), err
  22. }
  23. func checkPasswordHash(password, hash string) bool {
  24. err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
  25. return err == nil
  26. }
  27. func (srv Service) Register(name, password, email string) (*models.User, error) {
  28. var user models.User
  29. err := srv.db.Users.Find(bson.M{"email": email}).One(&user)
  30. if err == nil {
  31. return nil, errors.New("user already exist")
  32. }
  33. hashedPassword, err := hashPassword(password)
  34. if err != nil {
  35. return nil, err
  36. }
  37. newUser := models.User{
  38. Name: name,
  39. Password: hashedPassword,
  40. Email: email,
  41. }
  42. err = srv.db.Users.Insert(newUser)
  43. if err != nil {
  44. return nil, err
  45. }
  46. err = srv.db.Users.Find(bson.M{"email": email}).One(&user)
  47. user.Password = ""
  48. return &user, err
  49. }
  50. var signingKey = []byte("TODO") // TODO
  51. func (srv Service) Login(email, password string) (*models.User, error) {
  52. var user models.User
  53. err := srv.db.Users.Find(bson.M{"email": email}).One(&user)
  54. if err != nil {
  55. return nil, errors.New("user not exist")
  56. }
  57. if !checkPasswordHash(password, user.Password) {
  58. return nil, errors.New("error with password")
  59. }
  60. // create jwt
  61. token := jwt.New(jwt.SigningMethodHS256)
  62. claims := make(jwt.MapClaims)
  63. claims["user"] = true
  64. claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
  65. token.Claims = claims
  66. tokenString, err := token.SignedString(signingKey)
  67. if err != nil {
  68. return nil, errors.New("error creating token")
  69. }
  70. // TODO
  71. // reuse Password parameter, to put there the token
  72. user.Password = tokenString
  73. return &user, err
  74. }