package api import ( "context" "errors" "fmt" "net" "github.com/Neur0toxine/sshpoke/internal/config" "github.com/Neur0toxine/sshpoke/internal/logger" "github.com/Neur0toxine/sshpoke/internal/server" "github.com/Neur0toxine/sshpoke/internal/server/driver/plugin" "github.com/Neur0toxine/sshpoke/pkg/convert" plugin2 "github.com/Neur0toxine/sshpoke/pkg/plugin" "github.com/Neur0toxine/sshpoke/pkg/plugin/pb" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/types/known/emptypb" ) var ErrUnauthorized = errors.New("unauthorized") type pluginAPI struct { pb.UnimplementedPluginServiceServer } func (p *pluginAPI) Event(_ *emptypb.Empty, stream pb.PluginService_EventServer) error { pl := p.receiverForContext(stream.Context()) if pl == nil { return ErrUnauthorized } logger.Sugar.Debugw("attached plugin event stream", "serverName", pl.Name()) err := pl.Listen(stream.Context(), &Stream{stream: stream}) if err != nil { logger.Sugar.Debugw("detached plugin event stream", "serverName", pl.Name(), "error", err) return err } logger.Sugar.Debugw("detached plugin event stream", "serverName", pl.Name()) return nil } func (p *pluginAPI) EventStatus(ctx context.Context, msg *pb.EventStatusMessage) (*emptypb.Empty, error) { pl := p.receiverForContext(ctx) if pl == nil { return nil, ErrUnauthorized } pl.PushEventStatus(convert.MessageToAppEventStatus(msg)) return &emptypb.Empty{}, nil } func (p *pluginAPI) receiverForContext(ctx context.Context) plugin.Plugin { md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil } tokens := md.Get("token") if len(tokens) != 1 { return nil } return server.DefaultManager.PluginByToken(tokens[0]) } func StartPluginAPI() { port := config.Default.PluginAPIPort if port == 0 { port = plugin2.DefaultPort } socket, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { logger.Sugar.Errorf("cannot start plugin API server on port %d: %s", port, err) return } s := grpc.NewServer() pb.RegisterPluginServiceServer(s, &pluginAPI{}) logger.Sugar.Debugf("starting plugin server on :%d", port) if err := s.Serve(socket); err != nil { logger.Sugar.Fatalf("cannot start plugin server on :%d: %s", port, err) } }