fix(settings): 保存 Turnstile 设置时验证参数有效性
This commit is contained in:
@@ -109,7 +109,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
antigravityOAuthHandler := admin.NewAntigravityOAuthHandler(antigravityOAuthService)
|
||||
proxyHandler := admin.NewProxyHandler(adminService)
|
||||
adminRedeemHandler := admin.NewRedeemHandler(adminService)
|
||||
settingHandler := admin.NewSettingHandler(settingService, emailService)
|
||||
settingHandler := admin.NewSettingHandler(settingService, emailService, turnstileService)
|
||||
updateCache := repository.NewUpdateCache(redisClient)
|
||||
gitHubReleaseClient := repository.NewGitHubReleaseClient()
|
||||
serviceBuildInfo := provideServiceBuildInfo(buildInfo)
|
||||
|
||||
@@ -10,15 +10,17 @@ import (
|
||||
|
||||
// SettingHandler 系统设置处理器
|
||||
type SettingHandler struct {
|
||||
settingService *service.SettingService
|
||||
emailService *service.EmailService
|
||||
settingService *service.SettingService
|
||||
emailService *service.EmailService
|
||||
turnstileService *service.TurnstileService
|
||||
}
|
||||
|
||||
// NewSettingHandler 创建系统设置处理器
|
||||
func NewSettingHandler(settingService *service.SettingService, emailService *service.EmailService) *SettingHandler {
|
||||
func NewSettingHandler(settingService *service.SettingService, emailService *service.EmailService, turnstileService *service.TurnstileService) *SettingHandler {
|
||||
return &SettingHandler{
|
||||
settingService: settingService,
|
||||
emailService: emailService,
|
||||
settingService: settingService,
|
||||
emailService: emailService,
|
||||
turnstileService: turnstileService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +110,36 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
||||
req.SmtpPort = 587
|
||||
}
|
||||
|
||||
// Turnstile 参数验证
|
||||
if req.TurnstileEnabled {
|
||||
// 检查必填字段
|
||||
if req.TurnstileSiteKey == "" {
|
||||
response.BadRequest(c, "Turnstile Site Key is required when enabled")
|
||||
return
|
||||
}
|
||||
if req.TurnstileSecretKey == "" {
|
||||
response.BadRequest(c, "Turnstile Secret Key is required when enabled")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前设置,检查参数是否有变化
|
||||
currentSettings, err := h.settingService.GetAllSettings(c.Request.Context())
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 当 site_key 或 secret_key 任一变化时验证(避免配置错误导致无法登录)
|
||||
siteKeyChanged := currentSettings.TurnstileSiteKey != req.TurnstileSiteKey
|
||||
secretKeyChanged := currentSettings.TurnstileSecretKey != req.TurnstileSecretKey
|
||||
if siteKeyChanged || secretKeyChanged {
|
||||
if err := h.turnstileService.ValidateSecretKey(c.Request.Context(), req.TurnstileSecretKey); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings := &service.SystemSettings{
|
||||
RegistrationEnabled: req.RegistrationEnabled,
|
||||
EmailVerifyEnabled: req.EmailVerifyEnabled,
|
||||
|
||||
@@ -385,7 +385,7 @@ func newContractDeps(t *testing.T) *contractDeps {
|
||||
authHandler := handler.NewAuthHandler(cfg, nil, userService)
|
||||
apiKeyHandler := handler.NewAPIKeyHandler(apiKeyService)
|
||||
usageHandler := handler.NewUsageHandler(usageService, apiKeyService)
|
||||
adminSettingHandler := adminhandler.NewSettingHandler(settingService, nil)
|
||||
adminSettingHandler := adminhandler.NewSettingHandler(settingService, nil, nil)
|
||||
|
||||
jwtAuth := func(c *gin.Context) {
|
||||
c.Set(string(middleware.ContextKeyUser), middleware.AuthSubject{
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
var (
|
||||
ErrTurnstileVerificationFailed = infraerrors.BadRequest("TURNSTILE_VERIFICATION_FAILED", "turnstile verification failed")
|
||||
ErrTurnstileNotConfigured = infraerrors.ServiceUnavailable("TURNSTILE_NOT_CONFIGURED", "turnstile not configured")
|
||||
ErrTurnstileInvalidSecretKey = infraerrors.BadRequest("TURNSTILE_INVALID_SECRET_KEY", "invalid turnstile secret key")
|
||||
)
|
||||
|
||||
// TurnstileVerifier 验证 Turnstile token 的接口
|
||||
@@ -83,3 +84,22 @@ func (s *TurnstileService) VerifyToken(ctx context.Context, token string, remote
|
||||
func (s *TurnstileService) IsEnabled(ctx context.Context) bool {
|
||||
return s.settingService.IsTurnstileEnabled(ctx)
|
||||
}
|
||||
|
||||
// ValidateSecretKey 验证 Turnstile Secret Key 是否有效
|
||||
func (s *TurnstileService) ValidateSecretKey(ctx context.Context, secretKey string) error {
|
||||
// 发送一个测试token的验证请求来检查secret_key是否有效
|
||||
result, err := s.verifier.VerifyToken(ctx, secretKey, "test-validation", "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("validate secret key: %w", err)
|
||||
}
|
||||
|
||||
// 检查是否有 invalid-input-secret 错误
|
||||
for _, code := range result.ErrorCodes {
|
||||
if code == "invalid-input-secret" {
|
||||
return ErrTurnstileInvalidSecretKey
|
||||
}
|
||||
}
|
||||
|
||||
// 其他错误(如 invalid-input-response)说明 secret key 是有效的
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user