wip: auth tokens

need to finish and test
This commit is contained in:
IRHM
2023-10-04 19:50:48 +01:00
parent e605c8e71a
commit a07d9e2882
6 changed files with 97 additions and 7 deletions
+2 -6
View File
@@ -1,8 +1,6 @@
package main
import (
"crypto/rand"
b64 "encoding/base64"
"encoding/json"
"log"
"log/slog"
@@ -92,13 +90,11 @@ func initFromConfig() error {
// Currently only JWT_SECRET is required, so this method
// generates a secret.
func generateConfig() error {
key := make([]byte, 64)
_, err := rand.Read(key)
key, err := generateString(64)
if err != nil {
return err
}
encKey := b64.StdEncoding.EncodeToString([]byte(key))
cfg := ServerConfig{JWT_SECRET: encKey}
cfg := ServerConfig{JWT_SECRET: key}
barej, err := json.MarshalIndent(cfg, "", "\t")
if err != nil {
return err
+16
View File
@@ -0,0 +1,16 @@
package main
import (
"crypto/rand"
b64 "encoding/base64"
)
// Generate a random string
func generateString(len int) (string, error) {
key := make([]byte, len)
_, err := rand.Read(key)
if err != nil {
return "", err
}
return b64.StdEncoding.EncodeToString([]byte(key)), nil
}
+11
View File
@@ -401,6 +401,17 @@ func (b *BaseRouter) addAuthRoutes() {
IsInSetup: ServerInSetup,
})
})
// Request admin token
auth.Use(AuthRequired(nil)).GET("/admin_token", func(c *gin.Context) {
userId := c.MustGet("userId").(uint)
err := createOneUseToken(b.db, userId)
if err != nil {
c.JSON(http.StatusForbidden, ErrorResponse{Error: err.Error()})
return
}
c.Status(http.StatusNoContent)
})
}
func (b *BaseRouter) addProfileRoutes() {
+22
View File
@@ -0,0 +1,22 @@
package main
import (
"log/slog"
"time"
"gorm.io/gorm"
)
// Setup recurring tasks (eg cleanup every 5 mins)
func setupTasks(db *gorm.DB) {
taskRunInterval := 5 * time.Second
ticker := time.NewTicker(taskRunInterval)
defer ticker.Stop()
for range ticker.C {
slog.Info("TIMER GOING OFFFFFFFF")
// Runs funcs that are in the place where we are cleaning.
// Bit cleaner and we can keep the related code close to its home.
cleanupTokens(db)
}
}
+43
View File
@@ -0,0 +1,43 @@
package main
import (
"errors"
"log/slog"
"time"
"gorm.io/gorm"
)
type TokenType string
var (
TOKEN_ADMIN TokenType = "ADMIN"
)
type Token struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time `json:"createdAt"`
Value string `gorm:"not null"`
Type TokenType `gorm:"not null"`
UserID uint `gorm:"not null"`
}
func createOneUseToken(db *gorm.DB, t TokenType, userId uint) error {
token, err := generateString(8)
if err != nil {
slog.Error("createOneUseToken: Failed to generate string!", "error", err)
return errors.New("failed to generate token")
}
res := db.Create(Token{Type: t, Value: token, UserID: userId})
if res.Error != nil {
slog.Error("createOneUseToken: Failed to insert token into db!", "error", res.Error)
return errors.New("failed to generate token")
}
return nil
}
// Cleans up tokens older than 2m.
func cleanupTokens(db *gorm.DB) {
fiveMinsAgo := time.Now().Add(-2 * time.Minute)
db.Where("created_at < ?", fiveMinsAgo).Delete(&Token{})
}
+3 -1
View File
@@ -68,7 +68,7 @@ func main() {
log.Fatal("Failed to connect to database:", err)
}
err = db.AutoMigrate(&User{}, &Content{}, &Watched{}, &Activity{})
err = db.AutoMigrate(&User{}, &Content{}, &Watched{}, &Activity{}, &Token{})
if err != nil {
log.Fatal("Failed to auto migrate database:", err)
}
@@ -122,6 +122,8 @@ func main() {
br.addImportRoutes()
br.rg.Static("/img", "./data/img")
go setupTasks(db)
gine.Run("0.0.0.0:3080")
}