Skip to content

Commit

Permalink
Merge pull request #162 from linkernetworks/johnlin/user-restful-api
Browse files Browse the repository at this point in the history
[Task] [VX-210] add user CRUD
  • Loading branch information
Hung-Wei Chiu authored Jul 25, 2018
2 parents 004dfbf + 4608eff commit ee80a86
Show file tree
Hide file tree
Showing 8 changed files with 552 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/entity/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package entity

import (
"time"

"github.com/satori/go.uuid"
"gopkg.in/mgo.v2/bson"
)

// UserCollectionName's const
const (
UserCollectionName string = "users"
)

// User is the structure for user info
type User struct {
ID bson.ObjectId `bson:"_id,omitempty" json:"id" validate:"-"`
UUID uuid.UUID `bson:"uuid" json:"uuid" validate:"required"`
JWT string `bson:"jwt" json:"jwt" validate:"-"`
Username string `bson:"username" json:"username" validate:"required"`
Email string `bson:"email" json:"email" validate:"required,email"`
Password string `bson:"password" json:"password" validate:"required"`
FirstName string `bson:"firstname" json:"firstName" validate:"required"`
LastName string `bson:"lastName" json:"lastName" validate:"required"`
PhoneNumber string `bson:"phoneNumber" json:"phoneNumber" validate:"required,numeric"`
CreatedAt *time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty" validate:"-"`
}

// GetCollection - get model mongo collection name.
func (u User) GetCollection() string {
return UserCollectionName
}
Binary file added src/prometheuscontroller/debug.test
Binary file not shown.
173 changes: 173 additions & 0 deletions src/server/handler_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package server

import (
"fmt"
"math"
"strconv"

"github.com/linkernetworks/utils/timeutils"
"github.com/linkernetworks/vortex/src/entity"
response "github.com/linkernetworks/vortex/src/net/http"
"github.com/linkernetworks/vortex/src/net/http/query"
"github.com/linkernetworks/vortex/src/web"

"github.com/satori/go.uuid"
mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)

func createUserHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

user := entity.User{}
if err := req.ReadEntity(&user); err != nil {
response.BadRequest(req.Request, resp.ResponseWriter, err)
return
}

user.UUID = uuid.Must(uuid.NewV4())

encryptedPassword, err := hashPassword(user.Password)
if err != nil {
response.BadRequest(req.Request, resp.ResponseWriter, err)
return
}
user.Password = encryptedPassword

if err := sp.Validator.Struct(user); err != nil {
response.BadRequest(req.Request, resp.ResponseWriter, err)
return
}

session := sp.Mongo.NewSession()
// make email to be a unique key
session.C(entity.UserCollectionName).EnsureIndex(mgo.Index{
Key: []string{"email"},
Unique: true,
})
defer session.Close()

user.ID = bson.NewObjectId()
user.CreatedAt = timeutils.Now()

if err := session.Insert(entity.UserCollectionName, &user); err != nil {
if mgo.IsDup(err) {
response.Conflict(req.Request, resp.ResponseWriter, fmt.Errorf("Email: %s already existed", user.Email))
} else {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
}
return
}

resp.WriteEntity(response.ActionResponse{
Error: false,
Message: "User Created Success",
})
}

func deleteUserHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

id := req.PathParameter("id")

session := sp.Mongo.NewSession()
defer session.Close()

user := entity.User{}
if err := session.FindOne(
entity.UserCollectionName,
bson.M{"_id": bson.ObjectIdHex(id)},
&user,
); err != nil {
response.BadRequest(req.Request, resp.ResponseWriter, err)
return
}

if err := session.Remove(entity.UserCollectionName, "_id", bson.ObjectIdHex(id)); err != nil {
switch err {
case mgo.ErrNotFound:
response.NotFound(req.Request, resp.ResponseWriter, err)
return
default:
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}
}

resp.WriteEntity(response.ActionResponse{
Error: false,
Message: "User Deleted Success",
})
}

func listUserHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

var pageSize = 10
query := query.New(req.Request.URL.Query())

page, err := query.Int("page", 1)
if err != nil {
response.BadRequest(req.Request, resp.ResponseWriter, err)
return
}
pageSize, err = query.Int("page_size", pageSize)
if err != nil {
response.BadRequest(req.Request, resp.ResponseWriter, err)
return
}

session := sp.Mongo.NewSession()
defer session.Close()

users := []entity.User{}
var c = session.C(entity.UserCollectionName)
var q *mgo.Query

selector := bson.M{}
q = c.Find(selector).Sort("_id").Skip((page - 1) * pageSize).Limit(pageSize)

if err := q.All(&users); err != nil {
switch err {
case mgo.ErrNotFound:
response.NotFound(req.Request, resp.ResponseWriter, err)
return
default:
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}
}

count, err := session.Count(entity.UserCollectionName, bson.M{})
if err != nil {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}
totalPages := int(math.Ceil(float64(count) / float64(pageSize)))
resp.AddHeader("X-Total-Count", strconv.Itoa(count))
resp.AddHeader("X-Total-Pages", strconv.Itoa(totalPages))
resp.WriteEntity(users)
}

func getUserHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

id := req.PathParameter("id")

session := sp.Mongo.NewSession()
defer session.Close()
c := session.C(entity.UserCollectionName)

user := entity.User{}
if err := c.FindId(bson.ObjectIdHex(id)).One(&user); err != nil {
switch err {
case mgo.ErrNotFound:
response.NotFound(req.Request, resp.ResponseWriter, err)
return
default:
response.InternalServerError(req.Request, resp.ResponseWriter, err)
return
}
}
resp.WriteEntity(user)
}
Loading

0 comments on commit ee80a86

Please sign in to comment.