fix(settings): 保存 Turnstile 设置时验证参数有效性
This commit is contained in:
@@ -109,7 +109,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
|||||||
antigravityOAuthHandler := admin.NewAntigravityOAuthHandler(antigravityOAuthService)
|
antigravityOAuthHandler := admin.NewAntigravityOAuthHandler(antigravityOAuthService)
|
||||||
proxyHandler := admin.NewProxyHandler(adminService)
|
proxyHandler := admin.NewProxyHandler(adminService)
|
||||||
adminRedeemHandler := admin.NewRedeemHandler(adminService)
|
adminRedeemHandler := admin.NewRedeemHandler(adminService)
|
||||||
settingHandler := admin.NewSettingHandler(settingService, emailService)
|
settingHandler := admin.NewSettingHandler(settingService, emailService, turnstileService)
|
||||||
updateCache := repository.NewUpdateCache(redisClient)
|
updateCache := repository.NewUpdateCache(redisClient)
|
||||||
gitHubReleaseClient := repository.NewGitHubReleaseClient()
|
gitHubReleaseClient := repository.NewGitHubReleaseClient()
|
||||||
serviceBuildInfo := provideServiceBuildInfo(buildInfo)
|
serviceBuildInfo := provideServiceBuildInfo(buildInfo)
|
||||||
|
|||||||
@@ -10,15 +10,17 @@ import (
|
|||||||
|
|
||||||
// SettingHandler 系统设置处理器
|
// SettingHandler 系统设置处理器
|
||||||
type SettingHandler struct {
|
type SettingHandler struct {
|
||||||
settingService *service.SettingService
|
settingService *service.SettingService
|
||||||
emailService *service.EmailService
|
emailService *service.EmailService
|
||||||
|
turnstileService *service.TurnstileService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSettingHandler 创建系统设置处理器
|
// NewSettingHandler 创建系统设置处理器
|
||||||
func NewSettingHandler(settingService *service.SettingService, emailService *service.EmailService) *SettingHandler {
|
func NewSettingHandler(settingService *service.SettingService, emailService *service.EmailService, turnstileService *service.TurnstileService) *SettingHandler {
|
||||||
return &SettingHandler{
|
return &SettingHandler{
|
||||||
settingService: settingService,
|
settingService: settingService,
|
||||||
emailService: emailService,
|
emailService: emailService,
|
||||||
|
turnstileService: turnstileService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +110,36 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
|||||||
req.SmtpPort = 587
|
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{
|
settings := &service.SystemSettings{
|
||||||
RegistrationEnabled: req.RegistrationEnabled,
|
RegistrationEnabled: req.RegistrationEnabled,
|
||||||
EmailVerifyEnabled: req.EmailVerifyEnabled,
|
EmailVerifyEnabled: req.EmailVerifyEnabled,
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ func newContractDeps(t *testing.T) *contractDeps {
|
|||||||
authHandler := handler.NewAuthHandler(cfg, nil, userService)
|
authHandler := handler.NewAuthHandler(cfg, nil, userService)
|
||||||
apiKeyHandler := handler.NewAPIKeyHandler(apiKeyService)
|
apiKeyHandler := handler.NewAPIKeyHandler(apiKeyService)
|
||||||
usageHandler := handler.NewUsageHandler(usageService, apiKeyService)
|
usageHandler := handler.NewUsageHandler(usageService, apiKeyService)
|
||||||
adminSettingHandler := adminhandler.NewSettingHandler(settingService, nil)
|
adminSettingHandler := adminhandler.NewSettingHandler(settingService, nil, nil)
|
||||||
|
|
||||||
jwtAuth := func(c *gin.Context) {
|
jwtAuth := func(c *gin.Context) {
|
||||||
c.Set(string(middleware.ContextKeyUser), middleware.AuthSubject{
|
c.Set(string(middleware.ContextKeyUser), middleware.AuthSubject{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
ErrTurnstileVerificationFailed = infraerrors.BadRequest("TURNSTILE_VERIFICATION_FAILED", "turnstile verification failed")
|
ErrTurnstileVerificationFailed = infraerrors.BadRequest("TURNSTILE_VERIFICATION_FAILED", "turnstile verification failed")
|
||||||
ErrTurnstileNotConfigured = infraerrors.ServiceUnavailable("TURNSTILE_NOT_CONFIGURED", "turnstile not configured")
|
ErrTurnstileNotConfigured = infraerrors.ServiceUnavailable("TURNSTILE_NOT_CONFIGURED", "turnstile not configured")
|
||||||
|
ErrTurnstileInvalidSecretKey = infraerrors.BadRequest("TURNSTILE_INVALID_SECRET_KEY", "invalid turnstile secret key")
|
||||||
)
|
)
|
||||||
|
|
||||||
// TurnstileVerifier 验证 Turnstile token 的接口
|
// 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 {
|
func (s *TurnstileService) IsEnabled(ctx context.Context) bool {
|
||||||
return s.settingService.IsTurnstileEnabled(ctx)
|
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