# permgen-for-goctl goctl 插件,配合 [permlib](https://code.clickto.dev/weiym/permlib) 使用,自动从 go-zero 的 `.api` 文件中提取权限声明,生成 `internal/perms/perms.go`。 ## 作用 产品端开发者在 `.api` 文件中通过 `@doc` 和 struct tag 声明权限,permgen 在代码生成时自动: 1. 收集所有接口的 `api:*` 权限 code,并自动生成配对的 `data:*` 权限 2. 收集请求/响应结构体中的字段级权限(`perm` tag) 3. 生成路由-权限映射表和字段-权限映射表 4. 输出 `internal/perms/perms.go`,供 `serviceContext` 注册到 permlib Engine ## 编译 ```bash git clone https://code.clickto.dev/weiym/permgen-for-goctl.git cd permgen-for-goctl go build -o permgen . ``` 将编译产物 `permgen` 放到 `PATH` 可访问的目录,例如: ```bash mv permgen /usr/local/bin/permgen ``` ## 使用 在产品项目根目录执行: ```bash goctl api go -api your.api -dir . --plugin permgen ``` 执行后会在 `internal/perms/perms.go` 生成如下内容: ```go // Code generated by permgen. DO NOT EDIT. package perms import "code.clickto.dev/weiym/permlib" var Perms = []permlib.PermDecl{ ... } var RoutePerms = []permlib.RoutePermDecl{ ... } var FieldPerms = map[string]permlib.FieldPermMap{ ... } ``` 在 `serviceContext` 中注册: ```go engine.RegisterPerms(perms.Perms) engine.RegisterRoutePerms(perms.RoutePerms) engine.RegisterFieldPerms(perms.FieldPerms) ``` ## api 文件写法 ### 接口权限 在 `@doc` 中通过 `perm` 字段声明接口权限 code: ``` @doc ( summary: "创建用户" perm: "api:user:create" ) @handler CreateUser post /user/create (CreateUserReq) returns (CreateUserResp) ``` - 没有 `perm` 声明的接口视为公开接口,不做权限检查 - `api:user:create` 会自动生成配对的 `data:user:create` ### 字段权限 在请求/响应结构体的字段上通过 `perm` tag 声明字段级权限: ``` type CreateUserReq { Username string `json:"username"` Email string `json:"email" perm:"data:user:email:write"` Salary int64 `json:"salary" perm:"data:user:salary:write"` } type UserListItem { Username string `json:"username"` Email string `json:"email" perm:"data:user:email:read"` Salary int64 `json:"salary" perm:"data:user:salary:read"` } ``` - `write` 权限:用户无权时,字段从请求体中移除(或拒绝请求,取决于 `FieldWriteMode`) - `read` 权限:用户无权时,字段从响应体中自动移除 - 没有 `perm` tag 的字段不受控制,始终放行