split and add api routes

This commit is contained in:
2026-03-02 21:49:53 +01:00
parent dd713b7afd
commit f6c0bb7343
4 changed files with 124 additions and 39 deletions

79
src/auth/auth.go Normal file
View File

@@ -0,0 +1,79 @@
package auth
import (
"fmt"
"time"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
)
var jwtSecret = []byte("SUPER_SECRET_CHANGE_THIS")
type Claims struct {
Username string `json:"username"`
jwt.RegisteredClaims
}
func GenerateToken(username string) (string, error) {
expirationTime := time.Now().Add(24 * time.Hour)
claims := &Claims{
Username: username,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(expirationTime),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(jwtSecret)
}
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
var tokenStr string
// 1⃣ Check Authorization header (Bearer token)
authHeader := c.GetHeader("Authorization")
if len(authHeader) > 7 && authHeader[:7] == "Bearer " {
tokenStr = authHeader[7:]
}
// 2⃣ Fallback to cookie if no Bearer token
if tokenStr == "" {
cookie, err := c.Cookie("auth")
if err == nil {
tokenStr = cookie
}
}
if tokenStr == "" {
c.Redirect(302, "/login")
return
}
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
// Validate signing method
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method")
}
return jwtSecret, nil
})
if err != nil || !token.Valid {
c.AbortWithStatusJSON(401, gin.H{"error": "invalid or expired token"})
return
}
// Store user in context
c.Set("username", claims.Username)
c.Next()
}
}

View File

@@ -1,6 +1,7 @@
package main
import (
"Backend/src/auth"
"fmt"
"io"
"os"
@@ -13,6 +14,11 @@ import (
"golang.org/x/crypto/bcrypt"
)
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
func uploadHandler(c *gin.Context) {
err := c.Request.ParseMultipartForm(0) // unlimited
if err != nil {
@@ -143,7 +149,7 @@ func loginHandler(c *gin.Context) {
return
}
token, _ := generateToken(username)
token, _ := auth.GenerateToken(username)
c.SetCookie(
"auth",
@@ -158,6 +164,41 @@ func loginHandler(c *gin.Context) {
c.Redirect(302, "/admin")
}
func apiLoginHandler(c *gin.Context) {
var req LoginRequest
// Bind JSON body
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": "Invalid request body"})
return
}
var user User
if err := db.Where("username = ?", req.Username).First(&user).Error; err != nil {
c.JSON(401, gin.H{"error": "Invalid credentials"})
return
}
if bcrypt.CompareHashAndPassword(
[]byte(user.Password),
[]byte(req.Password),
) != nil {
c.JSON(401, gin.H{"error": "Invalid credentials"})
return
}
// Generate JWT
token, err := auth.GenerateToken(user.Username)
if err != nil {
c.JSON(500, gin.H{"error": "Could not generate token"})
return
}
c.JSON(200, gin.H{
"token": token,
})
}
func adminIndexHandler(c *gin.Context) {
var files []FileRecord

View File

@@ -1,6 +1,7 @@
package main
import (
"Backend/src/auth"
"fmt"
"html/template"
"log"
@@ -52,9 +53,10 @@ func main() {
router.GET("/api/file/delete/:del_id", deleteHandler)
router.POST("/api/upload", uploadHandler)
router.POST("/api/login", apiLoginHandler)
admin := router.Group("/admin")
admin.Use(authMiddleware())
admin.Use(auth.AuthMiddleware())
admin.GET("/", adminIndexHandler)
admin.GET("/delete/fr/:id", func(c *gin.Context) {

View File

@@ -5,9 +5,6 @@ import (
"os"
"path/filepath"
"time"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
)
func performDeletion(r *FileRecord) {
@@ -39,40 +36,6 @@ func cleanupWorker() {
}
}
var jwtSecret = []byte("SUPER_SECRET_CHANGE_THIS")
func generateToken(username string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
})
return token.SignedString(jwtSecret)
}
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenStr, err := c.Cookie("auth")
if err != nil {
c.Redirect(302, "/login")
c.Abort()
return
}
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
return jwtSecret, nil
})
if err != nil || !token.Valid {
c.Redirect(302, "/login")
c.Abort()
return
}
c.Next()
}
}
func humanSize(size int64) string {
const unit = 1024
if size < unit {