Slight refactor to re-use Auth structures

* Now Auth.Login is a consolidated attempt to verify password, 2fa code
and verified status
This commit is contained in:
🐙PiperYxzzy
2022-04-30 16:03:42 +02:00
parent 47ac0cdc07
commit 4b270733a7
2 changed files with 51 additions and 17 deletions

48
main.go
View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"time"
"github.com/yxzzy-wtf/gin-gonic-prepack/database" "github.com/yxzzy-wtf/gin-gonic-prepack/database"
"github.com/yxzzy-wtf/gin-gonic-prepack/models" "github.com/yxzzy-wtf/gin-gonic-prepack/models"
@@ -86,20 +85,12 @@ func userLogin() gin.HandlerFunc {
return return
} }
err := u.CheckPassword(loginVals.Password) if err, returnErr := u.Login(loginVals.Password, loginVals.TwoFactor); err != nil {
if err != nil { if returnErr {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
err = u.ValidateTwoFactor(loginVals.TwoFactor, time.Now())
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{err.Error()}) c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{err.Error()})
return } else {
c.AbortWithStatus(http.StatusUnauthorized)
} }
if !u.Verified {
c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{"not yet verified"})
return return
} }
@@ -141,7 +132,33 @@ func userSignup() gin.HandlerFunc {
func adminLogin() gin.HandlerFunc { func adminLogin() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
var loginVals login
if err := c.ShouldBind(&loginVals); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, failmsg{"requires username and password"})
}
if loginVals.TwoFactor == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{"admin access requires 2FA"})
return
}
a := models.Admin{}
if err := a.ByEmail(loginVals.UserKey); err != nil {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
if err, returnErr := a.Login(loginVals.Password, loginVals.TwoFactor); err != nil {
if returnErr {
c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{err.Error()})
} else {
c.AbortWithStatus(http.StatusUnauthorized)
}
return
}
jwt, maxAge := a.GetJwt()
c.SetCookie(JwtHeader, jwt, maxAge, ServicePath, ServiceDomain, true, true)
} }
} }
@@ -149,10 +166,11 @@ func userAuth() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
jwt := c.GetHeader(JwtHeader) jwt := c.GetHeader(JwtHeader)
if jwt == "" { if jwt == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{"Requires `" + jwt + "` header"}) c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{"requires `" + JwtHeader + "` header"})
return return
} }
c.AbortWithStatus(http.StatusUnauthorized)
} }
} }
@@ -160,7 +178,7 @@ func adminAuth() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
jwt := c.GetHeader(JwtHeader) jwt := c.GetHeader(JwtHeader)
if jwt == "" { if jwt == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{"Requires `" + jwt + "` header"}) c.AbortWithStatusJSON(http.StatusUnauthorized, failmsg{"requires `" + JwtHeader + "` header"})
return return
} }

View File

@@ -21,6 +21,22 @@ func (a *Auth) SetPassword(pass string) error {
return nil return nil
} }
func (a *Auth) Login(pass string, tfCode string) (error, bool) {
if err := a.CheckPassword(pass); err != nil {
return err, false
}
if err := a.ValidateTwoFactor(tfCode, time.Now()); err != nil {
return err, true
}
if !a.Verified {
return errors.New("not yet verified"), true
}
return nil, false
}
func (a *Auth) CheckPassword(pass string) error { func (a *Auth) CheckPassword(pass string) error {
return bcrypt.CompareHashAndPassword([]byte(a.PasswordHash), []byte(pass)) return bcrypt.CompareHashAndPassword([]byte(a.PasswordHash), []byte(pass))
} }