init: web_hgcg_server 初始化提交
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"videoweb/pub/common"
|
||||
"videoweb/pub/common/errors"
|
||||
"videoweb/pub/common/ipaddr"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/common/srvdef"
|
||||
"videoweb/pub/common/utils"
|
||||
"videoweb/pub/models/mwacc"
|
||||
"videoweb/pub/models/oplog"
|
||||
"videoweb/web/webg"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
var (
|
||||
RoleApiMenus = map[int64][]string{} // 角色Api
|
||||
mutex sync.RWMutex
|
||||
)
|
||||
|
||||
var (
|
||||
tokener = utils.NewTokenRedis()
|
||||
)
|
||||
|
||||
const (
|
||||
AccId = "ACC_ID"
|
||||
roleAuthAdrr = "/web/role/getauth"
|
||||
)
|
||||
|
||||
type APIInfo struct {
|
||||
Api string
|
||||
Desc string
|
||||
}
|
||||
|
||||
var (
|
||||
// 白名单,不需要验证token的api
|
||||
whiteList = []string{
|
||||
"/swagger",
|
||||
"/api/web/file/uploadImg",
|
||||
"/api/web/file/uploadImgs",
|
||||
"/api/web/media/videoBody",
|
||||
"/api/web/media/videoOk",
|
||||
"/api/web/m3u8",
|
||||
"/api/web/uploader/m3u8",
|
||||
"/api/web/enkey",
|
||||
"/api/web/newenkey",
|
||||
"/api/web/login/acc",
|
||||
"/api/web/login/bind",
|
||||
"/api/web/login/slogin",
|
||||
"/api/web/stat/media/list",
|
||||
"/api/web/stat/analytics",
|
||||
"/api/web/stat/daily/analytics",
|
||||
"/api/web/sync/video/list",
|
||||
"/api/web/sync/videocollection/list",
|
||||
"/api/web/sync/category/list",
|
||||
"/api/web/sync/creator/list",
|
||||
"/api/web/sync/tag/list",
|
||||
"/wbapi",
|
||||
"/api/web/third/newpaycenter/recharge/callback",
|
||||
}
|
||||
)
|
||||
|
||||
// 读取角色信息
|
||||
func GetRoleApiMenus(ctx context.Context, accid int64) (roles []string, err error) {
|
||||
mutex.RLock()
|
||||
roles, ok := RoleApiMenus[accid]
|
||||
mutex.RUnlock()
|
||||
if !ok {
|
||||
accInfo, dataErr := mwacc.FindOneAccByFilter(nil, bson.M{mwacc.FN.MwAcc.Id: accid})
|
||||
if dataErr != nil || accInfo.Id == 0 {
|
||||
return roles, dataErr
|
||||
}
|
||||
|
||||
roleInfo, roleErr := mwacc.FindOneRoleByFilter(ctx, bson.M{mwacc.FN.MwRole.Id: accInfo.RoleId})
|
||||
|
||||
if roleErr != nil || roleInfo.Id == 0 {
|
||||
return roles, roleErr
|
||||
}
|
||||
|
||||
if roleInfo.Name == "超级管理员" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
RoleApiMenus[accid] = roleInfo.ApiMenus
|
||||
mutex.Unlock()
|
||||
roles = roleInfo.ApiMenus
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 是否角色api
|
||||
func HasRoleApi(path string, apis []string) bool {
|
||||
apimap := make(map[string]struct{})
|
||||
for _, v := range apis {
|
||||
apimap[v] = struct{}{}
|
||||
}
|
||||
_, ok := apimap[path]
|
||||
return ok
|
||||
}
|
||||
|
||||
// 角色权限
|
||||
func handleRoles(ctx *gin.Context) (int, error) {
|
||||
path := ctx.Request.URL.Path
|
||||
if strings.HasPrefix(path, roleAuthAdrr) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
accid := ctx.GetInt(AccId)
|
||||
apis, err := GetRoleApiMenus(ctx, int64(accid))
|
||||
if err != nil {
|
||||
return int(errors.RoleErr), err
|
||||
}
|
||||
if apis == nil {
|
||||
return 0, nil
|
||||
}
|
||||
has := HasRoleApi(path, apis)
|
||||
if !has {
|
||||
return int(errors.RoleErr), srvdef.New(srvdef.RoleErr, (srvdef.RoleErr).Msg(), "")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// 验证后台账号IP
|
||||
func authMwIP(ctx *gin.Context) (int, error) {
|
||||
|
||||
cIP := ipaddr.ResolveClientIP(ctx)
|
||||
accid := ctx.GetInt64(AccId)
|
||||
accInfo, dataErr := mwacc.FindOneAccByFilter(nil, bson.M{mwacc.FN.MwAcc.Id: accid})
|
||||
if dataErr != nil || accInfo.Id == 0 {
|
||||
return int(errors.RoleErr), dataErr
|
||||
}
|
||||
if len(accInfo.LimitIP) != 0 {
|
||||
for _, v := range accInfo.LimitIP {
|
||||
if v == cIP {
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
return int(errors.LimitIPErr), dataErr
|
||||
} else {
|
||||
return int(errors.LimitIPErr), dataErr
|
||||
}
|
||||
|
||||
// return 0, nil
|
||||
}
|
||||
|
||||
// 验证
|
||||
func Auth(ctx *gin.Context) {
|
||||
//for test
|
||||
//ctx.Set(AccId, int64(1000))
|
||||
//return
|
||||
// 对指定 group 跳过
|
||||
if strings.HasPrefix(ctx.Request.URL.Path, "/mdps/mdcom/api/web") {
|
||||
ctx.Next()
|
||||
return
|
||||
}
|
||||
p := ctx.Request.URL.Path
|
||||
if strings.Contains(p, "swagger") {
|
||||
return
|
||||
}
|
||||
for _, w := range whiteList {
|
||||
if strings.HasPrefix(ctx.Request.URL.Path, w) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if v, ok := common.ApiSetMaps[p]; ok {
|
||||
fmt.Println(v.IsWhite)
|
||||
if v.IsWhite {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
doToken := func() (int, error) {
|
||||
checkToken := ctx.Request.Header.Get("Authorization")
|
||||
// 去掉Bearer,如果有
|
||||
checkToken = utils.StripBearerPrefixFromTokenString(checkToken)
|
||||
|
||||
if checkToken == "" {
|
||||
return http.StatusUnauthorized, srvdef.New(srvdef.NoToken, (srvdef.NoToken).Msg(), "")
|
||||
}
|
||||
|
||||
has, err := mwacc.CheckToken(ctx, checkToken)
|
||||
if err != nil {
|
||||
return http.StatusUnauthorized, err
|
||||
}
|
||||
if !has {
|
||||
return http.StatusUnauthorized, srvdef.New(srvdef.ReLogin, (srvdef.ReLogin).Msg(), "")
|
||||
}
|
||||
|
||||
userId, _, err := utils.ParseUserToken(checkToken, webg.Conf.JwtKey)
|
||||
if err != nil {
|
||||
return http.StatusUnauthorized, srvdef.New(srvdef.InvalidToken, (srvdef.InvalidToken).Msg(), "")
|
||||
}
|
||||
// log.Info("Auth test", log.Any("checkToken", checkToken), log.Any("userId", userId))
|
||||
ctx.Set(AccId, userId)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
statusCode, err := doToken()
|
||||
if err != nil || statusCode != 0 {
|
||||
ctx.AbortWithStatusJSON(statusCode, err)
|
||||
return
|
||||
}
|
||||
|
||||
roleCode, err := handleRoles(ctx)
|
||||
if err != nil || roleCode != 0 {
|
||||
ctx.AbortWithStatusJSON(http.StatusForbidden, err)
|
||||
}
|
||||
|
||||
// authIPCode, err2 := authMwIP(ctx)
|
||||
// if err2 != nil || authIPCode != 0 {
|
||||
// ctx.AbortWithStatusJSON(http.StatusForbidden, err)
|
||||
// }
|
||||
}
|
||||
|
||||
// func userAgentHandler(ctx *gin.Context) {
|
||||
// userAgent := ctx.Request.Header.Get("User-Agent")
|
||||
// if userAgent != "" {
|
||||
// fields := strings.Fields(userAgent)
|
||||
// curVersion := fields[len(fields)-1]
|
||||
// if strings.HasPrefix(curVersion, "version:") {
|
||||
// versionNum := strings.Split(curVersion, ":")[1]
|
||||
// ctx.Set("VERSION", versionNum)
|
||||
// } else {
|
||||
// ctx.Set("VERSION", "")
|
||||
// }
|
||||
// }
|
||||
// if strings.Contains(userAgent, "Android") {
|
||||
// ctx.Set("SYSTEM", "android")
|
||||
// }
|
||||
// if strings.Contains(userAgent, "iPhone") {
|
||||
// ctx.Set("SYSTEM", "ios")
|
||||
// }
|
||||
|
||||
// // 增加 不签名,不加密 开关
|
||||
// }
|
||||
|
||||
// 操作日志
|
||||
func OperateLog(ctx *gin.Context) {
|
||||
desc := ""
|
||||
find := false
|
||||
for _, w := range LogList {
|
||||
if ctx.Request.URL.Path == w.Api {
|
||||
find = true
|
||||
desc = w.Desc
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
ctx.Next()
|
||||
return
|
||||
}
|
||||
|
||||
accId := ctx.GetInt64(AccId)
|
||||
rawData, err := ctx.GetRawData()
|
||||
ip := ipaddr.ResolveClientIP(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithStatusJSON(400, err)
|
||||
}
|
||||
|
||||
log.Info("OperateLog Test", log.Any("vmap.Path", ctx.Request.URL.Path))
|
||||
|
||||
err = oplog.AddLog(ctx, ctx.Request.URL.Path, desc, accId, string(rawData), ip)
|
||||
if err != nil {
|
||||
ctx.AbortWithStatusJSON(int(errors.OperateLog), err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(rawData)) // 将取出来的执行条件放回ctx中
|
||||
ctx.Next()
|
||||
}
|
||||
|
||||
func GetAccount(ctx *gin.Context) int64 {
|
||||
return ctx.GetInt64(AccId)
|
||||
}
|
||||
Reference in New Issue
Block a user