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.

84 lines
1.9 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) (*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, nil, errors.New("user not exist")
  56. }
  57. if !checkPasswordHash(password, user.Password) {
  58. return nil, nil, errors.New("error with password")
  59. }
  60. user.Password = ""
  61. // create jwt
  62. token := jwt.New(jwt.SigningMethodHS256)
  63. claims := make(jwt.MapClaims)
  64. claims["user"] = true
  65. claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
  66. token.Claims = claims
  67. tokenString, err := token.SignedString(signingKey)
  68. if err != nil {
  69. return nil, nil, errors.New("error creating token")
  70. }
  71. return &tokenString, &user, err
  72. }