tcpforwarding.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package service
  2. import (
  3. "context"
  4. v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
  5. "github.com/go-nunu/nunu-layout-advanced/internal/model"
  6. "github.com/go-nunu/nunu-layout-advanced/internal/repository"
  7. "strconv"
  8. "strings"
  9. )
  10. type TcpforwardingService interface {
  11. GetTcpforwarding(ctx context.Context, id int64) (*model.Tcpforwarding, error)
  12. AddTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) error
  13. EditTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) error
  14. DeleteTcpForwarding(ctx context.Context, wafTcpId int) error
  15. }
  16. func NewTcpforwardingService(
  17. service *Service,
  18. tcpforwardingRepository repository.TcpforwardingRepository,
  19. parser ParserService,
  20. required RequiredService,
  21. crawler CrawlerService,
  22. globalRep repository.GlobalLimitRepository,
  23. hostRep repository.HostRepository,
  24. wafformatter WafFormatterService,
  25. ) TcpforwardingService {
  26. return &tcpforwardingService{
  27. Service: service,
  28. tcpforwardingRepository: tcpforwardingRepository,
  29. parser: parser,
  30. required: required,
  31. crawler: crawler,
  32. globalRep: globalRep,
  33. hostRep: hostRep,
  34. wafformatter: wafformatter,
  35. }
  36. }
  37. type tcpforwardingService struct {
  38. *Service
  39. tcpforwardingRepository repository.TcpforwardingRepository
  40. parser ParserService
  41. required RequiredService
  42. crawler CrawlerService
  43. globalRep repository.GlobalLimitRepository
  44. hostRep repository.HostRepository
  45. wafformatter WafFormatterService
  46. }
  47. func (s *tcpforwardingService) GetTcpforwarding(ctx context.Context, id int64) (*model.Tcpforwarding, error) {
  48. return s.tcpforwardingRepository.GetTcpforwarding(ctx, id)
  49. }
  50. func (s *tcpforwardingService) require(ctx context.Context,req v1.GlobalRequire) (v1.GlobalRequire, error) {
  51. res, err := s.wafformatter.require(ctx, req, "tcp")
  52. if err != nil {
  53. return v1.GlobalRequire{}, err
  54. }
  55. return res, nil
  56. }
  57. func (s *tcpforwardingService) buildWafFormData(req *v1.TcpForwardingDataSend, require v1.GlobalRequire) map[string]interface{} {
  58. return map[string]interface{}{
  59. "waf_tcp_id": req.WafTcpId,
  60. "tag": require.Tag,
  61. "port": req.Port,
  62. "waf_gateway_group_id": require.WafGatewayGroupId,
  63. "waf_tcp_limit_id": require.LimitRuleId,
  64. "cc_count": req.CcCount,
  65. "cc_duration": req.CcDuration,
  66. "cc_block_count": req.CcBlockCount,
  67. "cc_block_duration": req.CcBlockDuration,
  68. "backend_protocol": req.BackendProtocol,
  69. "backend_timeout": req.BackendTimeout,
  70. "comment": req.Comment,
  71. "backend_list": req.BackendList,
  72. "allow_ip_list": req.AllowIpList,
  73. "deny_ip_list": req.DenyIpList,
  74. "access_rule": req.AccessRule,
  75. }
  76. }
  77. func (s *tcpforwardingService) buildTcpForwardingModel(req *v1.TcpForwardingDataRequest, ruleId int, require v1.GlobalRequire) *model.Tcpforwarding {
  78. return &model.Tcpforwarding{
  79. HostId: require.HostId,
  80. WafTcpId: ruleId,
  81. Port: req.Port,
  82. Tag: require.Tag,
  83. Comment: req.Comment,
  84. WafGatewayGroupId: require.WafGatewayGroupId,
  85. CcCount: req.CcCount,
  86. CcDuration: req.CcDuration,
  87. CcBlockCount: req.CcBlockCount,
  88. CcBlockDuration: req.CcBlockDuration,
  89. BackendProtocol: req.BackendProtocol,
  90. BackendTimeout: req.BackendTimeout,
  91. }
  92. }
  93. func (s *tcpforwardingService) buildTcpRuleModel(reqData *v1.TcpForwardingDataRequest, require v1.GlobalRequire, localDbId int) *model.TcpForwardingRule {
  94. return &model.TcpForwardingRule{
  95. Uid: require.Uid,
  96. HostId: require.HostId,
  97. TcpId: localDbId, // 关联到本地数据库的主记录 ID
  98. BackendList: reqData.BackendList,
  99. AllowIpList: reqData.AllowIpList,
  100. DenyIpList: reqData.DenyIpList,
  101. AccessRule: reqData.AccessRule,
  102. }
  103. }
  104. func (s *tcpforwardingService) prepareWafData(ctx context.Context, req *v1.TcpForwardingRequest) (v1.GlobalRequire, map[string]interface{}, error) {
  105. // 1. 获取必要的全局信息
  106. require, err := s.require(ctx, v1.GlobalRequire{
  107. HostId: req.HostId,
  108. Uid: req.Uid,
  109. Comment: req.TcpForwardingData.Comment,
  110. })
  111. if err != nil {
  112. return v1.GlobalRequire{}, nil, err
  113. }
  114. // 2. 将字符串切片拼接成字符串,用于 WAF API
  115. backendListStr := strings.Join(req.TcpForwardingData.BackendList, "\n")
  116. allowIpListStr := strings.Join(req.TcpForwardingData.AllowIpList, "\n")
  117. denyIpListStr := strings.Join(req.TcpForwardingData.DenyIpList, "\n")
  118. // 3. 创建用于构建 WAF 表单的数据结构
  119. formDataBase := v1.TcpForwardingDataSend{
  120. Tag: require.Tag,
  121. WafTcpId: req.TcpForwardingData.WafTcpId,
  122. WafGatewayGroupId: require.WafGatewayGroupId,
  123. WafTcpLimitRuleId: require.LimitRuleId,
  124. Port: req.TcpForwardingData.Port,
  125. CcCount: req.TcpForwardingData.CcCount,
  126. CcDuration: req.TcpForwardingData.CcDuration,
  127. CcBlockCount: req.TcpForwardingData.CcBlockCount,
  128. CcBlockDuration: req.TcpForwardingData.CcBlockDuration,
  129. BackendProtocol: req.TcpForwardingData.BackendProtocol,
  130. BackendTimeout: req.TcpForwardingData.BackendTimeout,
  131. BackendList: backendListStr,
  132. AllowIpList: allowIpListStr,
  133. DenyIpList: denyIpListStr,
  134. AccessRule: req.TcpForwardingData.AccessRule,
  135. Comment: req.TcpForwardingData.Comment,
  136. }
  137. // 4. 构建 WAF 表单数据映射
  138. formData := s.buildWafFormData(&formDataBase, require)
  139. return require, formData, nil
  140. }
  141. func (s *tcpforwardingService) AddTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) error {
  142. require, formData, err := s.prepareWafData(ctx, req)
  143. if err != nil {
  144. return err
  145. }
  146. wafTcpId, err := s.wafformatter.sendFormData(ctx, "admin/info/waf_tcp/new", "admin/new/waf_tcp", formData)
  147. if err != nil {
  148. return err
  149. }
  150. tcpModel := s.buildTcpForwardingModel(&req.TcpForwardingData, wafTcpId, require)
  151. id, err := s.tcpforwardingRepository.AddTcpforwarding(ctx, tcpModel)
  152. if err != nil {
  153. return err
  154. }
  155. TcpRuleModel := s.buildTcpRuleModel(&req.TcpForwardingData, require, id)
  156. if _, err = s.tcpforwardingRepository.AddTcpforwardingIps(ctx, *TcpRuleModel); err != nil {
  157. return err
  158. }
  159. return nil
  160. }
  161. func (s *tcpforwardingService) EditTcpForwarding(ctx context.Context, req *v1.TcpForwardingRequest) error {
  162. WafTcpId, err := s.tcpforwardingRepository.GetTcpforwardingWafTcpIdById(ctx, req.Id)
  163. if err != nil {
  164. return err
  165. }
  166. req.TcpForwardingData.WafTcpId = WafTcpId
  167. require, formData, err := s.prepareWafData(ctx, req)
  168. if err != nil {
  169. return err
  170. }
  171. _, err = s.wafformatter.sendFormData(ctx, "admin/info/waf_tcp/edit?&__goadmin_edit_pk="+strconv.Itoa(req.TcpForwardingData.WafTcpId), "admin/edit/waf_tcp", formData)
  172. if err != nil {
  173. return err
  174. }
  175. tcpModel := s.buildTcpForwardingModel(&req.TcpForwardingData, req.TcpForwardingData.WafTcpId, require)
  176. tcpModel.Id = req.Id
  177. if err = s.tcpforwardingRepository.EditTcpforwarding(ctx, tcpModel); err != nil {
  178. return err
  179. }
  180. TcpRuleModel := s.buildTcpRuleModel(&req.TcpForwardingData, require, req.Id)
  181. if err = s.tcpforwardingRepository.EditTcpforwardingIps(ctx, *TcpRuleModel); err != nil {
  182. return err
  183. }
  184. return nil
  185. }
  186. func (s *tcpforwardingService) DeleteTcpForwarding(ctx context.Context, wafTcpId int) error {
  187. _, err := s.crawler.DeleteRule(ctx, wafTcpId, "admin/delete/waf_tcp?page=1&__pageSize=10&__sort=waf_tcp_id&__sort_type=desc")
  188. if err != nil {
  189. return err
  190. }
  191. return nil
  192. }