permlib.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package permlib
  2. import (
  3. "context"
  4. "net/http"
  5. )
  6. // PermDecl 权限声明,用于静态注册(permgen 插件生成)
  7. type PermDecl struct {
  8. Code string
  9. Name string
  10. }
  11. // RoutePermDecl 路由-权限映射,用于静态注册
  12. type RoutePermDecl struct {
  13. Method string
  14. Path string
  15. PermCode string
  16. DataCode string // 配对的 data 权限 code
  17. }
  18. // FieldPermMap 字段权限映射,用于静态注册(替代反射)
  19. type FieldPermMap struct {
  20. Request map[string]string // json字段名 → permCode
  21. Response map[string]string // json字段名 → permCode
  22. }
  23. type Engine struct {
  24. cfg Config
  25. client *grpcClient
  26. cache *permCache
  27. staticPerms []PermDecl
  28. routePerms map[string]RoutePermDecl // "METHOD /path" → RoutePermDecl
  29. fieldPerms map[string]FieldPermMap // "METHOD /path" → FieldPermMap
  30. }
  31. type LoginResult struct {
  32. AccessToken string
  33. RefreshToken string
  34. Expires int64
  35. UserId int64
  36. Username string
  37. Nickname string
  38. MemberType string
  39. Perms []string
  40. }
  41. type RefreshTokenResult struct {
  42. AccessToken string
  43. RefreshToken string
  44. Expires int64
  45. Perms []string
  46. }
  47. type UserPermsResult struct {
  48. Perms []string
  49. MemberType string
  50. }
  51. func New(cfg Config) (*Engine, error) {
  52. cfg.defaults()
  53. if err := cfg.validate(); err != nil {
  54. return nil, err
  55. }
  56. client, err := newGRPCClient(cfg.PermServerAddr)
  57. if err != nil {
  58. return nil, err
  59. }
  60. return &Engine{
  61. cfg: cfg,
  62. client: client,
  63. cache: newPermCache(cfg.CacheTTL),
  64. routePerms: make(map[string]RoutePermDecl),
  65. fieldPerms: make(map[string]FieldPermMap),
  66. }, nil
  67. }
  68. // RegisterPerms 静态注册权限声明(由 permgen 插件生成的代码调用)
  69. func (e *Engine) RegisterPerms(perms []PermDecl) {
  70. e.staticPerms = append(e.staticPerms, perms...)
  71. }
  72. // RegisterRoutePerms 静态注册路由-权限映射(由 permgen 插件生成的代码调用)
  73. func (e *Engine) RegisterRoutePerms(decls []RoutePermDecl) {
  74. for _, d := range decls {
  75. key := d.Method + " " + d.Path
  76. e.routePerms[key] = d
  77. }
  78. }
  79. // RegisterFieldPerms 静态注册字段权限映射(由 permgen 插件生成的代码调用,替代反射)
  80. func (e *Engine) RegisterFieldPerms(m map[string]FieldPermMap) {
  81. for k, v := range m {
  82. e.fieldPerms[k] = v
  83. }
  84. }
  85. func (e *Engine) Start(ctx context.Context) error {
  86. perms := e.collectPerms()
  87. if len(perms) > 0 {
  88. if err := e.syncPerms(ctx, perms); err != nil {
  89. return err
  90. }
  91. }
  92. return nil
  93. }
  94. // Login 调用权限系统 gRPC Login 接口
  95. func (e *Engine) Login(ctx context.Context, username, password string) (*LoginResult, error) {
  96. resp, err := e.client.login(ctx, e.cfg.ProductCode, username, password)
  97. if err != nil {
  98. return nil, err
  99. }
  100. return &LoginResult{
  101. AccessToken: resp.AccessToken,
  102. RefreshToken: resp.RefreshToken,
  103. Expires: resp.Expires,
  104. UserId: resp.UserId,
  105. Username: resp.Username,
  106. Nickname: resp.Nickname,
  107. MemberType: resp.MemberType,
  108. Perms: resp.Perms,
  109. }, nil
  110. }
  111. // RefreshToken 调用权限系统 gRPC RefreshToken 接口
  112. func (e *Engine) RefreshToken(ctx context.Context, refreshToken string) (*RefreshTokenResult, error) {
  113. resp, err := e.client.refreshToken(ctx, refreshToken, e.cfg.ProductCode)
  114. if err != nil {
  115. return nil, err
  116. }
  117. return &RefreshTokenResult{
  118. AccessToken: resp.AccessToken,
  119. RefreshToken: resp.RefreshToken,
  120. Expires: resp.Expires,
  121. Perms: resp.Perms,
  122. }, nil
  123. }
  124. // GetUserPerms 查询指定用户在当前产品下的权限列表,使用 appKey/appSecret 做服务间认证
  125. // 适用于定时任务、服务间调用等不走 token 验证的场景
  126. func (e *Engine) GetUserPerms(ctx context.Context, userId int64) (*UserPermsResult, error) {
  127. resp, err := e.client.getUserPerms(ctx, e.cfg.AppKey, e.cfg.AppSecret, userId, e.cfg.ProductCode)
  128. if err != nil {
  129. return nil, err
  130. }
  131. return &UserPermsResult{
  132. Perms: resp.Perms,
  133. MemberType: resp.MemberType,
  134. }, nil
  135. }
  136. // AuthMiddleware 返回鉴权 handler,供产品端中间件直接调用
  137. func (e *Engine) AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
  138. return e.authMiddleware(next)
  139. }