package handler import ( "net/http" "affiliate_dash/internal/pkg/response" "affiliate_dash/internal/service" "github.com/gin-gonic/gin" ) // DCAuthHandler 暴露 DCAuth 2.0.0 协议端点。 type DCAuthHandler struct { svc *service.DCAuthService } func NewDCAuthHandler(svc *service.DCAuthService) *DCAuthHandler { return &DCAuthHandler{svc: svc} } // Authorize 接收 DCAuth 客户端签名并推进 challenge 到 authorized。 func (h *DCAuthHandler) Authorize(c *gin.Context) { if h == nil || h.svc == nil { writeDCAuthError(c, newDCAuthUnavailable()) return } var req service.DCAuthorizeRequest if err := c.ShouldBindJSON(&req); err != nil { writeDCAuthError(c, &service.AuthError{Status: http.StatusBadRequest, Code: "payload_invalid", Message: "设备认证参数无效"}) return } if err := h.svc.Authorize(req); err != nil { writeDCAuthError(c, err) return } response.OK(c, gin.H{"status": "authorized"}) } // Status 轮询 challenge 状态;authorized 时签发一次性 deviceTicket。 func (h *DCAuthHandler) Status(c *gin.Context) { if h == nil || h.svc == nil { writeDCAuthError(c, newDCAuthUnavailable()) return } pollToken := c.GetHeader("X-Poll-Token") if pollToken == "" { pollToken = c.Query("pollToken") } status, err := h.svc.ChallengeStatus(c.Param("challengeId"), pollToken) if err != nil { writeDCAuthError(c, err) return } response.OK(c, status) } func newDCAuthUnavailable() *service.AuthError { return &service.AuthError{Status: http.StatusServiceUnavailable, Code: "device_auth_unavailable", Message: "设备认证服务未配置"} } // writeDCAuthError 使用协议约定的字符串 error code,便于 DCAuth 客户端识别。 func writeDCAuthError(c *gin.Context, err error) { if authErr, ok := service.AsAuthError(err); ok { c.JSON(authErr.Status, gin.H{"code": authErr.Code, "message": authErr.Message}) return } c.JSON(http.StatusInternalServerError, gin.H{"code": "internal_error", "message": "设备认证服务异常"}) }