| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- package permlib
- import (
- "context"
- "net/http"
- )
- // PermDecl 权限声明,用于静态注册(permgen 插件生成)
- type PermDecl struct {
- Code string
- Name string
- }
- // RoutePermDecl 路由-权限映射,用于静态注册
- type RoutePermDecl struct {
- Method string
- Path string
- PermCode string
- DataCode string // 配对的 data 权限 code
- }
- // FieldNode 树形字段权限节点,支持任意深度嵌套
- type FieldNode struct {
- Fields map[string]string // jsonName → permCode(当前层需过滤的字段)
- Nested map[string]*FieldNode // jsonName → 子节点(有嵌套结构的字段)
- }
- // FieldPermMap 字段权限映射,用于静态注册(替代反射)
- type FieldPermMap struct {
- Request *FieldNode
- Response *FieldNode
- }
- type Engine struct {
- cfg Config
- client *grpcClient
- cache *permCache
- staticPerms []PermDecl
- routePerms map[string]RoutePermDecl // "METHOD /path" → RoutePermDecl
- fieldPerms map[string]FieldPermMap // "METHOD /path" → FieldPermMap
- }
- type LoginResult struct {
- AccessToken string
- RefreshToken string
- Expires int64
- UserId int64
- Username string
- Nickname string
- MemberType string
- Perms []string
- }
- type RefreshTokenResult struct {
- AccessToken string
- RefreshToken string
- Expires int64
- Perms []string
- }
- type UserPermsResult struct {
- Perms []string
- MemberType string
- }
- func New(cfg Config) (*Engine, error) {
- cfg.defaults()
- if err := cfg.validate(); err != nil {
- return nil, err
- }
- client, err := newGRPCClient(cfg.PermServerAddr)
- if err != nil {
- return nil, err
- }
- return &Engine{
- cfg: cfg,
- client: client,
- cache: newPermCache(cfg.CacheTTL),
- routePerms: make(map[string]RoutePermDecl),
- fieldPerms: make(map[string]FieldPermMap),
- }, nil
- }
- // RegisterPerms 静态注册权限声明(由 permgen 插件生成的代码调用)
- func (e *Engine) RegisterPerms(perms []PermDecl) {
- e.staticPerms = append(e.staticPerms, perms...)
- }
- // RegisterRoutePerms 静态注册路由-权限映射(由 permgen 插件生成的代码调用)
- func (e *Engine) RegisterRoutePerms(decls []RoutePermDecl) {
- for _, d := range decls {
- key := d.Method + " " + d.Path
- e.routePerms[key] = d
- }
- }
- // RegisterFieldPerms 静态注册字段权限映射(由 permgen 插件生成的代码调用,替代反射)
- func (e *Engine) RegisterFieldPerms(m map[string]FieldPermMap) {
- for k, v := range m {
- e.fieldPerms[k] = v
- }
- }
- func (e *Engine) Start(ctx context.Context) error {
- perms := e.collectPerms()
- if len(perms) > 0 {
- if err := e.syncPerms(ctx, perms); err != nil {
- return err
- }
- }
- return nil
- }
- // Login 调用权限系统 gRPC Login 接口
- func (e *Engine) Login(ctx context.Context, username, password string) (*LoginResult, error) {
- resp, err := e.client.login(ctx, e.cfg.ProductCode, username, password)
- if err != nil {
- return nil, err
- }
- return &LoginResult{
- AccessToken: resp.AccessToken,
- RefreshToken: resp.RefreshToken,
- Expires: resp.Expires,
- UserId: resp.UserId,
- Username: resp.Username,
- Nickname: resp.Nickname,
- MemberType: resp.MemberType,
- Perms: resp.Perms,
- }, nil
- }
- // RefreshToken 调用权限系统 gRPC RefreshToken 接口
- func (e *Engine) RefreshToken(ctx context.Context, refreshToken string) (*RefreshTokenResult, error) {
- resp, err := e.client.refreshToken(ctx, refreshToken, e.cfg.ProductCode)
- if err != nil {
- return nil, err
- }
- return &RefreshTokenResult{
- AccessToken: resp.AccessToken,
- RefreshToken: resp.RefreshToken,
- Expires: resp.Expires,
- Perms: resp.Perms,
- }, nil
- }
- // GetUserPerms 查询指定用户在当前产品下的权限列表,使用 appKey/appSecret 做服务间认证
- // 适用于定时任务、服务间调用等不走 token 验证的场景
- func (e *Engine) GetUserPerms(ctx context.Context, userId int64) (*UserPermsResult, error) {
- resp, err := e.client.getUserPerms(ctx, e.cfg.AppKey, e.cfg.AppSecret, userId, e.cfg.ProductCode)
- if err != nil {
- return nil, err
- }
- return &UserPermsResult{
- Perms: resp.Perms,
- MemberType: resp.MemberType,
- }, nil
- }
- // Logout 调用权限系统 gRPC Logout 接口,使 accessToken 对应用户的所有令牌立即失效
- func (e *Engine) Logout(ctx context.Context, accessToken string) error {
- return e.client.logout(ctx, accessToken)
- }
- // AuthMiddleware 返回鉴权 handler,供产品端中间件直接调用
- func (e *Engine) AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
- return e.authMiddleware(next)
- }
|