把工作区里其余在制品一并入库,主要是工作台产品化的推进:
后端:新增 capability_definition / project / my_app_center / office_skill
接口与 action_definition / skill_definition / project / user_app_center
模型,config 加路由健康上报。
前端:新增 frontend/src/skills(Office 技能与 workbuddy 复刻)、
项目管理、应用中心、能力目录页,以及配套 api / store / config;
聊天侧新增 SpecialistChip / SpecialistPanel / SkillStrip / AppChatRail
等组件。
清理:移除旧 views/tools 下的单页工具(已并入工作台)、_frozen 冻结组件、
cmd/inspect_oa_debug 调试入口,以及两份调试笔记。
其它:文档与启动脚本同步。
(这批改动与上一提交的 SY23 工作并行进行,此前已在同一工作区内交织。)
Co-Authored-By: Claude Code <noreply@anthropic.com>
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package middleware
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"eai_agentplatform/backend/internal/auth"
|
|
"eai_agentplatform/backend/internal/config"
|
|
"eai_agentplatform/backend/internal/model"
|
|
"eai_agentplatform/backend/internal/store"
|
|
"eai_agentplatform/backend/internal/web"
|
|
)
|
|
|
|
// Auth 解析 JWT → 校验用户 → 注入 current_user
|
|
func Auth(cfg *config.Config) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
tokenStr := extractBearer(c)
|
|
if tokenStr == "" {
|
|
web.Fail(c, web.NewAuthError("缺少 Authorization Bearer 令牌"))
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
claims, err := auth.ParseToken(tokenStr, cfg.JWTSecret)
|
|
if err != nil {
|
|
web.Fail(c, web.NewAuthError("令牌无效或已过期"))
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
username, _ := claims["sub"].(string)
|
|
if username == "" {
|
|
web.Fail(c, web.NewAuthError("令牌中缺少用户标识"))
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
var user model.User
|
|
if err := store.DB.Where("username = ?", username).First(&user).Error; err != nil {
|
|
web.Fail(c, web.NewAuthError("用户不存在"))
|
|
c.Abort()
|
|
return
|
|
}
|
|
if user.Status != "active" {
|
|
web.Fail(c, web.NewAuthError("账号已禁用"))
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
c.Set("current_user", &user)
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// RequireAdmin 管理员角色守卫(须在 Auth 之后)
|
|
func RequireAdmin() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
u := CurrentUser(c)
|
|
if u == nil || u.Role != "admin" {
|
|
web.Fail(c, web.NewForbiddenError("需要管理员权限"))
|
|
c.Abort()
|
|
return
|
|
}
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// CurrentUser 从 context 取当前用户(可能为 nil)
|
|
func CurrentUser(c *gin.Context) *model.User {
|
|
if v, ok := c.Get("current_user"); ok {
|
|
if u, ok := v.(*model.User); ok {
|
|
return u
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func extractBearer(c *gin.Context) string {
|
|
h := c.GetHeader("Authorization")
|
|
if strings.HasPrefix(h, "Bearer ") {
|
|
return strings.TrimSpace(h[len("Bearer "):])
|
|
}
|
|
return ""
|
|
}
|