| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package main
- import (
- "errors"
- "log"
- "net/http"
- "os"
- "os/signal"
- "golang.org/x/crypto/bcrypt"
- "gopkg.in/mgo.v2"
- "gopkg.in/mgo.v2/bson"
- )
- func DBConnect(address string) *mgo.Session {
- session, err := mgo.Dial(address)
- if err != nil {
- panic(err)
- }
- // Optional. Switch the session to a monotonic behavior.
- session.SetMode(mgo.Monotonic, true)
- c := make(chan os.Signal, 1)
- signal.Notify(c, os.Interrupt)
- go func() {
- for sig := range c {
- log.Println("%v captured - Closing database connection", sig)
- session.Close()
- os.Exit(1)
- }
- }()
- return session
- }
- func DBEnsureIndices(s *mgo.Session) error {
- i := mgo.Index{
- Key: []string{"email"},
- Unique: true,
- Background: true,
- Name: "email",
- }
- return s.DB(DBNAME).C("users").EnsureIndex(i)
- }
- type User struct {
- ID bson.ObjectId `bson:"_id" json:"-"`
- Email string `bson:"email" json:"email"`
- Password string `bson:"password,omitempty" json:"-"`
- DisplayName string `bson:"displayName,omitempty" json:"displayName,omitempty"`
- Picture string `bson:"picture,omitempty" json:"picture,omitempty"`
- Facebook string `bson:"facebook,omitempty" json:"facebook,omitempty"`
- Foursquare string `bson:"foursquare,omitempty" json:"foursquare,omitempty"`
- Google string `bson:"google,omitempty" json:"google,omitempty"`
- Github string `bson:"github,omitempty" json:"github,omitempty"`
- Linkedin string `bson:"linkedin,omitempty" json:"linkedin,omitempty"`
- Live string `bson:"live,omitempty" json:"live,omitempty"`
- Yahoo string `bson:"yahoo,omitempty" json:"yahoo,omitempty"`
- Twitter string `bson:"twitter,omitempty" json:"twitter,omitempty"`
- }
- func (u *User) Save(db *mgo.Database) error {
- uC := db.C("users")
- _, err := uC.UpsertId(u.ID, bson.M{"$set": u})
- return err
- }
- func NewUser() (u *User) {
- u = &User{}
- u.ID = bson.NewObjectId()
- return
- }
- func CreateUser(db *mgo.Database, u *User) *Error {
- uC := db.C("users")
- pwHash, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
- if err != nil {
- return &Error{Reason: errors.New("Couldn't hash password"), Internal: true}
- }
- u.Password = string(pwHash)
- u.ID = bson.NewObjectId()
- err = uC.Insert(u)
- if mgo.IsDup(err) {
- return &Error{Reason: errors.New("User already exists"), Internal: false}
- }
- return nil
- }
- func AuthUser(db *mgo.Database, email, password string) (*User, *Error) {
- uC := db.C("users")
- user := &User{}
- err := uC.Find(bson.M{"email": email}).One(user)
- if err != nil {
- if err == mgo.ErrNotFound {
- return nil, &Error{Reason: errors.New("User wasn't found on our servers"), Internal: false}
- }
- return nil, &Error{Reason: err, Internal: true}
- }
- if user.ID == "" {
- return nil, &Error{Reason: errors.New("No user found"), Internal: false}
- }
- err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
- if err != nil {
- return nil, &Error{Reason: errors.New("Incorrect password"), Internal: false, Code: http.StatusUnauthorized}
- }
- return user, nil
- }
- func FindUserByQuery(db *mgo.Database, query bson.M) (*User, *Error) {
- uC := db.C("users")
- user := &User{}
- err := uC.Find(query).One(user)
- if err != nil {
- return nil, &Error{Reason: err, Internal: true}
- } else if user.ID == "" {
- return nil, &Error{Reason: errors.New("No user found"), Internal: false}
- }
- return user, nil
- }
- func FindUserById(db *mgo.Database, id bson.ObjectId) (*User, *Error) {
- uC := db.C("users")
- user := &User{}
- err := uC.FindId(id).One(user)
- if err != nil {
- return nil, &Error{Reason: err, Internal: true}
- } else if user.ID == "" {
- return nil, &Error{Reason: errors.New("No user found"), Internal: false}
- }
- return user, nil
- }
- func FindUserByProvider(db *mgo.Database, provider, sub string) (*User, *Error) {
- return FindUserByQuery(db, bson.M{provider: sub})
- }
- func UpdateUserById(db *mgo.Database, id bson.ObjectId, email, displayName string) *Error {
- uC := db.C("users")
- user, errM := FindUserById(db, id)
- if errM != nil {
- return errM
- }
- if displayName == "" {
- displayName = user.DisplayName
- }
- if email == "" {
- email = user.Email
- }
- err := uC.Update(bson.M{"_id": id}, bson.M{"$set": bson.M{"email": email, "displayName": displayName}})
- if err != nil {
- return &Error{Reason: errors.New("No user found"), Internal: false}
- }
- return nil
- }
|