82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
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()
|
|
}
|