Skip to content

Commit

Permalink
Refactor: data access
Browse files Browse the repository at this point in the history
  • Loading branch information
MrXu committed Apr 19, 2016
1 parent abe10fd commit 2f8ab27
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import (
"net/http"
"goServe/mongodb"
"gopkg.in/mgo.v2"
"time"
)

const (
EmailVerifyCode string = "vcode"
)

type LoginCredential struct{
Expand All @@ -24,20 +27,26 @@ func LoginUserWithEmail(c *gin.Context){
if c.BindJSON(&loginJson) == nil {

var user *UserAccount
user, err := getUserByEmail(loginJson.Email, c)
// db access
db := c.MustGet(mongodb.DBMiddlewareName).(*mgo.Database)
user, err := GetUserByEmail(loginJson.Email, db)

if err != nil {
abortWithError(c, http.StatusUnauthorized, "authentication fail")
return
}

passwordValidErr := safeComparePassword(user.Password, []byte(loginJson.Password))
if passwordValidErr != nil{
abortWithError(c, http.StatusUnauthorized, "authentication fail")
return
}

tokenString, tokenErr := GenerateToken(loginJson.Email)

if tokenErr != nil{
abortWithError(c, http.StatusUnauthorized, "authentication fail")
abortWithError(c, http.StatusUnauthorized, "authentication fail")
return
}

c.JSON(http.StatusOK, gin.H{"authenticated":"true","token":tokenString})
Expand All @@ -54,26 +63,26 @@ func SignUpWithEmail(c *gin.Context) {
if c.BindJSON(&signUpJson) == nil {

if validateEmail(signUpJson.Email, c) && validatePassword(signUpJson.Password){
hash, hasherr := hashPassword(signUpJson.Password)
if hasherr != nil{
abortWithError(c, http.StatusBadRequest, "signup fail")
}
// db access
db := c.MustGet(mongodb.DBMiddlewareName).(*mgo.Database)
err := db.C(CollectionUserAccount).Insert(&UserAccount{
Id:signUpJson.Email,
Password:hash,
CreatedOn:int64(time.Now().Second()),
UpdatedOn:int64(time.Now().Second()),
Active:false})
err := InsertUserAccount(signUpJson.Email, signUpJson.Password, db)

if err != nil{
abortWithError(c, http.StatusBadRequest, "signup fail")
return
}

// sent email
sendRegistrationConfirmationEmail(signUpJson.Email,signUpJson.Email,c)

// login and sent back token
tokenString, tokenErr := GenerateToken(signUpJson.Email)
if tokenErr != nil{
abortWithError(c, http.StatusUnauthorized, "authentication fail")
return
}
c.JSON(http.StatusOK, gin.H{"status":"sign up success","authenticated":"true","token":tokenString})

c.JSON(http.StatusOK, gin.H{"status":"sign up success"})
}else{
c.JSON(http.StatusBadRequest, gin.H{"error":"sign up fail"})
}
Expand All @@ -83,3 +92,31 @@ func SignUpWithEmail(c *gin.Context) {
}
}


func ActivateAccountAfterEmailSignup(c *gin.Context) {
vcode := c.Query(EmailVerifyCode)
db := c.MustGet(mongodb.DBMiddlewareName).(*mgo.Database)
result,err := GetEmailConfirm(vcode,db)

// err getting record
if err != nil {
abortWithError(c, http.StatusBadRequest, "invalid code")
return
}

// vcode used or vcode expire
if result.Used || isTimeStampExpired(result.ExpireAt){
abortWithError(c, http.StatusBadRequest, "invalid code")
return
}


updateErr := SetEmailConfirmUsed(vcode, db)
if updateErr != nil {
abortWithError(c, http.StatusBadRequest, "invalid code")
return
}

c.JSON(http.StatusOK, gin.H{"activated":"true"})
}

File renamed without changes.
5 changes: 4 additions & 1 deletion auth/authMiddleware.go → auth/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package auth

import (
"net/http"
"goServe/mongodb"
"gopkg.in/mgo.v2"
"github.com/gin-gonic/gin"
jwt "github.com/dgrijalva/jwt-go"
)
Expand All @@ -22,7 +24,8 @@ func TokenAuthMiddleware(c *gin.Context) {


if token.Claims[USERID] != nil{
user, getUserErr := getUserByEmail(token.Claims[USERID].(string),c)
db := c.MustGet(mongodb.DBMiddlewareName).(*mgo.Database)
user, getUserErr := GetUserByEmail(token.Claims[USERID].(string),db)
if getUserErr != nil{
abortWithError(c, http.StatusUnauthorized, "Invalid User Token")
}
Expand Down
35 changes: 28 additions & 7 deletions auth/modelOperation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package auth

import (

"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"time"
)

Expand All @@ -17,22 +20,40 @@ const (

type tempOpsToken struct{
UserId string
Token []byte
Token string `json:"token" bson:"token"`
Used bool
ExpireAt int64
}


type emailConfirmation struct{
type EmailConfirmation struct{
UserId string
Token []byte
Used bool
Token string `json:"token" bson:"token"`
Used bool `json:"used" bson:"used"`
ExpireAt int64
}

type passwordChange struct{
type PasswordChange struct{
UserId string
Token []byte
Used bool
Token string `json:"token" bson:"token"`
Used bool `json:"used" bson:"used"`
ExpireAt int64
}


func GetEmailConfirm(vcode string, db *mgo.Database) (*EmailConfirmation,error) {
result := &EmailConfirmation{}
err := db.C(CollectionEmailConfirmation).Find(bson.M{"token":vcode}).One(&result)
return result,err
}

func SetEmailConfirmUsed(vcode string, db *mgo.Database) error{
err := db.C(CollectionEmailConfirmation).Update(bson.M{"token":vcode}, bson.M{"$set":bson.M{"used":true}})
return err
}






35 changes: 35 additions & 0 deletions auth/modelUser.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package auth

import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"time"
)

const (
User string = "user"
)
Expand Down Expand Up @@ -33,3 +39,32 @@ type SocialAuth struct{
service string `json:"service" bson:"service"`
token string
}



func GetUserByEmail(userId string, db *mgo.Database) (*UserAccount, error){
result := &UserAccount{}
err := db.C(CollectionUserAccount).Find(bson.M{"_id":userId}).One(&result)

return result,err
}

func InsertUserAccount(email string, password string, db *mgo.Database) error {

hash, hasherr := hashPassword(password)
if hasherr != nil{
return hasherr
}

err := db.C(CollectionUserAccount).Insert(&UserAccount{
Id: email,
Password: hash, // hash
CreatedOn:int64(time.Now().Second()),
UpdatedOn:int64(time.Now().Second()),
Active:false})

return err

}


33 changes: 14 additions & 19 deletions auth/authUtil.go → auth/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,25 @@ package auth

import (
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
"github.com/dchest/uniuri"
"time"
"goServe/mongodb"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"golang.org/x/crypto/bcrypt"
"crypto/rand"
)

func getUserByEmail(userId string, c *gin.Context) (*UserAccount, error){
db := c.MustGet(mongodb.DBMiddlewareName).(*mgo.Database)
result := &UserAccount{}
err := db.C(CollectionUserAccount).Find(bson.M{"_id":userId}).One(&result)

return result,err

}

func validateEmail(userId string, c *gin.Context) bool {
db := c.MustGet(mongodb.DBMiddlewareName).(*mgo.Database)

result := &UserAccount{}

err := db.C(CollectionUserAccount).Find(bson.M{"_id":userId}).One(&result)
_,err := GetUserByEmail(userId, db)
if err != nil{
return true
}else{
return false
}
}

// hash password with bcypt
func hashPassword(password string) ([]byte, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil{
Expand All @@ -51,9 +41,8 @@ func validatePassword(password string) bool{
return true
}

func generateRandomToken() []byte{
b := make([]byte, 24)
rand.Read(b)
func generateRandomUri() string{
b := uniuri.NewLen(64)
return b
}

Expand All @@ -65,4 +54,10 @@ func abortWithError(c *gin.Context, code int, message string) {
"message": message,
})
c.Abort()
}
}

func isTimeStampExpired(timestamp int64) bool{
now := time.Now()
expireAt := time.Unix(timestamp,0)
return expireAt.Before(now)
}
6 changes: 3 additions & 3 deletions auth/authEmail.go → auth/utilEmail.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (

func sendRegistrationConfirmationEmail(email string, userId string, c *gin.Context){
context := c.Copy()
randomToken := generateRandomToken()
randomToken := generateRandomUri()
db := context.MustGet(mongodb.DBMiddlewareName).(*mgo.Database)
err := db.C(CollectionEmailConfirmation).Insert(&emailConfirmation{
err := db.C(CollectionEmailConfirmation).Insert(&EmailConfirmation{
UserId:userId,
Token:randomToken,
Used: false,
Expand All @@ -24,7 +24,7 @@ func sendRegistrationConfirmationEmail(email string, userId string, c *gin.Conte
}

go func() {
emailWorker.SendAnEmail(email,"hello email")
emailWorker.SendAnEmail(email,randomToken)
}()

}
File renamed without changes.
2 changes: 1 addition & 1 deletion email/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func SendAnEmail(to string, msg string){
m.SetHeader("From", Email.Address)
m.SetHeader("To", to)
m.SetHeader("Subject", "Hello!")
m.SetBody("text/html", "Hello <b>Email</b>!")
m.SetBody("text/html", "Hello <b>Email</b>!" + msg)
//m.Attach("/home/Alex/lolcat.jpg")

d := gomail.NewDialer(Email.Host, Email.Port, Email.Address, Email.Password)
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func main() {
*/
r.POST("/login", auth.LoginUserWithEmail)
r.POST("/signup/email", auth.SignUpWithEmail)
r.POST("/signup/email/verify-email", auth.ActivateAccountAfterEmailSignup)


/*
Expand All @@ -59,5 +60,6 @@ func main() {




r.Run(":8080") // listen and serve on 0.0.0.0:8080
}

0 comments on commit 2f8ab27

Please sign in to comment.