diff --git a/apps/system/api/api.go b/apps/system/api/api.go index a7faefa..21ab448 100644 --- a/apps/system/api/api.go +++ b/apps/system/api/api.go @@ -7,6 +7,7 @@ import ( "github.com/XM-GO/PandaKit/utils" entity "pandax/apps/system/entity" services "pandax/apps/system/services" + "pandax/pkg/global" "strconv" ) @@ -61,5 +62,6 @@ func (s *SystemApiApi) GetAllApis(rc *restfulx.ReqCtx) { func (s *SystemApiApi) GetPolicyPathByRoleId(rc *restfulx.ReqCtx) { roleKey := rc.Request.QueryParameter("roleKey") tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) - rc.ResData = casbin.GetPolicyPathByRoleId(tenantId, roleKey) + ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} + rc.ResData = ca.GetPolicyPathByRoleId(tenantId, roleKey) } diff --git a/apps/system/api/role.go b/apps/system/api/role.go index 44dbfab..a6ba174 100644 --- a/apps/system/api/role.go +++ b/apps/system/api/role.go @@ -64,7 +64,8 @@ func (r *RoleApi) InsertRole(rc *restfulx.ReqCtx) { r.RoleMenuApp.Insert(insert.RoleId, role.MenuIds) //添加权限 tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) - casbin.UpdateCasbin(tenantId, role.RoleKey, role.ApiIds) + ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} + ca.UpdateCasbin(tenantId, role.RoleKey, role.ApiIds) } // UpdateRole 修改用户角色 @@ -80,7 +81,8 @@ func (r *RoleApi) UpdateRole(rc *restfulx.ReqCtx) { r.RoleMenuApp.Insert(role.RoleId, role.MenuIds) //修改api权限 tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) - casbin.UpdateCasbin(tenantId, role.RoleKey, role.ApiIds) + ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} + ca.UpdateCasbin(tenantId, role.RoleKey, role.ApiIds) } // UpdateRoleStatus 修改用户角色状态 @@ -122,7 +124,8 @@ func (r *RoleApi) DeleteRole(rc *restfulx.ReqCtx) { if len(*list) == 0 { delList = append(delList, rid) //删除角色绑定api - casbin.ClearCasbin(0, role.RoleKey) + ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} + ca.ClearCasbin(0, role.RoleKey) } else { global.Log.Info(fmt.Sprintf("role:%d 存在用户无法删除", rid)) } diff --git a/apps/system/api/system.go b/apps/system/api/system.go index ff6de60..ab3c576 100644 --- a/apps/system/api/system.go +++ b/apps/system/api/system.go @@ -8,6 +8,7 @@ import ( "github.com/emicklei/go-restful/v3" "github.com/gorilla/websocket" "github.com/kakuilan/kgo" + "pandax/pkg/middleware" "runtime" ) @@ -71,7 +72,7 @@ func (s *System) ConnectWs(request *restful.Request, response *restful.Response) } // 权限校验 rc := restfulx.NewReqCtx(request, response) - if err = restfulx.PermissionHandler(rc); err != nil { + if err = middleware.PermissionHandler(rc); err != nil { panic(any(biz.NewBizErr("没有权限"))) } diff --git a/apps/system/services/api.go b/apps/system/services/api.go index 3d57db2..48d64f4 100644 --- a/apps/system/services/api.go +++ b/apps/system/services/api.go @@ -107,7 +107,8 @@ func (m *sysApiModelImpl) Update(api entity.SysApi) *entity.SysApi { biz.IsTrue(errors.Is(err, gorm.ErrRecordNotFound), "存在相同api路径") } // 异常直接抛错误 - casbin.UpdateCasbinApi(oldA.Path, api.Path, oldA.Method, api.Method) + ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} + ca.UpdateCasbinApi(oldA.Path, api.Path, oldA.Method, api.Method) err = global.Db.Table(m.table).Model(&api).Updates(&api).Error biz.ErrIsNil(err, "修改api信息失败") return &api diff --git a/config.yml b/config.yml index 07cd05e..b3b8ace 100644 --- a/config.yml +++ b/config.yml @@ -20,7 +20,7 @@ server: key-file: ./resource/default.key cert-file: ./resource/default.pem jwt: - key: mykey + key: PandaX # 过期时间单位秒 7天 expire-time: 604800 @@ -56,6 +56,6 @@ gen: log: # 日志等级, trace, debug, info, warn, error, fatal level: info - # file: - # path: ./ - # name: panda_log.log \ No newline at end of file +# file: +# path: ./ +# name: panda_log.log \ No newline at end of file diff --git a/go.mod b/go.mod index 2ace69f..d806f72 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module pandax go 1.18 require ( - github.com/XM-GO/PandaKit v0.0.0-20220814121200-1838edb60142 github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/didip/tollbooth v4.0.2+incompatible github.com/emicklei/go-restful-openapi/v2 v2.9.0 @@ -25,6 +24,7 @@ require ( github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect + github.com/XM-GO/PandaKit v0.0.0-20220819095140-dd76101b435f // indirect github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible // indirect github.com/brianvoe/gofakeit/v6 v6.0.2 // indirect github.com/casbin/casbin/v2 v2.37.4 // indirect @@ -96,3 +96,5 @@ require ( gorm.io/driver/sqlserver v1.2.1 // indirect gorm.io/plugin/dbresolver v1.1.0 // indirect ) + +replace github.com/XM-GO/PandaKit => D:\GOwork\pro\PnadaX\PandaKit \ No newline at end of file diff --git a/go.sum b/go.sum index c169900..596e8ee 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjl github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/XM-GO/PandaKit v0.0.0-20220814121200-1838edb60142 h1:G7V4eFIeR7rHWkK9LCW5TAH5fUmFb9+M1s74Q/nP9JA= github.com/XM-GO/PandaKit v0.0.0-20220814121200-1838edb60142/go.mod h1:A/0dFObLVa7Yzeq6cMmcjNUoajSgcLkEJglLc41BO3w= +github.com/XM-GO/PandaKit v0.0.0-20220819095140-dd76101b435f h1:Ginj9GfKXfr10uLn+akHDzDclOAEWR+m4qL+8ff80rs= +github.com/XM-GO/PandaKit v0.0.0-20220819095140-dd76101b435f/go.mod h1:A/0dFObLVa7Yzeq6cMmcjNUoajSgcLkEJglLc41BO3w= github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible h1:ht2+VfbXtNLGhCsnTMc6/N26nSTBK6qdhktjYyjJQkk= github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= diff --git a/main.go b/main.go index edd2817..2c9a3f8 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,8 @@ package main import ( "context" - "github.com/XM-GO/PandaKit/config" + "pandax/pkg/config" + "github.com/XM-GO/PandaKit/logger" "github.com/XM-GO/PandaKit/restfulx" "github.com/XM-GO/PandaKit/starter" @@ -27,8 +28,18 @@ var rootCmd = &cobra.Command{ PreRun: func(cmd *cobra.Command, args []string) { if configFile != "" { global.Conf = config.InitConfig(configFile) - global.Log = logger.InitLog(global.Conf.Log) - global.Db = starter.GormInit(global.Conf.Server.DbType) + global.Log = logger.InitLog(global.Conf.Log.File.GetFilename(), global.Conf.Log.Level) + dbGorm := starter.DbGorm{Type: global.Conf.Server.DbType} + if global.Conf.Server.DbType == "mysql" { + dbGorm.Dsn = global.Conf.Mysql.Dsn() + dbGorm.MaxIdleConns = global.Conf.Mysql.MaxIdleConns + dbGorm.MaxOpenConns = global.Conf.Mysql.MaxOpenConns + } else { + dbGorm.Dsn = global.Conf.Postgresql.PgDsn() + dbGorm.MaxIdleConns = global.Conf.Postgresql.MaxIdleConns + dbGorm.MaxOpenConns = global.Conf.Postgresql.MaxOpenConns + } + global.Db = dbGorm.GormInit() initialize.InitTable() } else { global.Log.Panic("请配置config") @@ -37,9 +48,9 @@ var rootCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { restfulx.UseAfterHandlerInterceptor(middleware.OperationHandler) // 前置 函数 - restfulx.UseBeforeHandlerInterceptor(restfulx.PermissionHandler) + restfulx.UseBeforeHandlerInterceptor(middleware.PermissionHandler) // 后置 函数 - restfulx.UseAfterHandlerInterceptor(restfulx.LogHandler) + restfulx.UseAfterHandlerInterceptor(middleware.LogHandler) go func() { // 启动系统调度任务 jobs.InitJob() @@ -47,7 +58,7 @@ var rootCmd = &cobra.Command{ }() app := initialize.InitRouter() - + global.Log.Info("路由初始化完成") app.Start(context.TODO()) stop := make(chan os.Signal, 1) signal.Notify(stop, syscall.SIGTERM, os.Interrupt) diff --git a/pkg/config/config.go b/pkg/config/config.go index 8dedb78..c30a890 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -8,8 +8,6 @@ import ( "path/filepath" ) -var Conf *Config - func InitConfig(configFilePath string) *Config { // 获取启动参数中,配置文件的绝对路径 path, _ := filepath.Abs(configFilePath) @@ -22,7 +20,6 @@ func InitConfig(configFilePath string) *Config { // 校验配置文件内容信息 yc.Valid() - Conf = yc return yc } diff --git a/pkg/config/log.go b/pkg/config/log.go index ac9815b..e2de254 100644 --- a/pkg/config/log.go +++ b/pkg/config/log.go @@ -15,6 +15,9 @@ type LogFile struct { // 获取完整路径文件名 func (l *LogFile) GetFilename() string { var filepath, filename string + if l == nil { + return "" + } if fp := l.Path; fp == "" { filepath = "./" } else { diff --git a/pkg/global/global.go b/pkg/global/global.go index 4cb1ff5..eeee04c 100644 --- a/pkg/global/global.go +++ b/pkg/global/global.go @@ -1,9 +1,9 @@ package global import ( - "github.com/XM-GO/PandaKit/config" "github.com/sirupsen/logrus" "gorm.io/gorm" + "pandax/pkg/config" ) var ( diff --git a/pkg/middleware/log.go b/pkg/middleware/log.go new file mode 100644 index 0000000..aa020f5 --- /dev/null +++ b/pkg/middleware/log.go @@ -0,0 +1,70 @@ +package middleware + +import ( + "encoding/json" + "fmt" + "github.com/XM-GO/PandaKit/biz" + "github.com/XM-GO/PandaKit/logger" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/XM-GO/PandaKit/utils" + "github.com/sirupsen/logrus" + "reflect" + "runtime/debug" +) + +func LogHandler(rc *restfulx.ReqCtx) error { + li := rc.LogInfo + if li == nil { + return nil + } + + lfs := logrus.Fields{} + if la := rc.LoginAccount; la != nil { + lfs["uid"] = la.UserId + lfs["uname"] = la.UserName + } + + req := rc.Request.Request + lfs[req.Method] = req.URL.Path + + if err := rc.Err; err != nil { + logger.Log.WithFields(lfs).Error(getErrMsg(rc, err)) + return nil + } + logger.Log.WithFields(lfs).Info(getLogMsg(rc)) + return nil +} + +func getLogMsg(rc *restfulx.ReqCtx) string { + msg := rc.LogInfo.Description + fmt.Sprintf(" ->%dms", rc.Timed) + if !utils.IsBlank(reflect.ValueOf(rc.ReqParam)) { + rb, _ := json.Marshal(rc.ReqParam) + msg = msg + fmt.Sprintf("\n--> %s", string(rb)) + } + + // 返回结果不为空,则记录返回结果 + if rc.LogInfo.LogResp && !utils.IsBlank(reflect.ValueOf(rc.ResData)) { + respB, _ := json.Marshal(rc.ResData) + msg = msg + fmt.Sprintf("\n<-- %s", string(respB)) + } + return msg +} + +func getErrMsg(rc *restfulx.ReqCtx, err any) string { + msg := rc.LogInfo.Description + if !utils.IsBlank(reflect.ValueOf(rc.ReqParam)) { + rb, _ := json.Marshal(rc.ReqParam) + msg = msg + fmt.Sprintf("\n--> %s", string(rb)) + } + + var errMsg string + switch t := err.(type) { + case *biz.BizError: + errMsg = fmt.Sprintf("\n<-e errCode: %d, errMsg: %s", t.Code(), t.Error()) + case error: + errMsg = fmt.Sprintf("\n<-e errMsg: %s\n%s", t.Error(), string(debug.Stack())) + case string: + errMsg = fmt.Sprintf("\n<-e errMsg: %s\n%s", t, string(debug.Stack())) + } + return (msg + errMsg) +} diff --git a/pkg/middleware/permission.go b/pkg/middleware/permission.go new file mode 100644 index 0000000..c86e504 --- /dev/null +++ b/pkg/middleware/permission.go @@ -0,0 +1,48 @@ +package middleware + +import ( + "github.com/XM-GO/PandaKit/biz" + "github.com/XM-GO/PandaKit/casbin" + "github.com/XM-GO/PandaKit/restfulx" + "github.com/XM-GO/PandaKit/token" + "github.com/dgrijalva/jwt-go" + "pandax/pkg/global" + "strconv" +) + +func PermissionHandler(rc *restfulx.ReqCtx) error { + permission := rc.RequiredPermission + // 如果需要的权限信息不为空,并且不需要token,则不返回错误,继续后续逻辑 + if permission != nil && !permission.NeedToken { + return nil + } + tokenStr := rc.Request.Request.Header.Get("X-TOKEN") + // header不存在则从查询参数token中获取 + if tokenStr == "" { + tokenStr = rc.Request.QueryParameter("token") + } + if tokenStr == "" { + return biz.PermissionErr + } + j := token.NewJWT("", []byte(global.Conf.Jwt.Key), jwt.SigningMethodHS256) + loginAccount, err := j.ParseToken(tokenStr) + if err != nil || loginAccount == nil { + return biz.PermissionErr + } + rc.LoginAccount = loginAccount + + if !permission.NeedCasbin { + return nil + } + + ca := casbin.CasbinS{ModelPath: global.Conf.Casbin.ModelPath} + e := ca.Casbin() + // 判断策略中是否存在 + tenantId := strconv.Itoa(int(rc.LoginAccount.TenantId)) + success, err := e.Enforce(tenantId, loginAccount.RoleKey, rc.Request.Request.URL.Path, rc.Request.Request.Method) + if !success { + return biz.CasbinErr + } + + return nil +} diff --git a/pkg/transport/http_server.go b/pkg/transport/http_server.go index 3dd40c7..c1f701e 100644 --- a/pkg/transport/http_server.go +++ b/pkg/transport/http_server.go @@ -35,7 +35,7 @@ func (s *HttpServer) Type() Type { } func (s *HttpServer) Start(ctx context.Context) error { - global.Log.Debugf("HTTP Server listen: %s", s.Addr) + global.Log.Infof("HTTP Server listen: %s", s.Addr) go func() { if err := s.srv.ListenAndServe(); err != nil { global.Log.Errorf("error http serve: %s", err)