diff --git a/internal/photos/api/account.go b/internal/photos/api/account.go index d20f319..332e266 100644 --- a/internal/photos/api/account.go +++ b/internal/photos/api/account.go @@ -18,11 +18,6 @@ type SignupOrLoginRequest struct { func (s *Service) Signup(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 @@ -38,7 +33,7 @@ func (s *Service) Signup(c *gin.Context) { return } if accountExists > 0 { - s.Error(c, http.StatusConflict, errors.New("account exists")) + s.Error(c, http.StatusConflict, ErrAccountExists) return } if err := s.DB.Create(models.NewAccount(account.Login, account.Password)).Error; err != nil { @@ -54,11 +49,6 @@ func (s *Service) Signup(c *gin.Context) { 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 @@ -66,10 +56,9 @@ func (s *Service) Login(c *gin.Context) { 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: + if errors.Is(err, gorm.ErrRecordNotFound) { + s.Error(c, http.StatusNotFound, ErrAccountAuth) + } else { s.Error(c, http.StatusInternalServerError, err) } return @@ -81,7 +70,12 @@ func (s *Service) Login(c *gin.Context) { } func (s *Service) Logout(c *gin.Context) { - c.JSON(http.StatusNotImplemented, gin.H{ - "status": "todo", + var sess *models.Session = c.MustGet("session").(*models.Session) + if err := s.DB.Delete(sess).Error; err != nil { + s.Error(c, http.StatusInternalServerError, err) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": "success", }) } diff --git a/internal/photos/api/session.go b/internal/photos/api/session.go new file mode 100644 index 0000000..36eb1ab --- /dev/null +++ b/internal/photos/api/session.go @@ -0,0 +1,37 @@ +package api + +import ( + "errors" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + "gitlab.celogeek.com/photos/api/internal/photos/models" + "gorm.io/gorm" +) + +func (s *Service) RequireSession(c *gin.Context) { + token := c.GetHeader("Authorization") + if !strings.HasPrefix(token, "Private ") { + s.Error(c, http.StatusForbidden, ErrTokenMissing) + return + } + token = token[8:] + c.Set("token", token) + + sess := &models.Session{} + if err := s.DB.Preload("Account").Where("token = ?", token).First(sess).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + s.Error(c, http.StatusForbidden, ErrSessionNotFound) + } else { + s.Error(c, http.StatusForbidden, err) + } + return + } + if sess.Account == nil { + s.Error(c, http.StatusInternalServerError, ErrSessionInvalid) + return + } + s.Logger.Printf("User: %s", sess.Account.Login) + c.Set("session", sess) +}