From be849e78e974c5142b9e984cdeb03d8fd55dc11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Tue, 11 May 2021 21:38:31 +0200 Subject: [PATCH] created login controller --- go.mod | 2 +- pkg/api/routes.go | 6 ++- pkg/controllers/login.go | 38 ++++++++++++++++ pkg/controllers/register.go | 12 ++--- pkg/models/auth.go | 10 +++++ pkg/services/register.go | 41 ----------------- pkg/services/users.go | 89 +++++++++++++++++++++++++++++++++++++ 7 files changed, 148 insertions(+), 50 deletions(-) create mode 100644 pkg/controllers/login.go create mode 100644 pkg/models/auth.go delete mode 100644 pkg/services/register.go create mode 100644 pkg/services/users.go diff --git a/go.mod b/go.mod index 1ab759f..9d5f5e6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module wallet-api go 1.15 require ( - github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-gonic/gin v1.7.1 github.com/go-pg/pg/v10 v10.9.1 github.com/go-playground/validator/v10 v10.5.0 // indirect diff --git a/pkg/api/routes.go b/pkg/api/routes.go index 2c8e034..fdb3d90 100644 --- a/pkg/api/routes.go +++ b/pkg/api/routes.go @@ -14,10 +14,12 @@ func Routes(s *gin.Engine, db *pg.DB) { api := ver.Group("api") register := ver.Group("register") + login := ver.Group("login") apiService := services.ApiService{Db: db} - registerService := services.RegisterService{Db: db} + usersService := services.UsersService{Db: db} controllers.NewApiController(&apiService, api) - controllers.NewRegisterController(®isterService, register) + controllers.NewRegisterController(&usersService, register) + controllers.NewLoginController(&usersService, login) } diff --git a/pkg/controllers/login.go b/pkg/controllers/login.go new file mode 100644 index 0000000..008fb4c --- /dev/null +++ b/pkg/controllers/login.go @@ -0,0 +1,38 @@ +package controllers + +import ( + "net/http" + "wallet-api/pkg/models" + "wallet-api/pkg/services" + + "github.com/gin-gonic/gin" +) + +type LoginController struct { + UsersService *services.UsersService +} + +func NewLoginController(rs *services.UsersService, s *gin.RouterGroup) *LoginController { + rc := new(LoginController) + rc.UsersService = rs + + s.POST("", rc.Post) + + return rc +} + +func (rc *LoginController) Post(c *gin.Context) { + loginBody := new(models.LoginModel) + if err := c.ShouldBindJSON(&loginBody); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + returnedUser, returnException := rc.UsersService.Login(loginBody) + + if returnException.Message != "" { + c.JSON(returnException.StatusCode, returnException) + } else { + c.JSON(200, returnedUser) + } + +} diff --git a/pkg/controllers/register.go b/pkg/controllers/register.go index e4a6957..fbb6740 100644 --- a/pkg/controllers/register.go +++ b/pkg/controllers/register.go @@ -10,12 +10,12 @@ import ( ) type RegisterController struct { - RegisterService *services.RegisterService + UsersService *services.UsersService } -func NewRegisterController(rs *services.RegisterService, s *gin.RouterGroup) *RegisterController { +func NewRegisterController(rs *services.UsersService, s *gin.RouterGroup) *RegisterController { rc := new(RegisterController) - rc.RegisterService = rs + rc.UsersService = rs s.POST("", rc.Post) @@ -23,12 +23,12 @@ func NewRegisterController(rs *services.RegisterService, s *gin.RouterGroup) *Re } func (rc *RegisterController) Post(c *gin.Context) { - registerBody := createModel() + registerBody := createUserModel() if err := c.ShouldBindJSON(®isterBody); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - returnedUser, returnException := rc.RegisterService.Create(®isterBody) + returnedUser, returnException := rc.UsersService.Create(®isterBody) if returnException.Message != "" { c.JSON(returnException.StatusCode, returnException) @@ -38,7 +38,7 @@ func (rc *RegisterController) Post(c *gin.Context) { } -func createModel() models.UserModel { +func createUserModel() models.UserModel { commonModel := common.CreateDbModel() userModel := models.UserModel{CommonModel: commonModel} return userModel diff --git a/pkg/models/auth.go b/pkg/models/auth.go new file mode 100644 index 0000000..5d75a10 --- /dev/null +++ b/pkg/models/auth.go @@ -0,0 +1,10 @@ +package models + +type TokenModel struct { + Token string `json:"token"` +} + +type LoginModel struct { + Email string + Password string +} diff --git a/pkg/services/register.go b/pkg/services/register.go deleted file mode 100644 index e841260..0000000 --- a/pkg/services/register.go +++ /dev/null @@ -1,41 +0,0 @@ -package services - -import ( - "wallet-api/pkg/models" - "wallet-api/pkg/utl/common" - - "golang.org/x/crypto/bcrypt" - - "github.com/go-pg/pg/v10" -) - -type RegisterService struct { - Db *pg.DB -} - -func (rs *RegisterService) Create(registerBody *models.UserModel) (*models.UserModel, models.ExceptionModel) { - var checkModel models.UserModel - var exceptionReturn models.ExceptionModel - - rs.Db.Model(&checkModel).Where("? = ?", pg.Ident("username"), registerBody.Username).WhereOr("? = ?", pg.Ident("email"), registerBody.Email).Select() - if checkModel.Username != "" || checkModel.Email != "" { - exceptionReturn.Message = "User already exists" - exceptionReturn.ErrorCode = "400101" - exceptionReturn.StatusCode = 400 - return &checkModel, exceptionReturn - } - - hashedPassword, err := bcrypt.GenerateFromPassword([]byte(registerBody.Password), bcrypt.DefaultCost) - common.CheckError(err) - - registerBody.Password = string(hashedPassword) - _, err = rs.Db.Model(registerBody).Insert() - - if err != nil { - exceptionReturn.Message = "Error creating user" - exceptionReturn.ErrorCode = "400102" - exceptionReturn.StatusCode = 400 - } - - return registerBody, exceptionReturn -} diff --git a/pkg/services/users.go b/pkg/services/users.go new file mode 100644 index 0000000..80cddbe --- /dev/null +++ b/pkg/services/users.go @@ -0,0 +1,89 @@ +package services + +import ( + "os" + "time" + "wallet-api/pkg/models" + "wallet-api/pkg/utl/common" + + jwt "github.com/dgrijalva/jwt-go" + "golang.org/x/crypto/bcrypt" + + "github.com/go-pg/pg/v10" +) + +type UsersService struct { + Db *pg.DB +} + +func (us *UsersService) Create(registerBody *models.UserModel) (*models.UserModel, models.ExceptionModel) { + var checkModel models.UserModel + var exceptionReturn models.ExceptionModel + + us.Db.Model(&checkModel).Where("? = ?", pg.Ident("username"), registerBody.Username).WhereOr("? = ?", pg.Ident("email"), registerBody.Email).Select() + if checkModel.Username != "" || checkModel.Email != "" { + exceptionReturn.Message = "User already exists" + exceptionReturn.ErrorCode = "400101" + exceptionReturn.StatusCode = 400 + return &checkModel, exceptionReturn + } + + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(registerBody.Password), bcrypt.DefaultCost) + common.CheckError(err) + + registerBody.Password = string(hashedPassword) + _, err = us.Db.Model(registerBody).Insert() + + if err != nil { + exceptionReturn.Message = "Error creating user" + exceptionReturn.ErrorCode = "400102" + exceptionReturn.StatusCode = 400 + } + + return registerBody, exceptionReturn +} + +func (us *UsersService) Login(loginBody *models.LoginModel) (models.TokenModel, models.ExceptionModel) { + var checkModel models.UserModel + var exceptionReturn models.ExceptionModel + var tokenPayload models.TokenModel + + us.Db.Model(&checkModel).Where("? = ?", pg.Ident("email"), loginBody.Email).Select() + if checkModel.Email == "" { + exceptionReturn.Message = "Email not found" + exceptionReturn.ErrorCode = "400103" + exceptionReturn.StatusCode = 400 + return tokenPayload, exceptionReturn + } + + if bcrypt.CompareHashAndPassword([]byte(checkModel.Password), []byte(loginBody.Password)) != nil { + exceptionReturn.Message = "Incorrect password" + exceptionReturn.ErrorCode = "400104" + exceptionReturn.StatusCode = 400 + return tokenPayload, exceptionReturn + } + + token, err := CreateToken(checkModel) + common.CheckError(err) + + tokenPayload.Token = token + + return tokenPayload, exceptionReturn +} + +func CreateToken(user models.UserModel) (string, error) { + atClaims := jwt.MapClaims{} + atClaims["authorized"] = true + atClaims["id"] = user.Id + atClaims["exp"] = time.Now().Add(time.Minute * 15).Unix() + + secret := os.Getenv("ACCESS_SECRET") + if secret == "" { + secret = "Dond3sta" + } + + at := jwt.NewWithClaims(jwt.SigningMethodHS256, atClaims) + token, err := at.SignedString([]byte(secret)) + + return token, err +}