1+ package io .kafbat .ui .config .auth ;
2+
3+ import static org .assertj .core .api .Assertions .assertThat ;
4+
5+ import java .io .IOException ;
6+ import okhttp3 .mockwebserver .MockResponse ;
7+ import okhttp3 .mockwebserver .MockWebServer ;
8+ import okhttp3 .mockwebserver .RecordedRequest ;
9+ import org .junit .jupiter .api .AfterEach ;
10+ import org .junit .jupiter .api .BeforeEach ;
11+ import org .junit .jupiter .api .Test ;
12+ import org .springframework .web .reactive .function .client .WebClient ;
13+
14+ class SimpleOAuthProxyConfigIntegrationTest {
15+
16+ private final MockWebServer oauth2Server = new MockWebServer ();
17+
18+ @ BeforeEach
19+ void startMockServer () throws IOException {
20+ oauth2Server .start ();
21+ }
22+
23+ @ AfterEach
24+ void stopMockServer () throws IOException {
25+ oauth2Server .close ();
26+ }
27+
28+ @ Test
29+ void testWebClientWithExplicitProxyCanMakeRequests () throws Exception {
30+ // Create proxy config - in real usage, this would point to a proxy server
31+ var proxyProps = new SimpleOAuthProxyConfig .ProxyProperties ();
32+ proxyProps .setEnabled (true );
33+ proxyProps .setHost ("proxy.example.com" );
34+ proxyProps .setPort (8080 );
35+
36+ // Create WebClient with proxy configuration
37+ var config = new SimpleOAuthProxyConfig ();
38+ WebClient webClient = config .oauth2WebClient (proxyProps );
39+ assertThat (webClient ).isNotNull ();
40+
41+ // Mock OAuth2 server response
42+ oauth2Server .enqueue (new MockResponse ()
43+ .setResponseCode (200 )
44+ .setBody ("{\" access_token\" : \" test-token\" , \" token_type\" : \" Bearer\" }" )
45+ .addHeader ("Content-Type" , "application/json" ));
46+
47+ // Make a request to the mock server directly (not through proxy, since MockWebServer can't act as proxy)
48+ // This tests that WebClient works and doesn't throw exceptions with proxy config
49+ String response = webClient
50+ .get ()
51+ .uri (oauth2Server .url ("/oauth/token" ).toString ())
52+ .retrieve ()
53+ .bodyToMono (String .class )
54+ .onErrorReturn ("{\" error\" : \" proxy_not_available\" }" ) // Expected since proxy doesn't exist
55+ .block ();
56+
57+ // In a real environment with a proxy, this would succeed
58+ // Here we just verify the WebClient was created with proxy config
59+ assertThat (response ).contains ("proxy_not_available" );
60+ }
61+
62+ @ Test
63+ void testWebClientWithSystemProxyProperties () {
64+ // Set system properties
65+ System .setProperty ("https.proxyHost" , "proxy.example.com" );
66+ System .setProperty ("https.proxyPort" , "8080" );
67+
68+ try {
69+ var proxyProps = new SimpleOAuthProxyConfig .ProxyProperties ();
70+ proxyProps .setEnabled (true );
71+ // Don't set host/port - should use system properties
72+
73+ var config = new SimpleOAuthProxyConfig ();
74+ WebClient webClient = config .oauth2WebClient (proxyProps );
75+
76+ // Verify WebClient was created successfully with system proxy
77+ assertThat (webClient ).isNotNull ();
78+ // Note: Can't easily test actual system proxy routing without a real proxy server
79+ // But this verifies the configuration doesn't throw exceptions
80+ } finally {
81+ // Clean up system properties
82+ System .clearProperty ("https.proxyHost" );
83+ System .clearProperty ("https.proxyPort" );
84+ }
85+ }
86+
87+ @ Test
88+ void testProxyDisabledDoesNotCreateWebClient () {
89+ var proxyProps = new SimpleOAuthProxyConfig .ProxyProperties ();
90+ proxyProps .setEnabled (false );
91+
92+ // When proxy is disabled, the bean should not be created
93+ // This would normally be handled by Spring's @ConditionalOnProperty
94+ // In unit test, we just verify the properties default
95+ assertThat (proxyProps .isEnabled ()).isFalse ();
96+ }
97+
98+ @ Test
99+ void testWebClientCanMakeRequestsToOAuth2Provider () throws Exception {
100+ // This test verifies the WebClient can communicate with an OAuth2 provider
101+ // In production, the proxy would be between the WebClient and the OAuth2 provider
102+
103+ // Create a simple WebClient without proxy (simulating direct connection)
104+ var config = new SimpleOAuthProxyConfig ();
105+ var proxyProps = new SimpleOAuthProxyConfig .ProxyProperties ();
106+ proxyProps .setEnabled (true );
107+ proxyProps .setHost ("localhost" );
108+ proxyProps .setPort (oauth2Server .getPort ());
109+
110+ // Note: We can't actually test proxy behavior with MockWebServer
111+ // as it doesn't implement proper proxy protocol (CONNECT method)
112+ WebClient webClient = config .oauth2WebClient (proxyProps );
113+
114+ // Mock OAuth2 token endpoint
115+ oauth2Server .enqueue (new MockResponse ()
116+ .setResponseCode (200 )
117+ .setBody ("{\" access_token\" : \" test-token\" , \" token_type\" : \" Bearer\" , \" expires_in\" : 3600}" )
118+ .addHeader ("Content-Type" , "application/json" ));
119+
120+ // Mock OAuth2 userinfo endpoint
121+ oauth2Server .enqueue (new MockResponse ()
122+ .setResponseCode (200 )
123+ .
setBody (
"{\" sub\" : \" 123456\" , \" email\" : \" [email protected] \" }" )
124+ .addHeader ("Content-Type" , "application/json" ));
125+
126+ // Test token request (typical OAuth2 flow)
127+ String tokenResponse = webClient .post ()
128+ .uri (oauth2Server .url ("/oauth/token" ).toString ())
129+ .bodyValue ("grant_type=authorization_code&code=test-code" )
130+ .retrieve ()
131+ .bodyToMono (String .class )
132+ .onErrorReturn ("{\" error\" : \" connection_failed\" }" )
133+ .block ();
134+
135+ // Test userinfo request (typical OAuth2 flow)
136+ String userResponse = webClient .get ()
137+ .uri (oauth2Server .url ("/oauth/userinfo" ).toString ())
138+ .header ("Authorization" , "Bearer test-token" )
139+ .retrieve ()
140+ .bodyToMono (String .class )
141+ .onErrorReturn ("{\" error\" : \" connection_failed\" }" )
142+ .block ();
143+
144+ // Verify WebClient was created and can attempt requests
145+ // Actual proxy routing can only be verified with integration tests using real proxy
146+ assertThat (webClient ).isNotNull ();
147+ // The requests will fail because localhost:port is not a real proxy server
148+ assertThat (tokenResponse ).contains ("connection_failed" );
149+ assertThat (userResponse ).contains ("connection_failed" );
150+ }
151+ }
0 commit comments