- 运行时分类体系:Shell/Python/JavaScript/Ruby/PHP 各含变体 - 用户注册/登录(JWT + bcrypt),首个注册用户为管理员 - 管理后台 /admin 动态管理分类和变体 - 脚本市场支持按分类筛选 - CodeMirror 语言模式根据分类名称自动切换 - 结果页展示该分类下所有变体的运行命令 - source 命令变体用于 Shell 类继承环境变量 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
54 lines
1.1 KiB
Go
54 lines
1.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"gitea.kmux.cn/zhilv/scriptforge/internal/auth"
|
|
)
|
|
|
|
func JWTAuth(authSvc *auth.AuthService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
tokenStr := ""
|
|
|
|
// Check Authorization header
|
|
authHeader := c.GetHeader("Authorization")
|
|
if strings.HasPrefix(authHeader, "Bearer ") {
|
|
tokenStr = strings.TrimPrefix(authHeader, "Bearer ")
|
|
}
|
|
|
|
// Also check query param for convenience
|
|
if tokenStr == "" {
|
|
tokenStr = c.Query("token")
|
|
}
|
|
|
|
if tokenStr == "" {
|
|
c.Next() // No token, proceed as anonymous
|
|
return
|
|
}
|
|
|
|
claims, err := authSvc.ParseToken(tokenStr)
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
|
|
return
|
|
}
|
|
|
|
c.Set("user_id", claims.UserID)
|
|
c.Set("username", claims.Username)
|
|
c.Set("role", claims.Role)
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
func AdminOnly(authSvc *auth.AuthService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
role, exists := c.Get("role")
|
|
if !exists || role != "admin" {
|
|
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "admin only"})
|
|
return
|
|
}
|
|
c.Next()
|
|
}
|
|
} |