============================================================================= Remote Resource Discovery RPCs ============================================================================= ListRemotePlugins returns plugins installed on the server. Security (L12): Filters by role — admin sees all, user
(ctx context.Context, req *pb.ListRemotePluginsRequest)
| 26 | // ListRemotePlugins returns plugins installed on the server. |
| 27 | // Security (L12): Filters by role — admin sees all, user sees non-internal, readonly sees none. |
| 28 | func (h *Handler) ListRemotePlugins(ctx context.Context, req *pb.ListRemotePluginsRequest) (*pb.ListRemotePluginsResponse, error) { |
| 29 | if h.pluginManager == nil { |
| 30 | return &pb.ListRemotePluginsResponse{}, nil |
| 31 | } |
| 32 | |
| 33 | // Access control based on role |
| 34 | user := UserFromContext(ctx) |
| 35 | if user != nil && user.Role == RoleReadonly { |
| 36 | return &pb.ListRemotePluginsResponse{}, nil // readonly sees nothing |
| 37 | } |
| 38 | |
| 39 | plist := h.pluginManager.GetPlugins() |
| 40 | result := make([]*pb.PluginInfo, 0, len(plist)) |
| 41 | for _, p := range plist { |
| 42 | // Filter internal plugins (prefixed with _) for non-admin users |
| 43 | if user != nil && user.Role != RoleAdmin && strings.HasPrefix(p.Name(), "_") { |
| 44 | continue |
| 45 | } |
| 46 | result = append(result, &pb.PluginInfo{ |
| 47 | Name: p.Name(), |
| 48 | Description: p.Description(), |
| 49 | Usage: p.Usage(), |
| 50 | Version: p.Version(), |
| 51 | Schema: p.Schema(), |
| 52 | }) |
| 53 | } |
| 54 | |
| 55 | return &pb.ListRemotePluginsResponse{Plugins: result}, nil |
| 56 | } |
| 57 | |
| 58 | // ListRemoteAgents returns all agents available on the server. |
| 59 | func (h *Handler) ListRemoteAgents(ctx context.Context, req *pb.ListRemoteAgentsRequest) (*pb.ListRemoteAgentsResponse, error) { |
nothing calls this directly
no test coverage detected