1+ using System . Net ;
2+ using System . Text . Json ;
3+ using System . Web ;
4+
5+ namespace OpenShock . API . IntegrationTests . HttpMessageHandlers ;
6+
7+ sealed class InterceptedHttpMessageHandler : DelegatingHandler
8+ {
9+ private async Task < HttpResponseMessage > HandleCloudflareTurnstileRequest ( HttpRequestMessage request , CancellationToken cancellationToken )
10+ {
11+ var formData = request . Content != null ? await request . Content . ReadAsStringAsync ( cancellationToken ) : string . Empty ;
12+ var parsedForm = HttpUtility . ParseQueryString ( formData ) ;
13+ var responseToken = parsedForm [ "response" ] ;
14+
15+ var responseDto = responseToken switch
16+ {
17+ "valid-token" => new CloudflareTurnstileVerifyResponseDto
18+ {
19+ Success = true ,
20+ ErrorCodes = [ ] ,
21+ ChallengeTs = DateTime . UtcNow ,
22+ Hostname = "validhost" ,
23+ Action = "validaction" ,
24+ Cdata = ""
25+ } ,
26+ "invalid-token" => new CloudflareTurnstileVerifyResponseDto
27+ {
28+ Success = false ,
29+ ErrorCodes = [ "invalid-input-response" ] ,
30+ ChallengeTs = DateTime . UtcNow ,
31+ Hostname = "invalidhost" ,
32+ Action = "invalidaction" ,
33+ Cdata = ""
34+ } ,
35+ _ => new CloudflareTurnstileVerifyResponseDto
36+ {
37+ Success = false ,
38+ ErrorCodes = [ "bad-request" ] ,
39+ ChallengeTs = DateTime . UtcNow ,
40+ Hostname = "unknownhost" ,
41+ Action = "unknownaction" ,
42+ Cdata = ""
43+ }
44+ } ;
45+
46+ var responseJson = JsonSerializer . Serialize ( responseDto ) ;
47+
48+ var responseMessage = new HttpResponseMessage ( HttpStatusCode . OK )
49+ {
50+ Content = new StringContent ( responseJson , System . Text . Encoding . UTF8 , "application/json" )
51+ } ;
52+
53+ return responseMessage ;
54+ }
55+
56+ private async Task < HttpResponseMessage > HandleMailJetApiHost ( HttpRequestMessage request , CancellationToken cancellationToken )
57+ {
58+ return new HttpResponseMessage ( HttpStatusCode . NotFound ) ;
59+ }
60+
61+ protected override async Task < HttpResponseMessage > SendAsync ( HttpRequestMessage request , CancellationToken cancellationToken )
62+ {
63+ return request . RequestUri switch
64+ {
65+ { Host : "challenges.cloudflare.com" , AbsolutePath : "/turnstile/v0/siteverify" } => await HandleCloudflareTurnstileRequest ( request , cancellationToken ) ,
66+ { Host : "api.mailjet.com" } => await HandleMailJetApiHost ( request , cancellationToken ) ,
67+ _ => new HttpResponseMessage ( HttpStatusCode . NotFound )
68+ } ;
69+ }
70+
71+ private class CloudflareTurnstileVerifyResponseDto
72+ {
73+ public bool Success { get ; set ; }
74+ public string [ ] ErrorCodes { get ; set ; }
75+ public DateTime ChallengeTs { get ; set ; }
76+ public string Hostname { get ; set ; }
77+ public string Action { get ; set ; }
78+ public string Cdata { get ; set ; }
79+ }
80+ }
0 commit comments