feat: add unified authorization middleware

This commit is contained in:
2026-08-12 11:46:48 +08:00
parent 2d1deb54f0
commit fa6898aef8
31 changed files with 341 additions and 490 deletions

View File

@@ -30,7 +30,6 @@ const maxDynamicRPCBody = 4 << 20
type dynamicGateway struct {
conn *grpc.ClientConn
allow map[string]struct{}
mu sync.RWMutex
cache map[string]protoreflect.MethodDescriptor
}
@@ -42,18 +41,12 @@ type dynamicRPCResponse struct {
Details []json.RawMessage `json:"details,omitempty"`
}
func newDynamicGateway(grpcAddr string, allow []string) (*dynamicGateway, error) {
func newDynamicGateway(grpcAddr string) (*dynamicGateway, error) {
conn, err := grpc.NewClient(reflectionTarget(grpcAddr), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, fmt.Errorf("create dynamic gRPC client: %w", err)
}
allowed := make(map[string]struct{}, len(allow))
for _, item := range allow {
if item = strings.TrimSpace(item); item != "" {
allowed[item] = struct{}{}
}
}
return &dynamicGateway{conn: conn, allow: allowed, cache: make(map[string]protoreflect.MethodDescriptor)}, nil
return &dynamicGateway{conn: conn, cache: make(map[string]protoreflect.MethodDescriptor)}, nil
}
func reflectionTarget(addr string) string {
@@ -78,12 +71,6 @@ func (g *dynamicGateway) handle(c *gin.Context) {
return
}
serviceName := moduleName + "." + serviceShortName
fullMethod := serviceName + "." + methodName
if !g.isAllowed(serviceName, fullMethod) {
writeDynamicError(c, status.Error(codes.PermissionDenied, "dynamic RPC method is not allowed"))
return
}
descriptor, err := g.resolveMethod(c.Request.Context(), serviceName, methodName)
if err != nil {
writeDynamicError(c, err)
@@ -125,15 +112,6 @@ func (g *dynamicGateway) handle(c *gin.Context) {
c.JSON(http.StatusOK, dynamicRPCResponse{Code: int32(codes.OK), Message: codes.OK.String(), Data: data})
}
func (g *dynamicGateway) isAllowed(serviceName, fullMethod string) bool {
for _, key := range []string{"*", serviceName, fullMethod} {
if _, ok := g.allow[key]; ok {
return true
}
}
return false
}
func (g *dynamicGateway) resolveMethod(ctx context.Context, serviceName, methodName string) (protoreflect.MethodDescriptor, error) {
cacheKey := serviceName + "." + methodName
g.mu.RLock()