diff options
Diffstat (limited to 'vendor/github.com/labstack/echo/cookbook/twitter/handler')
3 files changed, 184 insertions, 0 deletions
diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go b/vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go new file mode 100644 index 00000000..263c5e21 --- /dev/null +++ b/vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go @@ -0,0 +1,14 @@ +package handler + +import mgo "gopkg.in/mgo.v2" + +type ( + Handler struct { + DB *mgo.Session + } +) + +const ( + // Key (Should come from somewhere else). + Key = "secret" +) diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go b/vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go new file mode 100644 index 00000000..b1428a30 --- /dev/null +++ b/vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go @@ -0,0 +1,73 @@ +package handler + +import ( + "net/http" + "strconv" + + "github.com/labstack/echo" + "github.com/labstack/echo/cookbook/twitter/model" + mgo "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" +) + +func (h *Handler) CreatePost(c echo.Context) (err error) { + u := &model.User{ + ID: bson.ObjectIdHex(userIDFromToken(c)), + } + p := &model.Post{ + ID: bson.NewObjectId(), + From: u.ID.Hex(), + } + if err = c.Bind(p); err != nil { + return + } + + // Validation + if p.To == "" || p.Message == "" { + return &echo.HTTPError{Code: http.StatusBadRequest, Message: "invalid to or message fields"} + } + + // Find user from database + db := h.DB.Clone() + defer db.Close() + if err = db.DB("twitter").C("users").FindId(u.ID).One(u); err != nil { + if err == mgo.ErrNotFound { + return echo.ErrNotFound + } + return + } + + // Save post in database + if err = db.DB("twitter").C("posts").Insert(p); err != nil { + return + } + return c.JSON(http.StatusCreated, p) +} + +func (h *Handler) FetchPost(c echo.Context) (err error) { + userID := userIDFromToken(c) + page, _ := strconv.Atoi(c.QueryParam("page")) + limit, _ := strconv.Atoi(c.QueryParam("limit")) + + // Defaults + if page == 0 { + page = 1 + } + if limit == 0 { + limit = 100 + } + + // Retrieve posts from database + posts := []*model.Post{} + db := h.DB.Clone() + if err = db.DB("twitter").C("posts"). + Find(bson.M{"to": userID}). + Skip((page - 1) * limit). + Limit(limit). + All(&posts); err != nil { + return + } + defer db.Close() + + return c.JSON(http.StatusOK, posts) +} diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go b/vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go new file mode 100644 index 00000000..a34d2f4e --- /dev/null +++ b/vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go @@ -0,0 +1,97 @@ +package handler + +import ( + "net/http" + "time" + + jwt "github.com/dgrijalva/jwt-go" + "github.com/labstack/echo" + "github.com/labstack/echo/cookbook/twitter/model" + mgo "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" +) + +func (h *Handler) Signup(c echo.Context) (err error) { + // Bind + u := &model.User{ID: bson.NewObjectId()} + if err = c.Bind(u); err != nil { + return + } + + // Validate + if u.Email == "" || u.Password == "" { + return &echo.HTTPError{Code: http.StatusBadRequest, Message: "invalid email or password"} + } + + // Save user + db := h.DB.Clone() + defer db.Close() + if err = db.DB("twitter").C("users").Insert(u); err != nil { + return + } + + return c.JSON(http.StatusCreated, u) +} + +func (h *Handler) Login(c echo.Context) (err error) { + // Bind + u := new(model.User) + if err = c.Bind(u); err != nil { + return + } + + // Find user + db := h.DB.Clone() + defer db.Close() + if err = db.DB("twitter").C("users"). + Find(bson.M{"email": u.Email, "password": u.Password}).One(u); err != nil { + if err == mgo.ErrNotFound { + return &echo.HTTPError{Code: http.StatusUnauthorized, Message: "invalid email or password"} + } + return + } + + //----- + // JWT + //----- + + // Create token + token := jwt.New(jwt.SigningMethodHS256) + + // Set claims + claims := token.Claims.(jwt.MapClaims) + claims["id"] = u.ID + claims["exp"] = time.Now().Add(time.Hour * 72).Unix() + + // Generate encoded token and send it as response + u.Token, err = token.SignedString([]byte(Key)) + if err != nil { + return err + } + + u.Password = "" // Don't send password + return c.JSON(http.StatusOK, u) +} + +func (h *Handler) Follow(c echo.Context) (err error) { + userID := userIDFromToken(c) + id := c.Param("id") + + // Add a follower to user + db := h.DB.Clone() + defer db.Close() + if err = db.DB("twitter").C("users"). + UpdateId(bson.ObjectIdHex(id), bson.M{"$addToSet": bson.M{"followers": userID}}); err != nil { + if err == mgo.ErrNotFound { + return echo.ErrNotFound + } + } + + return +} + +func userIDFromToken(c echo.Context) string { + user := c.Get("user").(*jwt.Token) + claims := user.Claims.(jwt.MapClaims) + return claims["id"].(string) +} |