From 969d6dca0baefe1ef933a416151afb41abf58a59 Mon Sep 17 00:00:00 2001 From: morrigan Date: Mon, 16 Jun 2025 18:23:57 +0200 Subject: [PATCH] auth middlewear --- auth.go | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ gargoyle.go | 62 +++++++++------------------------------- go.mod | 1 + go.sum | 2 ++ 4 files changed, 99 insertions(+), 48 deletions(-) create mode 100644 auth.go diff --git a/auth.go b/auth.go new file mode 100644 index 0000000..c236b68 --- /dev/null +++ b/auth.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "strings" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" + "github.com/pquerna/otp/totp" + "gorm.io/gorm" +) + +type Signup struct { + Username string `form:"username"` +} + +func signup(c *gin.Context) { + var s Signup + c.Bind(&s) + + key, err := totp.Generate(totp.GenerateOpts{AccountName: s.Username, Issuer: "me"}) + if err != nil { + c.Status(502) + return + } + + var user User + if db.First(&user, "username = ?", s.Username).Error == gorm.ErrRecordNotFound { + user.Username = s.Username + user.Secret = key.Secret() + user.Token = uuid.New() + + db.Create(&user) + + c.SetCookie("auth", fmt.Sprint("Bearer ", user.Token), 10000, "/", "localhost", true, false) + c.Header("Authorization", fmt.Sprint("Bearer ", user.Token)) + c.String(200, "%s", key.Secret()) + } else { + c.String(404, "username already used") + } +} + +type Login struct { + Username string `form:"username"` + Code string `form:"code"` +} + +func login(c *gin.Context) { + var login Login + var user User + c.Bind(&login) + if err := db.Where("username = ?", login.Username).First(&user).Error; err != nil { + c.String(404, "something went wrong") + return + } + correct := totp.Validate(login.Code, user.Secret) + if correct { + c.SetCookie("auth", fmt.Sprint("Bearer ", user.Token), 10000, "/", "localhost", true, false) + c.Redirect(200, "/") + } else { + c.String(404, "wrong code") + } +} + +func reset_token(c *gin.Context) { + user := c.MustGet("user").(User) + user.Token = uuid.New() + db.Update("token", &user) +} + +func check_auth(c *gin.Context) { + cookie, _ := c.Cookie("auth") + token, _ := strings.CutPrefix(cookie, "Bearer ") + user := User{} + auth := db.First(&user, "token = ?", token).Error == nil + + c.Set("authorized", auth) + if auth { + c.Set("user", user) + } + c.Next() +} diff --git a/gargoyle.go b/gargoyle.go index 0bf1204..39929b4 100644 --- a/gargoyle.go +++ b/gargoyle.go @@ -2,7 +2,7 @@ package main import ( "github.com/gin-gonic/gin" - "github.com/pquerna/otp/totp" + "github.com/google/uuid" "gorm.io/driver/sqlite" "gorm.io/gorm" ) @@ -15,7 +15,7 @@ type User struct { gorm.Model Secret string Username string `gorm:"uniqueIndex"` - Email string + Token uuid.UUID } func init() { @@ -29,55 +29,21 @@ func init() { func main() { r := gin.Default() - r.GET("/ping", func(c *gin.Context) { - c.String(200, "format string, values ...any") - }) - r.POST("/signup", signup) - r.POST("/login", login) - r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")} + r.Use(check_auth) + r.GET("/api/signup", signup) + r.GET("/api/login", login) + r.GET("/api/reset", reset_token) + r.GET("/", show) + r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080") } -type Signup struct { - Username string `form:"username"` - Email string `form:"email"` -} +func show(c *gin.Context) { + auth := c.MustGet("authorized").(bool) -func signup(c *gin.Context) { - var s Signup - c.Bind(&s) - - key, err := totp.Generate(totp.GenerateOpts{AccountName: s.Username, Issuer: "me"}) - if err != nil { - c.Status(502) - return - } - - var user User - user.Email = s.Email - user.Username = s.Username - user.Secret = key.Secret() - db.Create(&user) - - c.String(200, "%s", key.Secret()) -} - -type Login struct { - Username string `form:"username"` - Code string `form:"code"` -} - -func login(c *gin.Context) { - var login Login - var user User - c.Bind(&login) - if err := db.Where("username = ?", login.Username).First(&user).Error; err != nil { - c.String(404, "something went wrong") - return - } - correct := totp.Validate(login.Code, user.Secret) - if correct { - c.String(200, "success!") + if auth { + user := c.MustGet("user").(User) + c.String(200, "%s", user) } else { - c.String(404, "something went wrong") + c.String(200, "not logged in") } } diff --git a/go.mod b/go.mod index b099672..062f921 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.26.0 // indirect github.com/goccy/go-json v0.10.5 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index b22f046..12dd95c 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.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.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=