gargoyle/auth.go

83 lines
1.7 KiB
Go
Raw Permalink Normal View History

2025-06-16 18:23:57 +02:00
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()
}