Sin descripción

models.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package main
  2. import (
  3. "errors"
  4. "log"
  5. "net/http"
  6. "os"
  7. "os/signal"
  8. "golang.org/x/crypto/bcrypt"
  9. "gopkg.in/mgo.v2"
  10. "gopkg.in/mgo.v2/bson"
  11. )
  12. func DBConnect(address string) *mgo.Session {
  13. session, err := mgo.Dial(address)
  14. if err != nil {
  15. panic(err)
  16. }
  17. // Optional. Switch the session to a monotonic behavior.
  18. session.SetMode(mgo.Monotonic, true)
  19. c := make(chan os.Signal, 1)
  20. signal.Notify(c, os.Interrupt)
  21. go func() {
  22. for sig := range c {
  23. log.Println("%v captured - Closing database connection", sig)
  24. session.Close()
  25. os.Exit(1)
  26. }
  27. }()
  28. return session
  29. }
  30. func DBEnsureIndices(s *mgo.Session) error {
  31. i := mgo.Index{
  32. Key: []string{"email"},
  33. Unique: true,
  34. Background: true,
  35. Name: "email",
  36. }
  37. return s.DB(DBNAME).C("users").EnsureIndex(i)
  38. }
  39. type User struct {
  40. ID bson.ObjectId `bson:"_id" json:"-"`
  41. Email string `bson:"email" json:"email"`
  42. Password string `bson:"password,omitempty" json:"-"`
  43. DisplayName string `bson:"displayName,omitempty" json:"displayName,omitempty"`
  44. Picture string `bson:"picture,omitempty" json:"picture,omitempty"`
  45. Facebook string `bson:"facebook,omitempty" json:"facebook,omitempty"`
  46. Foursquare string `bson:"foursquare,omitempty" json:"foursquare,omitempty"`
  47. Google string `bson:"google,omitempty" json:"google,omitempty"`
  48. Github string `bson:"github,omitempty" json:"github,omitempty"`
  49. Linkedin string `bson:"linkedin,omitempty" json:"linkedin,omitempty"`
  50. Live string `bson:"live,omitempty" json:"live,omitempty"`
  51. Yahoo string `bson:"yahoo,omitempty" json:"yahoo,omitempty"`
  52. Twitter string `bson:"twitter,omitempty" json:"twitter,omitempty"`
  53. }
  54. func (u *User) Save(db *mgo.Database) error {
  55. uC := db.C("users")
  56. _, err := uC.UpsertId(u.ID, bson.M{"$set": u})
  57. return err
  58. }
  59. func NewUser() (u *User) {
  60. u = &User{}
  61. u.ID = bson.NewObjectId()
  62. return
  63. }
  64. func CreateUser(db *mgo.Database, u *User) *Error {
  65. uC := db.C("users")
  66. pwHash, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
  67. if err != nil {
  68. return &Error{Reason: errors.New("Couldn't hash password"), Internal: true}
  69. }
  70. u.Password = string(pwHash)
  71. u.ID = bson.NewObjectId()
  72. err = uC.Insert(u)
  73. if mgo.IsDup(err) {
  74. return &Error{Reason: errors.New("User already exists"), Internal: false}
  75. }
  76. return nil
  77. }
  78. func AuthUser(db *mgo.Database, email, password string) (*User, *Error) {
  79. uC := db.C("users")
  80. user := &User{}
  81. err := uC.Find(bson.M{"email": email}).One(user)
  82. if err != nil {
  83. if err == mgo.ErrNotFound {
  84. return nil, &Error{Reason: errors.New("User wasn't found on our servers"), Internal: false}
  85. }
  86. return nil, &Error{Reason: err, Internal: true}
  87. }
  88. if user.ID == "" {
  89. return nil, &Error{Reason: errors.New("No user found"), Internal: false}
  90. }
  91. err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
  92. if err != nil {
  93. return nil, &Error{Reason: errors.New("Incorrect password"), Internal: false, Code: http.StatusUnauthorized}
  94. }
  95. return user, nil
  96. }
  97. func FindUserByQuery(db *mgo.Database, query bson.M) (*User, *Error) {
  98. uC := db.C("users")
  99. user := &User{}
  100. err := uC.Find(query).One(user)
  101. if err != nil {
  102. return nil, &Error{Reason: err, Internal: true}
  103. } else if user.ID == "" {
  104. return nil, &Error{Reason: errors.New("No user found"), Internal: false}
  105. }
  106. return user, nil
  107. }
  108. func FindUserById(db *mgo.Database, id bson.ObjectId) (*User, *Error) {
  109. uC := db.C("users")
  110. user := &User{}
  111. err := uC.FindId(id).One(user)
  112. if err != nil {
  113. return nil, &Error{Reason: err, Internal: true}
  114. } else if user.ID == "" {
  115. return nil, &Error{Reason: errors.New("No user found"), Internal: false}
  116. }
  117. return user, nil
  118. }
  119. func FindUserByProvider(db *mgo.Database, provider, sub string) (*User, *Error) {
  120. return FindUserByQuery(db, bson.M{provider: sub})
  121. }
  122. func UpdateUserById(db *mgo.Database, id bson.ObjectId, email, displayName string) *Error {
  123. uC := db.C("users")
  124. user, errM := FindUserById(db, id)
  125. if errM != nil {
  126. return errM
  127. }
  128. if displayName == "" {
  129. displayName = user.DisplayName
  130. }
  131. if email == "" {
  132. email = user.Email
  133. }
  134. err := uC.Update(bson.M{"_id": id}, bson.M{"$set": bson.M{"email": email, "displayName": displayName}})
  135. if err != nil {
  136. return &Error{Reason: errors.New("No user found"), Internal: false}
  137. }
  138. return nil
  139. }