github.com/imannamdari/v2ray-core/v5@v5.0.5/app/proxyman/command/command.go (about)

     1  package command
     2  
     3  import (
     4  	"context"
     5  
     6  	grpc "google.golang.org/grpc"
     7  
     8  	core "github.com/imannamdari/v2ray-core/v5"
     9  	"github.com/imannamdari/v2ray-core/v5/common"
    10  	"github.com/imannamdari/v2ray-core/v5/common/serial"
    11  	"github.com/imannamdari/v2ray-core/v5/features/inbound"
    12  	"github.com/imannamdari/v2ray-core/v5/features/outbound"
    13  	"github.com/imannamdari/v2ray-core/v5/proxy"
    14  )
    15  
    16  // InboundOperation is the interface for operations that applies to inbound handlers.
    17  type InboundOperation interface {
    18  	// ApplyInbound applies this operation to the given inbound handler.
    19  	ApplyInbound(context.Context, inbound.Handler) error
    20  }
    21  
    22  // OutboundOperation is the interface for operations that applies to outbound handlers.
    23  type OutboundOperation interface {
    24  	// ApplyOutbound applies this operation to the given outbound handler.
    25  	ApplyOutbound(context.Context, outbound.Handler) error
    26  }
    27  
    28  func getInbound(handler inbound.Handler) (proxy.Inbound, error) {
    29  	gi, ok := handler.(proxy.GetInbound)
    30  	if !ok {
    31  		return nil, newError("can't get inbound proxy from handler.")
    32  	}
    33  	return gi.GetInbound(), nil
    34  }
    35  
    36  // ApplyInbound implements InboundOperation.
    37  func (op *AddUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {
    38  	p, err := getInbound(handler)
    39  	if err != nil {
    40  		return err
    41  	}
    42  	um, ok := p.(proxy.UserManager)
    43  	if !ok {
    44  		return newError("proxy is not a UserManager")
    45  	}
    46  	mUser, err := op.User.ToMemoryUser()
    47  	if err != nil {
    48  		return newError("failed to parse user").Base(err)
    49  	}
    50  	return um.AddUser(ctx, mUser)
    51  }
    52  
    53  // ApplyInbound implements InboundOperation.
    54  func (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {
    55  	p, err := getInbound(handler)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	um, ok := p.(proxy.UserManager)
    60  	if !ok {
    61  		return newError("proxy is not a UserManager")
    62  	}
    63  	return um.RemoveUser(ctx, op.Email)
    64  }
    65  
    66  type handlerServer struct {
    67  	s   *core.Instance
    68  	ihm inbound.Manager
    69  	ohm outbound.Manager
    70  }
    71  
    72  func (s *handlerServer) AddInbound(ctx context.Context, request *AddInboundRequest) (*AddInboundResponse, error) {
    73  	if err := core.AddInboundHandler(s.s, request.Inbound); err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	return &AddInboundResponse{}, nil
    78  }
    79  
    80  func (s *handlerServer) RemoveInbound(ctx context.Context, request *RemoveInboundRequest) (*RemoveInboundResponse, error) {
    81  	return &RemoveInboundResponse{}, s.ihm.RemoveHandler(ctx, request.Tag)
    82  }
    83  
    84  func (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) {
    85  	rawOperation, err := serial.GetInstanceOf(request.Operation)
    86  	if err != nil {
    87  		return nil, newError("unknown operation").Base(err)
    88  	}
    89  	operation, ok := rawOperation.(InboundOperation)
    90  	if !ok {
    91  		return nil, newError("not an inbound operation")
    92  	}
    93  
    94  	handler, err := s.ihm.GetHandler(ctx, request.Tag)
    95  	if err != nil {
    96  		return nil, newError("failed to get handler: ", request.Tag).Base(err)
    97  	}
    98  
    99  	return &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler)
   100  }
   101  
   102  func (s *handlerServer) AddOutbound(ctx context.Context, request *AddOutboundRequest) (*AddOutboundResponse, error) {
   103  	if err := core.AddOutboundHandler(s.s, request.Outbound); err != nil {
   104  		return nil, err
   105  	}
   106  	return &AddOutboundResponse{}, nil
   107  }
   108  
   109  func (s *handlerServer) RemoveOutbound(ctx context.Context, request *RemoveOutboundRequest) (*RemoveOutboundResponse, error) {
   110  	return &RemoveOutboundResponse{}, s.ohm.RemoveHandler(ctx, request.Tag)
   111  }
   112  
   113  func (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboundRequest) (*AlterOutboundResponse, error) {
   114  	rawOperation, err := serial.GetInstanceOf(request.Operation)
   115  	if err != nil {
   116  		return nil, newError("unknown operation").Base(err)
   117  	}
   118  	operation, ok := rawOperation.(OutboundOperation)
   119  	if !ok {
   120  		return nil, newError("not an outbound operation")
   121  	}
   122  
   123  	handler := s.ohm.GetHandler(request.Tag)
   124  	return &AlterOutboundResponse{}, operation.ApplyOutbound(ctx, handler)
   125  }
   126  
   127  func (s *handlerServer) mustEmbedUnimplementedHandlerServiceServer() {}
   128  
   129  type service struct {
   130  	v *core.Instance
   131  }
   132  
   133  func (s *service) Register(server *grpc.Server) {
   134  	hs := &handlerServer{
   135  		s: s.v,
   136  	}
   137  	common.Must(s.v.RequireFeatures(func(im inbound.Manager, om outbound.Manager) {
   138  		hs.ihm = im
   139  		hs.ohm = om
   140  	}))
   141  	RegisterHandlerServiceServer(server, hs)
   142  }
   143  
   144  func init() {
   145  	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
   146  		s := core.MustFromContext(ctx)
   147  		return &service{v: s}, nil
   148  	}))
   149  }