From f710c19d65b8ce806ecfafa47f889e02d69e07f0 Mon Sep 17 00:00:00 2001 From: celogeek Date: Wed, 2 Feb 2022 21:46:20 +0100 Subject: [PATCH] add login --- go.mod | 3 +- go.sum | 2 ++ internal/photos/api/account.go | 52 ++++++++++++++++++++++--------- internal/photos/api/db.go | 1 + internal/photos/models/session.go | 43 +++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 internal/photos/models/session.go diff --git a/go.mod b/go.mod index f9e8433..2df04e9 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.17 require ( github.com/gin-gonic/gin v1.7.7 github.com/go-sql-driver/mysql v1.6.0 + github.com/google/uuid v1.3.0 + gopkg.in/validator.v2 v2.0.0-20210331031555-b37d688a7fb0 gorm.io/driver/mysql v1.2.3 gorm.io/gorm v1.22.5 ) @@ -25,6 +27,5 @@ require ( github.com/ugorji/go/codec v1.1.7 // indirect golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect - gopkg.in/validator.v2 v2.0.0-20210331031555-b37d688a7fb0 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/go.sum b/go.sum index 7baa364..49f17b3 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= diff --git a/internal/photos/api/account.go b/internal/photos/api/account.go index 5d685a1..d20f319 100644 --- a/internal/photos/api/account.go +++ b/internal/photos/api/account.go @@ -7,27 +7,16 @@ import ( "github.com/gin-gonic/gin" "gitlab.celogeek.com/photos/api/internal/photos/models" "gopkg.in/validator.v2" + "gorm.io/gorm" ) -func (s *Service) Login(c *gin.Context) { - c.JSON(http.StatusNotImplemented, gin.H{ - "status": "todo", - }) -} - -func (s *Service) Logout(c *gin.Context) { - c.JSON(http.StatusNotImplemented, gin.H{ - "status": "todo", - }) -} - -type SignupRequest struct { +type SignupOrLoginRequest struct { Login string `validate:"min=3,max=40,regexp=^[a-zA-Z0-9]*$"` Password string `validate:"min=8,max=40"` } func (s *Service) Signup(c *gin.Context) { - var account *SignupRequest + var account *SignupOrLoginRequest if c.Request.ContentLength == 0 { s.Error(c, http.StatusBadRequest, errors.New("missing body")) @@ -61,3 +50,38 @@ func (s *Service) Signup(c *gin.Context) { "status": "success", }) } + +func (s *Service) Login(c *gin.Context) { + var account *SignupOrLoginRequest + + if c.Request.ContentLength == 0 { + s.Error(c, http.StatusBadRequest, errors.New("missing body")) + return + } + + if err := c.ShouldBindJSON(&account); err != nil { + s.Error(c, http.StatusBadRequest, err) + return + } + + session, err := models.NewSession(s.DB, account.Login, account.Password) + if err != nil { + switch err { + case gorm.ErrRecordNotFound: + s.Error(c, http.StatusNotFound, errors.New("login or password incorrect")) + default: + s.Error(c, http.StatusInternalServerError, err) + } + return + } + + c.JSON(http.StatusOK, gin.H{ + "token": session.Token, + }) +} + +func (s *Service) Logout(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{ + "status": "todo", + }) +} diff --git a/internal/photos/api/db.go b/internal/photos/api/db.go index f6a6986..bce2ff6 100644 --- a/internal/photos/api/db.go +++ b/internal/photos/api/db.go @@ -11,6 +11,7 @@ import ( func (s *Service) Migrate() { tx := s.DB.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin") tx.AutoMigrate(&models.Account{}) + tx.AutoMigrate(&models.Session{}) } func (s *Service) DBConfig() { diff --git a/internal/photos/models/session.go b/internal/photos/models/session.go new file mode 100644 index 0000000..c81f957 --- /dev/null +++ b/internal/photos/models/session.go @@ -0,0 +1,43 @@ +package models + +import ( + "time" + + "github.com/google/uuid" + "gorm.io/gorm" +) + +type Session struct { + ID uint32 `gorm:"primary_key"` + Token string `gorm:"size:36"` + Account *Account `gorm:"constraint:OnDelete:CASCADE,OnUpdate:CASCADE"` + AccountId uint32 `gorm:"not null"` + CreatedAt time.Time + UpdatedAt time.Time +} + +func (s *Session) BeforeCreate(tx *gorm.DB) error { + uuid, err := uuid.NewRandom() + if err != nil { + return err + } + s.Token = uuid.String() + return nil +} + +func NewSession(tx *gorm.DB, login string, password string) (*Session, error) { + account := NewAccount(login, password) + if err := tx.Where( + "login = ? and encrypted_password = ?", + account.Login, + account.EncryptedPassword, + ).First(account).Error; err != nil { + return nil, err + } + + session := &Session{Account: account} + if err := tx.Create(session).Error; err != nil { + return nil, err + } + return session, nil +}