2024-05-18 17:12:24 +08:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2024-12-04 16:59:30 +08:00
|
|
|
|
"encoding/json"
|
|
|
|
|
|
"fmt"
|
2024-05-18 17:12:24 +08:00
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
"github.com/golang-jwt/jwt"
|
2024-11-06 15:13:06 +08:00
|
|
|
|
"github.com/robfig/cron/v3"
|
2024-06-12 18:03:19 +08:00
|
|
|
|
"io"
|
2024-11-06 15:13:06 +08:00
|
|
|
|
"log"
|
2024-07-05 11:38:59 +08:00
|
|
|
|
"os"
|
2024-05-18 18:16:34 +08:00
|
|
|
|
"strings"
|
2024-05-18 17:12:24 +08:00
|
|
|
|
"videoplayer/dao"
|
|
|
|
|
|
"videoplayer/handler"
|
2024-06-25 09:38:21 +08:00
|
|
|
|
"videoplayer/proto"
|
2024-12-11 16:10:56 +08:00
|
|
|
|
"videoplayer/service"
|
2024-05-18 17:12:24 +08:00
|
|
|
|
"videoplayer/worker"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
2024-07-06 20:18:56 +08:00
|
|
|
|
gin.SetMode(gin.ReleaseMode)
|
2024-09-27 21:13:56 +08:00
|
|
|
|
r := gin.Default()
|
2024-08-02 10:30:41 +08:00
|
|
|
|
err := dao.Init()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
panic("failed to connect database:" + err.Error())
|
|
|
|
|
|
}
|
|
|
|
|
|
err = worker.InitRedis()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
panic("failed to connect redis:" + err.Error())
|
|
|
|
|
|
}
|
2024-05-28 15:15:02 +08:00
|
|
|
|
r.Use(handler.CrosHandler())
|
2024-06-27 10:53:47 +08:00
|
|
|
|
r.Use(JWTAuthMiddleware()) // 使用 JWT 认证中间件
|
|
|
|
|
|
handler.SetUpVideoGroup(r) // Video
|
|
|
|
|
|
handler.SetUpUserGroup(r) // User
|
|
|
|
|
|
handler.SetUpDeviceGroup(r) // Device
|
|
|
|
|
|
handler.SetUpIMGroup(r) // IM
|
2024-07-04 18:31:04 +08:00
|
|
|
|
handler.SetUpCIDGroup(r) // CID,持续集成、部署
|
2024-07-21 11:00:08 +08:00
|
|
|
|
handler.SetUpToolGroup(r) // Tool
|
2024-05-18 18:16:34 +08:00
|
|
|
|
defer dao.Close()
|
|
|
|
|
|
defer worker.CloseRedis()
|
2024-11-06 15:13:06 +08:00
|
|
|
|
//定时任务
|
|
|
|
|
|
c := cron.New(cron.WithSeconds())
|
|
|
|
|
|
// 添加每 10 秒执行一次的任务
|
|
|
|
|
|
_, err = c.AddFunc("@every 10s", myTask)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Fatal("添加定时任务失败: ", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
c.Start()
|
2024-12-04 16:59:30 +08:00
|
|
|
|
//读取配置文件,设置系统
|
|
|
|
|
|
ReadConfigToSetSystem()
|
2024-11-07 15:45:27 +08:00
|
|
|
|
r.Run(":" + proto.Config.SERVER_PORT) // listen and serve on 0.0.0.0:8083
|
2024-05-18 17:12:24 +08:00
|
|
|
|
}
|
2024-07-05 11:38:59 +08:00
|
|
|
|
func init() {
|
|
|
|
|
|
// 创建cid的目录
|
|
|
|
|
|
os.MkdirAll(proto.CID_BASE_DIR, os.ModePerm)
|
|
|
|
|
|
os.MkdirAll(proto.CID_BASE_DIR+"script", os.ModePerm)
|
|
|
|
|
|
os.MkdirAll(proto.CID_BASE_DIR+"workspace", os.ModePerm)
|
2024-09-22 13:59:33 +08:00
|
|
|
|
//读取配置文件
|
|
|
|
|
|
//文件地址/home/videoplayer/vp.conf
|
|
|
|
|
|
configPath := "/home/videoplayer/vp.conf"
|
|
|
|
|
|
//读取配置文件
|
|
|
|
|
|
err := proto.ReadConfig(configPath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
panic("failed to read config file:" + err.Error())
|
|
|
|
|
|
}
|
2024-07-05 11:38:59 +08:00
|
|
|
|
}
|
2024-05-18 17:12:24 +08:00
|
|
|
|
|
2024-06-10 12:23:34 +08:00
|
|
|
|
func writeLogger(c *gin.Context) {
|
|
|
|
|
|
ip := c.ClientIP()
|
|
|
|
|
|
method := c.Request.Method
|
|
|
|
|
|
path := c.Request.URL.Path
|
|
|
|
|
|
params := ""
|
2024-08-30 15:03:33 +08:00
|
|
|
|
|
2024-06-10 12:23:34 +08:00
|
|
|
|
if method == "GET" {
|
|
|
|
|
|
params = c.Request.URL.RawQuery
|
|
|
|
|
|
}
|
2024-08-30 15:03:33 +08:00
|
|
|
|
if method == "POST" && !strings.Contains(c.Request.URL.Path, "/upload") {
|
2024-06-12 18:03:19 +08:00
|
|
|
|
params = c.Request.PostForm.Encode()
|
|
|
|
|
|
if params == "" {
|
2024-06-13 11:11:05 +08:00
|
|
|
|
// 请求体
|
|
|
|
|
|
bodyBytes, _ := io.ReadAll(c.Request.Body)
|
|
|
|
|
|
c.Request.Body = io.NopCloser(strings.NewReader(string(bodyBytes))) // Write body back, so other handler can read it too
|
2024-06-12 18:03:19 +08:00
|
|
|
|
params = string(bodyBytes)
|
2024-06-12 17:43:15 +08:00
|
|
|
|
}
|
2024-06-10 12:23:34 +08:00
|
|
|
|
}
|
2024-08-30 15:03:33 +08:00
|
|
|
|
if strings.Contains(c.Request.URL.Path, "/upload") {
|
|
|
|
|
|
params = "upload file"
|
|
|
|
|
|
}
|
2024-06-14 17:59:53 +08:00
|
|
|
|
go dao.InsertLogToDB(path, ip, method, params)
|
2024-06-09 14:22:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-18 17:12:24 +08:00
|
|
|
|
func JWTAuthMiddleware() gin.HandlerFunc {
|
|
|
|
|
|
return func(c *gin.Context) {
|
2024-12-04 16:59:30 +08:00
|
|
|
|
if proto.Config.LOG_SAVE_DAYS > 0 {
|
|
|
|
|
|
writeLogger(c)
|
|
|
|
|
|
}
|
2024-05-18 17:12:24 +08:00
|
|
|
|
// 从请求头中获取 JWT 令牌
|
2024-05-28 15:15:02 +08:00
|
|
|
|
tokenString := c.Request.Header.Get("token")
|
2024-05-18 17:12:24 +08:00
|
|
|
|
|
|
|
|
|
|
//请求方式为get时,从url中获取token
|
|
|
|
|
|
if tokenString == "" {
|
|
|
|
|
|
tokenString = c.Query("token")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//如果请求为login或register,则不需要验证token
|
2024-10-07 15:22:58 +08:00
|
|
|
|
for k, _ := range proto.Url_map {
|
|
|
|
|
|
if strings.Contains(c.Request.URL.Path, k) {
|
|
|
|
|
|
c.Next()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-05-18 17:12:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
if tokenString == "" {
|
2024-05-28 15:15:02 +08:00
|
|
|
|
//c.AbortWithStatus(200)
|
|
|
|
|
|
c.JSON(200, gin.H{
|
2024-05-18 17:12:24 +08:00
|
|
|
|
"message": "Unauthorized",
|
|
|
|
|
|
"error": "token is empty",
|
2024-06-25 09:38:21 +08:00
|
|
|
|
"code": proto.TokenIsNull,
|
2024-05-18 17:12:24 +08:00
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-09-22 13:59:33 +08:00
|
|
|
|
if proto.Config.TOKEN_USE_REDIS {
|
|
|
|
|
|
redisToken := worker.GetRedis(tokenString)
|
|
|
|
|
|
if redisToken == "" {
|
|
|
|
|
|
c.AbortWithStatus(200)
|
|
|
|
|
|
c.JSON(200, gin.H{
|
|
|
|
|
|
"message": "NOT_LOGIN",
|
|
|
|
|
|
"error": "server token is empty",
|
|
|
|
|
|
"code": proto.TokenIsNull,
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-05-18 18:16:34 +08:00
|
|
|
|
}
|
2024-12-04 16:07:51 +08:00
|
|
|
|
//查看token是否在超级token中
|
|
|
|
|
|
if worker.IsContainSet("super_permission_tokens", tokenString) {
|
|
|
|
|
|
s_id := c.Request.Header.Get("super_id")
|
|
|
|
|
|
if s_id == "" {
|
|
|
|
|
|
c.AbortWithStatus(200)
|
|
|
|
|
|
c.JSON(200, gin.H{
|
|
|
|
|
|
"message": "NOT_LOGIN",
|
|
|
|
|
|
"error": "super_id is empty",
|
|
|
|
|
|
"code": proto.TokenIsNull,
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
c.Set("id", s_id)
|
|
|
|
|
|
c.Next()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2024-05-18 17:12:24 +08:00
|
|
|
|
|
2024-09-22 13:59:33 +08:00
|
|
|
|
// 使用加密secret 解析 JWT 令牌
|
2024-05-18 17:12:24 +08:00
|
|
|
|
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
2024-09-22 13:59:33 +08:00
|
|
|
|
return proto.SigningKey, nil
|
2024-05-18 17:12:24 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 验证令牌
|
|
|
|
|
|
if err != nil || !token.Valid {
|
2024-05-28 15:15:02 +08:00
|
|
|
|
c.AbortWithStatus(200)
|
|
|
|
|
|
c.JSON(200, gin.H{
|
|
|
|
|
|
"message": "NOT_LOGIN",
|
2024-05-18 17:12:24 +08:00
|
|
|
|
"error": "Invalid token",
|
2024-06-25 09:38:21 +08:00
|
|
|
|
"code": proto.TokenExpired,
|
2024-05-18 17:12:24 +08:00
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 将用户信息添加到上下文中
|
|
|
|
|
|
c.Set("id", token.Claims.(jwt.MapClaims)["id"])
|
|
|
|
|
|
c.Set("username", token.Claims.(jwt.MapClaims)["username"])
|
|
|
|
|
|
|
2024-12-04 18:39:57 +08:00
|
|
|
|
if UserFuncIntercept(int(token.Claims.(jwt.MapClaims)["id"].(float64)), c.Request.URL.Path) {
|
|
|
|
|
|
c.AbortWithStatus(200)
|
|
|
|
|
|
c.JSON(200, gin.H{
|
|
|
|
|
|
"message": "no function permission",
|
|
|
|
|
|
"error": "no permission",
|
|
|
|
|
|
"code": proto.NoPermission,
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-18 17:12:24 +08:00
|
|
|
|
// 继续处理请求
|
|
|
|
|
|
c.Next()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-11-06 15:13:06 +08:00
|
|
|
|
|
|
|
|
|
|
func myTask() {
|
|
|
|
|
|
// 定时任务
|
|
|
|
|
|
//redis中取出数据
|
|
|
|
|
|
handler.RunCron()
|
2024-11-07 15:45:27 +08:00
|
|
|
|
if proto.Config.MONITOR {
|
|
|
|
|
|
handler.ScanDeviceStatus()
|
|
|
|
|
|
}
|
2024-12-04 16:59:30 +08:00
|
|
|
|
//其它定时任务-通用
|
|
|
|
|
|
RunGeneralCron()
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func ReadConfigToSetSystem() {
|
|
|
|
|
|
//redis添加通用定时任务
|
|
|
|
|
|
key := "cron_info"
|
|
|
|
|
|
//日志清理
|
|
|
|
|
|
res := worker.GetRedis(key)
|
|
|
|
|
|
var cron_infos []proto.CronInfo
|
|
|
|
|
|
if res != "" {
|
|
|
|
|
|
err := json.Unmarshal([]byte(res), &cron_infos)
|
|
|
|
|
|
if err != nil {
|
2024-12-04 19:09:08 +08:00
|
|
|
|
fmt.Println("ReadConfigToSetSystem Error decoding config,key value is :", res)
|
2024-12-04 16:59:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//查看清除日志任务是否存在
|
|
|
|
|
|
if proto.Config.LOG_SAVE_DAYS > 0 {
|
|
|
|
|
|
var is_exist bool
|
|
|
|
|
|
for _, v := range cron_infos {
|
|
|
|
|
|
if v.Type == 1 {
|
|
|
|
|
|
is_exist = true
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if !is_exist {
|
|
|
|
|
|
var logClean proto.CronInfo
|
|
|
|
|
|
logClean.Type = 1
|
|
|
|
|
|
logClean.Info = "日志清理"
|
|
|
|
|
|
logClean.Curr = 86400
|
|
|
|
|
|
logClean.Every = 86400
|
|
|
|
|
|
cron_infos = append(cron_infos, logClean)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-15 14:54:43 +08:00
|
|
|
|
|
|
|
|
|
|
var is_exist bool
|
|
|
|
|
|
user_sync_id := -1
|
|
|
|
|
|
for i, v := range cron_infos {
|
|
|
|
|
|
if v.Type == 2 {
|
|
|
|
|
|
is_exist = true
|
|
|
|
|
|
if proto.Config.USER_SYNC_TIME != v.Every {
|
|
|
|
|
|
v.Every = proto.Config.USER_SYNC_TIME
|
|
|
|
|
|
v.Curr = proto.Config.USER_SYNC_TIME
|
2024-12-11 16:10:56 +08:00
|
|
|
|
}
|
2024-12-15 14:54:43 +08:00
|
|
|
|
user_sync_id = i
|
|
|
|
|
|
break
|
2024-12-11 16:10:56 +08:00
|
|
|
|
}
|
2024-12-15 14:54:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
if proto.Config.SERVER_USER_TYPE == "slave" {
|
|
|
|
|
|
if proto.Config.USER_SYNC_TIME > 0 && !is_exist {
|
2024-12-11 16:10:56 +08:00
|
|
|
|
var userSync proto.CronInfo
|
|
|
|
|
|
userSync.Type = 2
|
|
|
|
|
|
userSync.Info = "user"
|
|
|
|
|
|
userSync.Curr = proto.Config.USER_SYNC_TIME
|
|
|
|
|
|
userSync.Every = proto.Config.USER_SYNC_TIME
|
|
|
|
|
|
cron_infos = append(cron_infos, userSync)
|
2024-12-15 14:54:43 +08:00
|
|
|
|
} else if user_sync_id != -1 {
|
|
|
|
|
|
cron_infos = append(cron_infos[:user_sync_id], cron_infos[user_sync_id+1:]...) //删除
|
2024-12-11 16:10:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-04 16:59:30 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
if proto.Config.LOG_SAVE_DAYS > 0 {
|
|
|
|
|
|
var logClean proto.CronInfo
|
|
|
|
|
|
logClean.Type = 1
|
|
|
|
|
|
logClean.Info = "日志清理"
|
|
|
|
|
|
logClean.Curr = 86400
|
|
|
|
|
|
logClean.Every = 86400
|
|
|
|
|
|
cron_infos = append(cron_infos, logClean)
|
|
|
|
|
|
}
|
2024-12-11 16:10:56 +08:00
|
|
|
|
if proto.Config.SERVER_USER_TYPE == "slave" && proto.Config.USER_SYNC_TIME > 0 {
|
|
|
|
|
|
var userSync proto.CronInfo
|
|
|
|
|
|
userSync.Type = 2
|
|
|
|
|
|
userSync.Info = "user"
|
|
|
|
|
|
userSync.Curr = proto.Config.USER_SYNC_TIME
|
|
|
|
|
|
userSync.Every = proto.Config.USER_SYNC_TIME
|
|
|
|
|
|
cron_infos = append(cron_infos, userSync)
|
|
|
|
|
|
}
|
2024-12-04 16:59:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
//存入redis
|
2024-12-04 19:13:38 +08:00
|
|
|
|
json_data, err := json.Marshal(cron_infos)
|
2024-12-04 16:59:30 +08:00
|
|
|
|
if err != nil {
|
2024-12-04 19:13:38 +08:00
|
|
|
|
fmt.Println("ReadConfigToSetSystem Error encoding config,value is :", cron_infos)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
worker.SetRedis(key, string(json_data))
|
2024-12-04 16:59:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func RunGeneralCron() {
|
|
|
|
|
|
//redis添加通用定时任务
|
|
|
|
|
|
key := "cron_info"
|
|
|
|
|
|
//日志清理
|
|
|
|
|
|
res := worker.GetRedis(key)
|
|
|
|
|
|
var cron_infos []proto.CronInfo
|
|
|
|
|
|
if res != "" {
|
2024-12-04 19:16:13 +08:00
|
|
|
|
err := json.Unmarshal([]byte(res), &cron_infos)
|
2024-12-04 16:59:30 +08:00
|
|
|
|
if err != nil {
|
2024-12-04 19:09:08 +08:00
|
|
|
|
fmt.Println("RunGeneralCron Error decoding config,key value is :", res)
|
2024-12-04 16:59:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
for _, v := range cron_infos {
|
|
|
|
|
|
//1:日志清理,其他待定
|
|
|
|
|
|
if v.Type == 1 {
|
|
|
|
|
|
//日志清理
|
|
|
|
|
|
if v.Curr <= 0 {
|
|
|
|
|
|
//执行日志清理
|
|
|
|
|
|
go dao.DeleteLog(proto.Config.LOG_SAVE_DAYS)
|
|
|
|
|
|
v.Curr = v.Every
|
|
|
|
|
|
} else {
|
|
|
|
|
|
v.Curr -= 10
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-11 16:10:56 +08:00
|
|
|
|
//2 从服务器同步数据
|
|
|
|
|
|
if v.Type == 2 {
|
|
|
|
|
|
if v.Curr <= 0 {
|
|
|
|
|
|
//执行从服务器同步数据
|
|
|
|
|
|
if proto.Config.SERVER_USER_TYPE == "slave" && v.Info == "user" {
|
|
|
|
|
|
go service.UserSyncDataFromMaster()
|
|
|
|
|
|
}
|
|
|
|
|
|
v.Curr = v.Every
|
|
|
|
|
|
} else {
|
|
|
|
|
|
v.Curr -= 10
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-04 16:59:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
//存入redis
|
2024-12-04 19:13:38 +08:00
|
|
|
|
json_data, err := json.Marshal(cron_infos)
|
2024-12-04 16:59:30 +08:00
|
|
|
|
if err != nil {
|
2024-12-04 19:09:08 +08:00
|
|
|
|
fmt.Println("RunGeneralCron Error encoding config,value is :", cron_infos)
|
2024-12-04 19:13:38 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
worker.SetRedis(key, string(json_data))
|
2024-12-04 16:59:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-11-06 15:13:06 +08:00
|
|
|
|
}
|
2024-12-04 18:39:57 +08:00
|
|
|
|
|
|
|
|
|
|
// 用户功能拦截,返回true表示拦截,false表示不拦截
|
|
|
|
|
|
func UserFuncIntercept(id int, url string) bool {
|
|
|
|
|
|
//先查看是否有权限
|
|
|
|
|
|
user := dao.FindUserByUserID(id)
|
|
|
|
|
|
//如果用户有权限,则不拦截
|
|
|
|
|
|
for k, v := range proto.Per_menu_map {
|
|
|
|
|
|
if strings.Contains(url, k) {
|
2024-12-04 19:23:57 +08:00
|
|
|
|
if v == 1 && user.VideoFunc == false {
|
|
|
|
|
|
return true
|
2024-12-04 18:39:57 +08:00
|
|
|
|
}
|
2024-12-04 19:23:57 +08:00
|
|
|
|
if v == 2 && user.DeviceFunc == false {
|
|
|
|
|
|
return true
|
2024-12-04 18:39:57 +08:00
|
|
|
|
}
|
2024-12-04 19:23:57 +08:00
|
|
|
|
if v == 3 && user.CIDFunc == false {
|
|
|
|
|
|
return true
|
2024-12-04 18:39:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-04 19:23:57 +08:00
|
|
|
|
return false
|
2024-12-04 18:39:57 +08:00
|
|
|
|
}
|