inbound_user_add.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package api
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/xtls/xray-core/common/protocol"
  6. handlerService "github.com/xtls/xray-core/app/proxyman/command"
  7. cserial "github.com/xtls/xray-core/common/serial"
  8. "github.com/xtls/xray-core/core"
  9. "github.com/xtls/xray-core/infra/conf"
  10. "github.com/xtls/xray-core/infra/conf/serial"
  11. "github.com/xtls/xray-core/proxy/shadowsocks"
  12. "github.com/xtls/xray-core/proxy/shadowsocks_2022"
  13. "github.com/xtls/xray-core/proxy/trojan"
  14. vlessin "github.com/xtls/xray-core/proxy/vless/inbound"
  15. vmessin "github.com/xtls/xray-core/proxy/vmess/inbound"
  16. "github.com/xtls/xray-core/main/commands/base"
  17. )
  18. var cmdAddInboundUsers = &base.Command{
  19. CustomFlags: true,
  20. UsageLine: "{{.Exec}} api adu [--server=127.0.0.1:8080] <c1.json> [c2.json]...",
  21. Short: "Add users to inbounds",
  22. Long: `
  23. Add users to inbounds.
  24. Arguments:
  25. -s, -server
  26. The API server address. Default 127.0.0.1:8080
  27. -t, -timeout
  28. Timeout seconds to call API. Default 3
  29. Example:
  30. {{.Exec}} {{.LongName}} --server=127.0.0.1:8080 c1.json c2.json
  31. `,
  32. Run: executeAddInboundUsers,
  33. }
  34. func executeAddInboundUsers(cmd *base.Command, args []string) {
  35. setSharedFlags(cmd)
  36. cmd.Flag.Parse(args)
  37. unnamedArgs := cmd.Flag.Args()
  38. inbs := extractInboundsConfig(unnamedArgs)
  39. conn, ctx, close := dialAPIServer()
  40. defer close()
  41. client := handlerService.NewHandlerServiceClient(conn)
  42. success := 0
  43. for _, inb := range inbs {
  44. success += executeInboundUserAction(ctx, client, inb, addInboundUserAction)
  45. }
  46. fmt.Println("Added", success, "user(s) in total.")
  47. }
  48. func addInboundUserAction(ctx context.Context, client handlerService.HandlerServiceClient, tag string, user *protocol.User) error {
  49. fmt.Println("add user:", user.Email)
  50. _, err := client.AlterInbound(ctx, &handlerService.AlterInboundRequest{
  51. Tag: tag,
  52. Operation: cserial.ToTypedMessage(
  53. &handlerService.AddUserOperation{
  54. User: user,
  55. }),
  56. })
  57. return err
  58. }
  59. func extractInboundUsers(inb *core.InboundHandlerConfig) []*protocol.User {
  60. if inb == nil {
  61. return nil
  62. }
  63. inst, err := inb.ProxySettings.GetInstance()
  64. if err != nil || inst == nil {
  65. fmt.Println("failed to get inbound instance:", err)
  66. return nil
  67. }
  68. switch ty := inst.(type) {
  69. case *vmessin.Config:
  70. return ty.User
  71. case *vlessin.Config:
  72. return ty.Clients
  73. case *trojan.ServerConfig:
  74. return ty.Users
  75. case *shadowsocks.ServerConfig:
  76. return ty.Users
  77. case *shadowsocks_2022.MultiUserServerConfig:
  78. return ty.Users
  79. default:
  80. fmt.Println("unsupported inbound type")
  81. }
  82. return nil
  83. }
  84. func extractInboundsConfig(unnamedArgs []string) []conf.InboundDetourConfig {
  85. ins := make([]conf.InboundDetourConfig, 0)
  86. for _, arg := range unnamedArgs {
  87. r, err := loadArg(arg)
  88. if err != nil {
  89. base.Fatalf("failed to load %s: %s", arg, err)
  90. }
  91. conf, err := serial.DecodeJSONConfig(r)
  92. if err != nil {
  93. base.Fatalf("failed to decode %s: %s", arg, err)
  94. }
  95. ins = append(ins, conf.InboundConfigs...)
  96. }
  97. return ins
  98. }
  99. func executeInboundUserAction(ctx context.Context, client handlerService.HandlerServiceClient, inb conf.InboundDetourConfig, action func(ctx context.Context, client handlerService.HandlerServiceClient, tag string, user *protocol.User) error) int {
  100. success := 0
  101. tag := inb.Tag
  102. if len(tag) < 1 {
  103. return success
  104. }
  105. fmt.Println("processing inbound:", tag)
  106. built, err := inb.Build()
  107. if err != nil {
  108. fmt.Println("failed to build config:", err)
  109. return success
  110. }
  111. users := extractInboundUsers(built)
  112. if users == nil {
  113. return success
  114. }
  115. for _, user := range users {
  116. if len(user.Email) < 1 {
  117. continue
  118. }
  119. if err := action(ctx, client, inb.Tag, user); err == nil {
  120. fmt.Println("result: ok")
  121. success += 1
  122. } else {
  123. fmt.Println(err)
  124. }
  125. }
  126. return success
  127. }