tls_fingerprint_profile_handler.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package admin
  2. import (
  3. "strconv"
  4. "github.com/Wei-Shaw/sub2api/internal/model"
  5. "github.com/Wei-Shaw/sub2api/internal/pkg/response"
  6. "github.com/Wei-Shaw/sub2api/internal/service"
  7. "github.com/gin-gonic/gin"
  8. )
  9. // TLSFingerprintProfileHandler 处理 TLS 指纹模板的 HTTP 请求
  10. type TLSFingerprintProfileHandler struct {
  11. service *service.TLSFingerprintProfileService
  12. }
  13. // NewTLSFingerprintProfileHandler 创建 TLS 指纹模板处理器
  14. func NewTLSFingerprintProfileHandler(service *service.TLSFingerprintProfileService) *TLSFingerprintProfileHandler {
  15. return &TLSFingerprintProfileHandler{service: service}
  16. }
  17. // CreateTLSFingerprintProfileRequest 创建模板请求
  18. type CreateTLSFingerprintProfileRequest struct {
  19. Name string `json:"name" binding:"required"`
  20. Description *string `json:"description"`
  21. EnableGREASE *bool `json:"enable_grease"`
  22. CipherSuites []uint16 `json:"cipher_suites"`
  23. Curves []uint16 `json:"curves"`
  24. PointFormats []uint16 `json:"point_formats"`
  25. SignatureAlgorithms []uint16 `json:"signature_algorithms"`
  26. ALPNProtocols []string `json:"alpn_protocols"`
  27. SupportedVersions []uint16 `json:"supported_versions"`
  28. KeyShareGroups []uint16 `json:"key_share_groups"`
  29. PSKModes []uint16 `json:"psk_modes"`
  30. Extensions []uint16 `json:"extensions"`
  31. }
  32. // UpdateTLSFingerprintProfileRequest 更新模板请求(部分更新)
  33. type UpdateTLSFingerprintProfileRequest struct {
  34. Name *string `json:"name"`
  35. Description *string `json:"description"`
  36. EnableGREASE *bool `json:"enable_grease"`
  37. CipherSuites []uint16 `json:"cipher_suites"`
  38. Curves []uint16 `json:"curves"`
  39. PointFormats []uint16 `json:"point_formats"`
  40. SignatureAlgorithms []uint16 `json:"signature_algorithms"`
  41. ALPNProtocols []string `json:"alpn_protocols"`
  42. SupportedVersions []uint16 `json:"supported_versions"`
  43. KeyShareGroups []uint16 `json:"key_share_groups"`
  44. PSKModes []uint16 `json:"psk_modes"`
  45. Extensions []uint16 `json:"extensions"`
  46. }
  47. // List 获取所有模板
  48. // GET /api/v1/admin/tls-fingerprint-profiles
  49. func (h *TLSFingerprintProfileHandler) List(c *gin.Context) {
  50. profiles, err := h.service.List(c.Request.Context())
  51. if err != nil {
  52. response.ErrorFrom(c, err)
  53. return
  54. }
  55. response.Success(c, profiles)
  56. }
  57. // GetByID 根据 ID 获取模板
  58. // GET /api/v1/admin/tls-fingerprint-profiles/:id
  59. func (h *TLSFingerprintProfileHandler) GetByID(c *gin.Context) {
  60. id, err := strconv.ParseInt(c.Param("id"), 10, 64)
  61. if err != nil {
  62. response.BadRequest(c, "Invalid profile ID")
  63. return
  64. }
  65. profile, err := h.service.GetByID(c.Request.Context(), id)
  66. if err != nil {
  67. response.ErrorFrom(c, err)
  68. return
  69. }
  70. if profile == nil {
  71. response.NotFound(c, "Profile not found")
  72. return
  73. }
  74. response.Success(c, profile)
  75. }
  76. // Create 创建模板
  77. // POST /api/v1/admin/tls-fingerprint-profiles
  78. func (h *TLSFingerprintProfileHandler) Create(c *gin.Context) {
  79. var req CreateTLSFingerprintProfileRequest
  80. if err := c.ShouldBindJSON(&req); err != nil {
  81. response.BadRequest(c, "Invalid request: "+err.Error())
  82. return
  83. }
  84. profile := &model.TLSFingerprintProfile{
  85. Name: req.Name,
  86. Description: req.Description,
  87. CipherSuites: req.CipherSuites,
  88. Curves: req.Curves,
  89. PointFormats: req.PointFormats,
  90. SignatureAlgorithms: req.SignatureAlgorithms,
  91. ALPNProtocols: req.ALPNProtocols,
  92. SupportedVersions: req.SupportedVersions,
  93. KeyShareGroups: req.KeyShareGroups,
  94. PSKModes: req.PSKModes,
  95. Extensions: req.Extensions,
  96. }
  97. if req.EnableGREASE != nil {
  98. profile.EnableGREASE = *req.EnableGREASE
  99. }
  100. created, err := h.service.Create(c.Request.Context(), profile)
  101. if err != nil {
  102. if _, ok := err.(*model.ValidationError); ok {
  103. response.BadRequest(c, err.Error())
  104. return
  105. }
  106. response.ErrorFrom(c, err)
  107. return
  108. }
  109. response.Success(c, created)
  110. }
  111. // Update 更新模板(支持部分更新)
  112. // PUT /api/v1/admin/tls-fingerprint-profiles/:id
  113. func (h *TLSFingerprintProfileHandler) Update(c *gin.Context) {
  114. id, err := strconv.ParseInt(c.Param("id"), 10, 64)
  115. if err != nil {
  116. response.BadRequest(c, "Invalid profile ID")
  117. return
  118. }
  119. var req UpdateTLSFingerprintProfileRequest
  120. if err := c.ShouldBindJSON(&req); err != nil {
  121. response.BadRequest(c, "Invalid request: "+err.Error())
  122. return
  123. }
  124. existing, err := h.service.GetByID(c.Request.Context(), id)
  125. if err != nil {
  126. response.ErrorFrom(c, err)
  127. return
  128. }
  129. if existing == nil {
  130. response.NotFound(c, "Profile not found")
  131. return
  132. }
  133. // 部分更新
  134. profile := &model.TLSFingerprintProfile{
  135. ID: id,
  136. Name: existing.Name,
  137. Description: existing.Description,
  138. EnableGREASE: existing.EnableGREASE,
  139. CipherSuites: existing.CipherSuites,
  140. Curves: existing.Curves,
  141. PointFormats: existing.PointFormats,
  142. SignatureAlgorithms: existing.SignatureAlgorithms,
  143. ALPNProtocols: existing.ALPNProtocols,
  144. SupportedVersions: existing.SupportedVersions,
  145. KeyShareGroups: existing.KeyShareGroups,
  146. PSKModes: existing.PSKModes,
  147. Extensions: existing.Extensions,
  148. }
  149. if req.Name != nil {
  150. profile.Name = *req.Name
  151. }
  152. if req.Description != nil {
  153. profile.Description = req.Description
  154. }
  155. if req.EnableGREASE != nil {
  156. profile.EnableGREASE = *req.EnableGREASE
  157. }
  158. if req.CipherSuites != nil {
  159. profile.CipherSuites = req.CipherSuites
  160. }
  161. if req.Curves != nil {
  162. profile.Curves = req.Curves
  163. }
  164. if req.PointFormats != nil {
  165. profile.PointFormats = req.PointFormats
  166. }
  167. if req.SignatureAlgorithms != nil {
  168. profile.SignatureAlgorithms = req.SignatureAlgorithms
  169. }
  170. if req.ALPNProtocols != nil {
  171. profile.ALPNProtocols = req.ALPNProtocols
  172. }
  173. if req.SupportedVersions != nil {
  174. profile.SupportedVersions = req.SupportedVersions
  175. }
  176. if req.KeyShareGroups != nil {
  177. profile.KeyShareGroups = req.KeyShareGroups
  178. }
  179. if req.PSKModes != nil {
  180. profile.PSKModes = req.PSKModes
  181. }
  182. if req.Extensions != nil {
  183. profile.Extensions = req.Extensions
  184. }
  185. updated, err := h.service.Update(c.Request.Context(), profile)
  186. if err != nil {
  187. if _, ok := err.(*model.ValidationError); ok {
  188. response.BadRequest(c, err.Error())
  189. return
  190. }
  191. response.ErrorFrom(c, err)
  192. return
  193. }
  194. response.Success(c, updated)
  195. }
  196. // Delete 删除模板
  197. // DELETE /api/v1/admin/tls-fingerprint-profiles/:id
  198. func (h *TLSFingerprintProfileHandler) Delete(c *gin.Context) {
  199. id, err := strconv.ParseInt(c.Param("id"), 10, 64)
  200. if err != nil {
  201. response.BadRequest(c, "Invalid profile ID")
  202. return
  203. }
  204. if err := h.service.Delete(c.Request.Context(), id); err != nil {
  205. response.ErrorFrom(c, err)
  206. return
  207. }
  208. response.Success(c, gin.H{"message": "Profile deleted successfully"})
  209. }