From f6a24cd17667f2acf3d255c41849f7acb7de2704 Mon Sep 17 00:00:00 2001 From: nevingeorgesunny Date: Tue, 13 Aug 2024 11:44:22 +0530 Subject: [PATCH 01/17] create a mockserver with com.sun.net.httpserver to be used in OpenShiftBearerTokenCredentialTest --- .../OpenShiftBearerTokenCredentialTest.java | 17 ++- ...ftBearerTokenCredentialTestMockServer.java | 106 ++++++++++++++++++ 2 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTestMockServer.java diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index cdee860..959074f 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -15,6 +15,8 @@ import java.io.IOException; import java.net.InetSocketAddress; +import com.sun.net.httpserver.HttpServer; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -27,14 +29,17 @@ public class OpenShiftBearerTokenCredentialTest { protected static final String USERNAME = "max.laverse"; protected static final String PASSWORD = "super-secret"; - @Rule - public JenkinsRule r = new JenkinsRule(); +// @Rule +// public JenkinsRule r = new JenkinsRule(); @Rule public ExpectedException expectedEx = ExpectedException.none(); private Server server; + private HttpServer server2; + private String mockserverBaseUrl; + @Before public void prepareFakeOAuthServer() throws Exception { InetSocketAddress addr = new InetSocketAddress("localhost", 0); @@ -44,6 +49,12 @@ public void prepareFakeOAuthServer() throws Exception { context.addServlet(new ServletHolder(new MockHttpServlet()), "/*"); server.setHandler(context); server.start(); + + + server2 = new OpenShiftBearerTokenCredentialTestMockServer().setupServer(); + server2.start(); + + mockserverBaseUrl = "http:/"+server2.getAddress()+"/"; } @After @@ -54,7 +65,7 @@ public void unprepareFakeOAuthServer() throws Exception { @Test public void testValidResponse() throws IOException { OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - String token = t.getToken(server.getURI() + "valid-response", null, true); + String token = t.getToken(mockserverBaseUrl + "valid-response", null, true); assertEquals("1234", token); } diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTestMockServer.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTestMockServer.java new file mode 100644 index 0000000..484dd4c --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTestMockServer.java @@ -0,0 +1,106 @@ +package org.jenkinsci.plugins.kubernetes.credentials; + + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.function.BiConsumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Author: Nevin Sunny + * Date: 13/08/24 + * Time: 11:24 am + */ +public class OpenShiftBearerTokenCredentialTestMockServer { + + public HttpServer setupServer() throws IOException { + HttpServer server = HttpServer + .create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0); + + BiConsumer register = server::createContext; + + register.accept("/bad-location/oauth/authorize", this::badLocationHandler); + register.accept("/missing-location/oauth/authorize", this::missingLocationHandler); + register.accept("/bad-response/oauth/authorize", this::badResponseHandler); + register.accept("/valid-response/oauth/authorize", this::validResponseHandler1); + register.accept("/valid-response2/oauth/authorize", this::validResponseHandler2); + register.accept("/", this::defaultHandler); + + return server; + } + + private void badLocationHandler(HttpExchange he) throws IOException { + String redirectURL = "bad"; + he.getResponseHeaders().set("Location", redirectURL); + he.sendResponseHeaders(302, -1); + } + + private void missingLocationHandler(HttpExchange he) throws IOException { + he.sendResponseHeaders(302, -1); // No Location header + } + + private void badResponseHandler(HttpExchange he) throws IOException { + he.sendResponseHeaders(400, -1); + } + + private void validResponseHandler1(HttpExchange he) throws IOException { + String redirectURL = "http://my-service/#access_token=1234&expires_in=86400"; + he.getResponseHeaders().set("Location", redirectURL); + he.sendResponseHeaders(302, -1); + } + + private void validResponseHandler2(HttpExchange he) throws IOException { + String redirectURL = "http://my-service/#access_token=1235&expires_in=86400"; + he.getResponseHeaders().set("Location", redirectURL); + he.sendResponseHeaders(302, -1); + } + + private void defaultHandler(HttpExchange he) throws IOException { + String path = he.getRequestURI().getPath(); + Pattern pattern = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); + Matcher matcher = pattern.matcher(path); + + if (matcher.find()) { + String responseToClient = "{\n" + + " \"issuer\": \"" + "http:/" + he.getLocalAddress() + "/\",\n" + + " \"authorization_endpoint\": \"" + "http:/" + he.getLocalAddress()+ matcher.group(1) + "/oauth/authorize\",\n" + + " \"token_endpoint\": \"" + "http:/" + he.getLocalAddress() + "/oauth/token\",\n" + + " \"scopes_supported\": [\n" + + " \"user:check-access\",\n" + + " \"user:full\",\n" + + " \"user:info\",\n" + + " \"user:list-projects\",\n" + + " \"user:list-scoped-projects\"\n" + + " ],\n" + + " \"response_types_supported\": [\n" + + " \"code\",\n" + + " \"token\"\n" + + " ],\n" + + " \"grant_types_supported\": [\n" + + " \"authorization_code\",\n" + + " \"implicit\"\n" + + " ],\n" + + " \"code_challenge_methods_supported\": [\n" + + " \"plain\",\n" + + " \"S256\"\n" + + " ]\n" + + "}"; + + byte[] responseBytes = responseToClient.getBytes(); + he.sendResponseHeaders(200, responseBytes.length); + try (OutputStream os = he.getResponseBody()) { + os.write(responseBytes); + } + } else { + he.sendResponseHeaders(500, -1); + he.getResponseBody().write(("Bad test: unknown path " + path).getBytes()); + } + } +} From 9d0e47a78a67bb56ddb56548d184809150a20d04 Mon Sep 17 00:00:00 2001 From: nevingeorgesunny Date: Tue, 13 Aug 2024 12:10:35 +0530 Subject: [PATCH 02/17] using the mockserver in OpenShiftBearerTokenCredentialTest and removed all the usaged of jetty server for doing moocks --- .../credentials/MockHttpServlet.java | 73 ------------------- .../OpenShiftBearerTokenCredentialTest.java | 41 +++-------- 2 files changed, 11 insertions(+), 103 deletions(-) delete mode 100644 src/test/java/org/jenkinsci/plugins/kubernetes/credentials/MockHttpServlet.java diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/MockHttpServlet.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/MockHttpServlet.java deleted file mode 100644 index 681864d..0000000 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/MockHttpServlet.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.jenkinsci.plugins.kubernetes.credentials; - -import org.eclipse.jetty.server.Request; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author Max Laverse - */ -public class MockHttpServlet extends HttpServlet { - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - switch (request.getPathInfo()) { - case "/bad-location/oauth/authorize": - response.sendRedirect("bad"); - break; - case "/missing-location/oauth/authorize": - response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); - break; - case "/bad-response/oauth/authorize": - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - break; - case "/valid-response/oauth/authorize": - response.sendRedirect("http://my-service/#access_token=1234&expires_in=86400"); - break; - case "/valid-response2/oauth/authorize": - response.sendRedirect("http://my-service/#access_token=1235&expires_in=86400"); - break; - default: - Pattern r = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); - // Now create matcher object. - Matcher m = r.matcher(request.getPathInfo()); - if (m.find()) { - String responseToClient = "{\n" + - " \"issuer\": \"" + ((Request) request).getRootURL() + "\",\n" + - " \"authorization_endpoint\": \"" + ((Request) request).getRootURL() + "/" + m.group(1) + "/oauth/authorize\",\n" + - " \"token_endpoint\": \"" + ((Request) request).getRootURL() + "/oauth/token\",\n" + - " \"scopes_supported\": [\n" + - " \"user:check-access\",\n" + - " \"user:full\",\n" + - " \"user:info\",\n" + - " \"user:list-projects\",\n" + - " \"user:list-scoped-projects\"\n" + - " ],\n" + - " \"response_types_supported\": [\n" + - " \"code\",\n" + - " \"token\"\n" + - " ],\n" + - " \"grant_types_supported\": [\n" + - " \"authorization_code\",\n" + - " \"implicit\"\n" + - " ],\n" + - " \"code_challenge_methods_supported\": [\n" + - " \"plain\",\n" + - " \"S256\"\n" + - " ]\n" + - "}"; - response.setStatus(HttpServletResponse.SC_OK); - response.getWriter().write(responseToClient); - response.getWriter().flush(); - response.getWriter().close(); - return; - } - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Bad test: unknown path " + request.getPathInfo()); - break; - } - } -} diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index 959074f..7903d95 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -2,18 +2,13 @@ import com.cloudbees.plugins.credentials.CredentialsScope; import hudson.util.Secret; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.jvnet.hudson.test.JenkinsRule; import java.io.IOException; -import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpServer; @@ -29,37 +24,23 @@ public class OpenShiftBearerTokenCredentialTest { protected static final String USERNAME = "max.laverse"; protected static final String PASSWORD = "super-secret"; -// @Rule -// public JenkinsRule r = new JenkinsRule(); - @Rule public ExpectedException expectedEx = ExpectedException.none(); - private Server server; - - private HttpServer server2; + private HttpServer server; private String mockserverBaseUrl; @Before public void prepareFakeOAuthServer() throws Exception { - InetSocketAddress addr = new InetSocketAddress("localhost", 0); - server = new Server(addr); - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/"); - context.addServlet(new ServletHolder(new MockHttpServlet()), "/*"); - server.setHandler(context); + server = new OpenShiftBearerTokenCredentialTestMockServer().setupServer(); server.start(); - - - server2 = new OpenShiftBearerTokenCredentialTestMockServer().setupServer(); - server2.start(); - - mockserverBaseUrl = "http:/"+server2.getAddress()+"/"; + mockserverBaseUrl = "http:/"+server.getAddress()+"/"; } @After public void unprepareFakeOAuthServer() throws Exception { - server.stop(); + //stop the server with zero delay + server.stop(0); } @Test @@ -72,9 +53,9 @@ public void testValidResponse() throws IOException { @Test public void testMultipleCachedTokens() throws IOException { OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - String token1 = t.getToken(server.getURI() + "valid-response", null, true); - String token2 = t.getToken(server.getURI() + "valid-response2", null, true); - String token3 = t.getToken(server.getURI() + "valid-response", null, true); + String token1 = t.getToken(mockserverBaseUrl + "valid-response", null, true); + String token2 = t.getToken(mockserverBaseUrl + "valid-response2", null, true); + String token3 = t.getToken(mockserverBaseUrl + "valid-response", null, true); assertEquals("1234", token1); assertEquals("1235", token2); assertEquals("1234", token3); @@ -86,7 +67,7 @@ public void testBadStatusCode() throws IOException { expectedEx.expectMessage("The response from the OAuth server was invalid: The OAuth service didn't respond with a redirection but with '400: Bad Request'"); OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - t.getToken(server.getURI() + "bad-response", null, true); + t.getToken(mockserverBaseUrl + "bad-response", null, true); } @Test @@ -95,7 +76,7 @@ public void testMissingLocation() throws IOException { expectedEx.expectMessage("The response from the OAuth server was invalid: The OAuth service didn't respond with location header"); OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - t.getToken(server.getURI() + "missing-location", null, true); + t.getToken(mockserverBaseUrl + "missing-location", null, true); } @Test @@ -104,7 +85,7 @@ public void testBadLocation() throws IOException { expectedEx.expectMessage("The response from the OAuth server was invalid: The response contained no token"); OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - t.getToken(server.getURI() + "bad-location", null, true); + t.getToken(mockserverBaseUrl + "bad-location", null, true); } @Test From 9333af7831710e0da60f60517322950f8b875ec4 Mon Sep 17 00:00:00 2001 From: nevingeorgesunny Date: Tue, 13 Aug 2024 13:33:56 +0530 Subject: [PATCH 03/17] removed JenkinsRule by mistake putting it back --- .../credentials/OpenShiftBearerTokenCredentialTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index 7903d95..f3f9b5c 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -7,6 +7,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.jvnet.hudson.test.JenkinsRule; import java.io.IOException; @@ -24,6 +25,9 @@ public class OpenShiftBearerTokenCredentialTest { protected static final String USERNAME = "max.laverse"; protected static final String PASSWORD = "super-secret"; + @Rule + public JenkinsRule r = new JenkinsRule(); + @Rule public ExpectedException expectedEx = ExpectedException.none(); From 6daded2926f65df7287197ddee9fcab92a207fd7 Mon Sep 17 00:00:00 2001 From: nevingeorgesunny Date: Tue, 13 Aug 2024 17:28:35 +0530 Subject: [PATCH 04/17] - AbstractOpenShiftBearerTokenCredentialFIPSTest is now using in-memory mock server - setting 17 2250.v03a_1295b_0a_30 2.472 --- pom.xml | 5 +- ...penShiftBearerTokenCredentialFIPSTest.java | 70 +++++++++---------- ...ShiftBearerTokenCredentialMockServer.java} | 51 +++++++------- .../OpenShiftBearerTokenCredentialTest.java | 4 +- 4 files changed, 66 insertions(+), 64 deletions(-) rename src/test/java/org/jenkinsci/plugins/kubernetes/credentials/{OpenShiftBearerTokenCredentialTestMockServer.java => OpenShiftBearerTokenCredentialMockServer.java} (60%) diff --git a/pom.xml b/pom.xml index 367df62..b37f58b 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ jenkinsci/${project.artifactId}-plugin - 2.426.3 + 2.472 bom-2.426.x 3208.vb_21177d4b_cd9 @@ -51,6 +51,9 @@ Max Low + + 17 + 2250.v03a_1295b_0a_30 diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java index a51cecf..3204d5b 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java @@ -1,16 +1,7 @@ package org.jenkinsci.plugins.kubernetes.credentials; import com.cloudbees.plugins.credentials.CredentialsScope; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.ssl.SslContextFactory; + import org.junit.After; import org.junit.Before; import org.junit.ClassRule; @@ -18,7 +9,16 @@ import org.jvnet.hudson.test.FlagRule; import java.io.IOException; +import java.net.InetSocketAddress; import java.net.URL; +import java.security.KeyStore; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; + +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; import static org.junit.Assert.fail; @@ -48,11 +48,7 @@ public abstract class AbstractOpenShiftBearerTokenCredentialFIPSTest { protected String motivation; - private Server server; - - private ServerConnector sslConnector; - - private ServerConnector serverConnector; + private HttpServer server; public AbstractOpenShiftBearerTokenCredentialFIPSTest( @@ -68,30 +64,34 @@ public void prepareFakeOAuthServer() throws Exception { if (keystore == null) { fail("Unable to find keystore.jks"); } - server = new Server(); - HttpConfiguration httpsConfig = new HttpConfiguration(); - httpsConfig.addCustomizer(new SecureRequestCustomizer()); + if ("https".equals(scheme)) { + server = HttpsServer.create(new InetSocketAddress("localhost", 0), 0); + setupHttps((HttpsServer) server); + OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); + } else { + server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); + } - SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setKeyStorePath(keystore.toExternalForm()); - sslContextFactory.setKeyManagerPassword("unittest"); - sslContextFactory.setKeyStorePassword("unittest"); + server.setExecutor(null); // Creates a default executor + server.start(); + } - sslConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, "http/1.1"), new HttpConnectionFactory(httpsConfig)); - serverConnector = new ServerConnector(server); - server.setConnectors(new Connector[]{serverConnector, sslConnector}); + private void setupHttps(HttpsServer httpsServer) throws Exception { + SSLContext sslContext = SSLContext.getInstance("TLS"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(keystore.openStream(), "unittest".toCharArray()); + kmf.init(ks, "unittest".toCharArray()); - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/"); - context.addServlet(new ServletHolder(new MockHttpServlet()), "/*"); - server.setHandler(context); - server.start(); + sslContext.init(kmf.getKeyManagers(), null, null); + httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); } @After public void unprepareFakeOAuthServer() throws Exception { - server.stop(); + server.stop(0); } @Test @@ -99,13 +99,7 @@ public void ensureFIPSCompliantURIRequest() throws IOException { OpenShiftBearerTokenCredentialImpl cred; cred = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, "id", "description", "username", "password"); try { - int port; - if ("https".equals(scheme)) { - port = sslConnector.getLocalPort(); - } else { - port = serverConnector.getLocalPort(); - } - cred.getToken(scheme + "://localhost:" + port + "/valid-response", null, skipTLSVerify); + cred.getToken(scheme + "://localhost:" + server.getAddress().getPort() + "/valid-response", null, skipTLSVerify); if (!shouldPass) { fail("This test was expected to fail, reason: " + motivation); } diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTestMockServer.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java similarity index 60% rename from src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTestMockServer.java rename to src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java index 484dd4c..e046fb8 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTestMockServer.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java @@ -4,11 +4,10 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsServer; import java.io.IOException; import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.util.function.BiConsumer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -18,60 +17,64 @@ * Date: 13/08/24 * Time: 11:24 am */ -public class OpenShiftBearerTokenCredentialTestMockServer { - - public HttpServer setupServer() throws IOException { - HttpServer server = HttpServer - .create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0); +public class OpenShiftBearerTokenCredentialMockServer { + public static void registerHttpHandlers(HttpServer server) throws IOException { BiConsumer register = server::createContext; - register.accept("/bad-location/oauth/authorize", this::badLocationHandler); - register.accept("/missing-location/oauth/authorize", this::missingLocationHandler); - register.accept("/bad-response/oauth/authorize", this::badResponseHandler); - register.accept("/valid-response/oauth/authorize", this::validResponseHandler1); - register.accept("/valid-response2/oauth/authorize", this::validResponseHandler2); - register.accept("/", this::defaultHandler); - - return server; + register.accept("/bad-location/oauth/authorize", + OpenShiftBearerTokenCredentialMockServer::badLocationHandler); + register.accept("/missing-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::missingLocationHandler); + register.accept("/bad-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::badResponseHandler); + register.accept("/valid-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler1); + register.accept("/valid-response2/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler2); + register.accept("/", OpenShiftBearerTokenCredentialMockServer::defaultHandler); } - private void badLocationHandler(HttpExchange he) throws IOException { + private static void badLocationHandler(HttpExchange he) throws IOException { String redirectURL = "bad"; he.getResponseHeaders().set("Location", redirectURL); he.sendResponseHeaders(302, -1); } - private void missingLocationHandler(HttpExchange he) throws IOException { + private static void missingLocationHandler(HttpExchange he) throws IOException { he.sendResponseHeaders(302, -1); // No Location header } - private void badResponseHandler(HttpExchange he) throws IOException { + private static void badResponseHandler(HttpExchange he) throws IOException { he.sendResponseHeaders(400, -1); } - private void validResponseHandler1(HttpExchange he) throws IOException { + private static void validResponseHandler1(HttpExchange he) throws IOException { String redirectURL = "http://my-service/#access_token=1234&expires_in=86400"; he.getResponseHeaders().set("Location", redirectURL); he.sendResponseHeaders(302, -1); } - private void validResponseHandler2(HttpExchange he) throws IOException { + private static void validResponseHandler2(HttpExchange he) throws IOException { String redirectURL = "http://my-service/#access_token=1235&expires_in=86400"; he.getResponseHeaders().set("Location", redirectURL); he.sendResponseHeaders(302, -1); } - private void defaultHandler(HttpExchange he) throws IOException { + private static void defaultHandler(HttpExchange he) throws IOException { String path = he.getRequestURI().getPath(); Pattern pattern = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); Matcher matcher = pattern.matcher(path); + String scheme = "http"; + if(he.getHttpContext().getServer() instanceof HttpsServer){ + scheme = "https"; + } + + String hostname = "localhost"; + int port = he.getLocalAddress().getPort(); + if (matcher.find()) { String responseToClient = "{\n" + - " \"issuer\": \"" + "http:/" + he.getLocalAddress() + "/\",\n" + - " \"authorization_endpoint\": \"" + "http:/" + he.getLocalAddress()+ matcher.group(1) + "/oauth/authorize\",\n" + - " \"token_endpoint\": \"" + "http:/" + he.getLocalAddress() + "/oauth/token\",\n" + + " \"issuer\": \"" + scheme + "://" + hostname + ":" + port + "/\",\n" + + " \"authorization_endpoint\": \"" + scheme + "://" + hostname + ":" + port + matcher.group(1) + "/oauth/authorize\",\n" + + " \"token_endpoint\": \"" + scheme + "://" + hostname + ":" + port + "/oauth/token\",\n" + " \"scopes_supported\": [\n" + " \"user:check-access\",\n" + " \"user:full\",\n" + diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index f3f9b5c..0be434f 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -10,6 +10,7 @@ import org.jvnet.hudson.test.JenkinsRule; import java.io.IOException; +import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpServer; @@ -36,7 +37,8 @@ public class OpenShiftBearerTokenCredentialTest { @Before public void prepareFakeOAuthServer() throws Exception { - server = new OpenShiftBearerTokenCredentialTestMockServer().setupServer(); + server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); server.start(); mockserverBaseUrl = "http:/"+server.getAddress()+"/"; } From 8e83a6a561fc5b4d7bf2e6fc78694c48c8cb7676 Mon Sep 17 00:00:00 2001 From: nevingeorgesunny Date: Wed, 14 Aug 2024 12:41:50 +0530 Subject: [PATCH 05/17] This file uses 8 space indentation when the rest of the files in this package seem to use 4 space indentation. fixing this --- ...nShiftBearerTokenCredentialMockServer.java | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java index e046fb8..cf35184 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java @@ -1,11 +1,9 @@ package org.jenkinsci.plugins.kubernetes.credentials; - import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsServer; - import java.io.IOException; import java.io.OutputStream; import java.util.function.BiConsumer; @@ -22,12 +20,14 @@ public class OpenShiftBearerTokenCredentialMockServer { public static void registerHttpHandlers(HttpServer server) throws IOException { BiConsumer register = server::createContext; - register.accept("/bad-location/oauth/authorize", - OpenShiftBearerTokenCredentialMockServer::badLocationHandler); - register.accept("/missing-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::missingLocationHandler); + register.accept("/bad-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::badLocationHandler); + register.accept( + "/missing-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::missingLocationHandler); register.accept("/bad-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::badResponseHandler); - register.accept("/valid-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler1); - register.accept("/valid-response2/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler2); + register.accept( + "/valid-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler1); + register.accept( + "/valid-response2/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler2); register.accept("/", OpenShiftBearerTokenCredentialMockServer::defaultHandler); } @@ -63,7 +63,7 @@ private static void defaultHandler(HttpExchange he) throws IOException { Matcher matcher = pattern.matcher(path); String scheme = "http"; - if(he.getHttpContext().getServer() instanceof HttpsServer){ + if (he.getHttpContext().getServer() instanceof HttpsServer) { scheme = "https"; } @@ -71,30 +71,30 @@ private static void defaultHandler(HttpExchange he) throws IOException { int port = he.getLocalAddress().getPort(); if (matcher.find()) { - String responseToClient = "{\n" + - " \"issuer\": \"" + scheme + "://" + hostname + ":" + port + "/\",\n" + - " \"authorization_endpoint\": \"" + scheme + "://" + hostname + ":" + port + matcher.group(1) + "/oauth/authorize\",\n" + - " \"token_endpoint\": \"" + scheme + "://" + hostname + ":" + port + "/oauth/token\",\n" + - " \"scopes_supported\": [\n" + - " \"user:check-access\",\n" + - " \"user:full\",\n" + - " \"user:info\",\n" + - " \"user:list-projects\",\n" + - " \"user:list-scoped-projects\"\n" + - " ],\n" + - " \"response_types_supported\": [\n" + - " \"code\",\n" + - " \"token\"\n" + - " ],\n" + - " \"grant_types_supported\": [\n" + - " \"authorization_code\",\n" + - " \"implicit\"\n" + - " ],\n" + - " \"code_challenge_methods_supported\": [\n" + - " \"plain\",\n" + - " \"S256\"\n" + - " ]\n" + - "}"; + String responseToClient = "{\n" + " \"issuer\": \"" + + scheme + "://" + hostname + ":" + port + "/\",\n" + " \"authorization_endpoint\": \"" + + scheme + "://" + hostname + ":" + port + matcher.group(1) + "/oauth/authorize\",\n" + + " \"token_endpoint\": \"" + + scheme + "://" + hostname + ":" + port + "/oauth/token\",\n" + " \"scopes_supported\": [\n" + + " \"user:check-access\",\n" + + " \"user:full\",\n" + + " \"user:info\",\n" + + " \"user:list-projects\",\n" + + " \"user:list-scoped-projects\"\n" + + " ],\n" + + " \"response_types_supported\": [\n" + + " \"code\",\n" + + " \"token\"\n" + + " ],\n" + + " \"grant_types_supported\": [\n" + + " \"authorization_code\",\n" + + " \"implicit\"\n" + + " ],\n" + + " \"code_challenge_methods_supported\": [\n" + + " \"plain\",\n" + + " \"S256\"\n" + + " ]\n" + + "}"; byte[] responseBytes = responseToClient.getBytes(); he.sendResponseHeaders(200, responseBytes.length); @@ -106,4 +106,4 @@ private static void defaultHandler(HttpExchange he) throws IOException { he.getResponseBody().write(("Bad test: unknown path " + path).getBytes()); } } -} +} \ No newline at end of file From 87473a96182c762ae51cf9ac90dcffe39d7a546b Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 07:05:28 -0700 Subject: [PATCH 06/17] Update pom.xml Co-authored-by: Mark Waite --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b37f58b..e5312c2 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ jenkinsci/${project.artifactId}-plugin - 2.472 + 2.426.3 bom-2.426.x 3208.vb_21177d4b_cd9 From 18c9fbbf5579d5aa24b0a61eef01d06d3bef10b3 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 07:05:36 -0700 Subject: [PATCH 07/17] Update pom.xml Co-authored-by: Mark Waite --- pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pom.xml b/pom.xml index e5312c2..367df62 100644 --- a/pom.xml +++ b/pom.xml @@ -51,9 +51,6 @@ Max Low - - 17 - 2250.v03a_1295b_0a_30 From 189fef9f3b86dee1b2fd3f527d485678c7b5032d Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 07:08:57 -0700 Subject: [PATCH 08/17] sort imports --- .../AbstractOpenShiftBearerTokenCredentialFIPSTest.java | 8 +++----- .../credentials/OpenShiftBearerTokenCredentialTest.java | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java index 3204d5b..60cbd9b 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java @@ -1,7 +1,9 @@ package org.jenkinsci.plugins.kubernetes.credentials; import com.cloudbees.plugins.credentials.CredentialsScope; - +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; @@ -16,10 +18,6 @@ import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; - import static org.junit.Assert.fail; public abstract class AbstractOpenShiftBearerTokenCredentialFIPSTest { diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index 0be434f..9d4da27 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -1,6 +1,7 @@ package org.jenkinsci.plugins.kubernetes.credentials; import com.cloudbees.plugins.credentials.CredentialsScope; +import com.sun.net.httpserver.HttpServer; import hudson.util.Secret; import org.junit.After; import org.junit.Before; @@ -12,8 +13,6 @@ import java.io.IOException; import java.net.InetSocketAddress; -import com.sun.net.httpserver.HttpServer; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; From 1330786186381742b4654d3579f6992ec8c6e04e Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 07:17:24 -0700 Subject: [PATCH 09/17] Format code consistently with other repositories --- ...nShiftBearerTokenCredentialMockServer.java | 189 ++++++++++-------- 1 file changed, 107 insertions(+), 82 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java index cf35184..7eac9a9 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java @@ -11,99 +11,124 @@ import java.util.regex.Pattern; /** - * Author: Nevin Sunny - * Date: 13/08/24 - * Time: 11:24 am + * @author Nevin Sunny */ public class OpenShiftBearerTokenCredentialMockServer { - public static void registerHttpHandlers(HttpServer server) throws IOException { - BiConsumer register = server::createContext; + public static void registerHttpHandlers(HttpServer server) throws IOException { + BiConsumer register = server::createContext; - register.accept("/bad-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::badLocationHandler); - register.accept( - "/missing-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::missingLocationHandler); - register.accept("/bad-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::badResponseHandler); - register.accept( - "/valid-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler1); - register.accept( - "/valid-response2/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler2); - register.accept("/", OpenShiftBearerTokenCredentialMockServer::defaultHandler); - } + register.accept( + "/bad-location/oauth/authorize", + OpenShiftBearerTokenCredentialMockServer::badLocationHandler); + register.accept( + "/missing-location/oauth/authorize", + OpenShiftBearerTokenCredentialMockServer::missingLocationHandler); + register.accept( + "/bad-response/oauth/authorize", + OpenShiftBearerTokenCredentialMockServer::badResponseHandler); + register.accept( + "/valid-response/oauth/authorize", + OpenShiftBearerTokenCredentialMockServer::validResponseHandler1); + register.accept( + "/valid-response2/oauth/authorize", + OpenShiftBearerTokenCredentialMockServer::validResponseHandler2); + register.accept("/", OpenShiftBearerTokenCredentialMockServer::defaultHandler); + } - private static void badLocationHandler(HttpExchange he) throws IOException { - String redirectURL = "bad"; - he.getResponseHeaders().set("Location", redirectURL); - he.sendResponseHeaders(302, -1); - } + private static void badLocationHandler(HttpExchange he) throws IOException { + String redirectURL = "bad"; + he.getResponseHeaders().set("Location", redirectURL); + he.sendResponseHeaders(302, -1); + } - private static void missingLocationHandler(HttpExchange he) throws IOException { - he.sendResponseHeaders(302, -1); // No Location header - } + private static void missingLocationHandler(HttpExchange he) throws IOException { + he.sendResponseHeaders(302, -1); // No Location header + } - private static void badResponseHandler(HttpExchange he) throws IOException { - he.sendResponseHeaders(400, -1); - } + private static void badResponseHandler(HttpExchange he) throws IOException { + he.sendResponseHeaders(400, -1); + } - private static void validResponseHandler1(HttpExchange he) throws IOException { - String redirectURL = "http://my-service/#access_token=1234&expires_in=86400"; - he.getResponseHeaders().set("Location", redirectURL); - he.sendResponseHeaders(302, -1); - } + private static void validResponseHandler1(HttpExchange he) throws IOException { + String redirectURL = "http://my-service/#access_token=1234&expires_in=86400"; + he.getResponseHeaders().set("Location", redirectURL); + he.sendResponseHeaders(302, -1); + } - private static void validResponseHandler2(HttpExchange he) throws IOException { - String redirectURL = "http://my-service/#access_token=1235&expires_in=86400"; - he.getResponseHeaders().set("Location", redirectURL); - he.sendResponseHeaders(302, -1); - } + private static void validResponseHandler2(HttpExchange he) throws IOException { + String redirectURL = "http://my-service/#access_token=1235&expires_in=86400"; + he.getResponseHeaders().set("Location", redirectURL); + he.sendResponseHeaders(302, -1); + } - private static void defaultHandler(HttpExchange he) throws IOException { - String path = he.getRequestURI().getPath(); - Pattern pattern = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); - Matcher matcher = pattern.matcher(path); + private static void defaultHandler(HttpExchange he) throws IOException { + String path = he.getRequestURI().getPath(); + Pattern pattern = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); + Matcher matcher = pattern.matcher(path); - String scheme = "http"; - if (he.getHttpContext().getServer() instanceof HttpsServer) { - scheme = "https"; - } + String scheme = "http"; + if (he.getHttpContext().getServer() instanceof HttpsServer) { + scheme = "https"; + } - String hostname = "localhost"; - int port = he.getLocalAddress().getPort(); + String hostname = "localhost"; + int port = he.getLocalAddress().getPort(); - if (matcher.find()) { - String responseToClient = "{\n" + " \"issuer\": \"" - + scheme + "://" + hostname + ":" + port + "/\",\n" + " \"authorization_endpoint\": \"" - + scheme + "://" + hostname + ":" + port + matcher.group(1) + "/oauth/authorize\",\n" - + " \"token_endpoint\": \"" - + scheme + "://" + hostname + ":" + port + "/oauth/token\",\n" + " \"scopes_supported\": [\n" - + " \"user:check-access\",\n" - + " \"user:full\",\n" - + " \"user:info\",\n" - + " \"user:list-projects\",\n" - + " \"user:list-scoped-projects\"\n" - + " ],\n" - + " \"response_types_supported\": [\n" - + " \"code\",\n" - + " \"token\"\n" - + " ],\n" - + " \"grant_types_supported\": [\n" - + " \"authorization_code\",\n" - + " \"implicit\"\n" - + " ],\n" - + " \"code_challenge_methods_supported\": [\n" - + " \"plain\",\n" - + " \"S256\"\n" - + " ]\n" - + "}"; + if (matcher.find()) { + String responseToClient = + "{\n" + + " \"issuer\": \"" + + scheme + + "://" + + hostname + + ":" + + port + + "/\",\n" + + " \"authorization_endpoint\": \"" + + scheme + + "://" + + hostname + + ":" + + port + + matcher.group(1) + + "/oauth/authorize\",\n" + + " \"token_endpoint\": \"" + + scheme + + "://" + + hostname + + ":" + + port + + "/oauth/token\",\n" + + " \"scopes_supported\": [\n" + + " \"user:check-access\",\n" + + " \"user:full\",\n" + + " \"user:info\",\n" + + " \"user:list-projects\",\n" + + " \"user:list-scoped-projects\"\n" + + " ],\n" + + " \"response_types_supported\": [\n" + + " \"code\",\n" + + " \"token\"\n" + + " ],\n" + + " \"grant_types_supported\": [\n" + + " \"authorization_code\",\n" + + " \"implicit\"\n" + + " ],\n" + + " \"code_challenge_methods_supported\": [\n" + + " \"plain\",\n" + + " \"S256\"\n" + + " ]\n" + + "}"; - byte[] responseBytes = responseToClient.getBytes(); - he.sendResponseHeaders(200, responseBytes.length); - try (OutputStream os = he.getResponseBody()) { - os.write(responseBytes); - } - } else { - he.sendResponseHeaders(500, -1); - he.getResponseBody().write(("Bad test: unknown path " + path).getBytes()); - } - } -} \ No newline at end of file + byte[] responseBytes = responseToClient.getBytes(); + he.sendResponseHeaders(200, responseBytes.length); + try (OutputStream os = he.getResponseBody()) { + os.write(responseBytes); + } + } else { + he.sendResponseHeaders(500, -1); + he.getResponseBody().write(("Bad test: unknown path " + path).getBytes()); + } + } +} From f8df999d2d3f507f83d295efa9f949da54c0c0f2 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 07:37:00 -0700 Subject: [PATCH 10/17] Remove unnecessary throws and comment The comment is unnecessary because it restates the code without providing any additional reasoning. --- .../credentials/OpenShiftBearerTokenCredentialTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index 9d4da27..0024a24 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -43,8 +43,7 @@ public void prepareFakeOAuthServer() throws Exception { } @After - public void unprepareFakeOAuthServer() throws Exception { - //stop the server with zero delay + public void unprepareFakeOAuthServer() { server.stop(0); } From b92127d7fb43bbfdd16285511bee158b4482ccb6 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 07:57:46 -0700 Subject: [PATCH 11/17] Improve legibility --- .../OpenShiftBearerTokenCredentialTest.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index 0024a24..08d5020 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -32,14 +32,12 @@ public class OpenShiftBearerTokenCredentialTest { public ExpectedException expectedEx = ExpectedException.none(); private HttpServer server; - private String mockserverBaseUrl; @Before public void prepareFakeOAuthServer() throws Exception { server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); server.start(); - mockserverBaseUrl = "http:/"+server.getAddress()+"/"; } @After @@ -47,19 +45,24 @@ public void unprepareFakeOAuthServer() { server.stop(0); } + private String getURI() { + InetSocketAddress address = server.getAddress(); + return "http://" + address.getHostString() + ":" + address.getPort() + "/"; + } + @Test public void testValidResponse() throws IOException { OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - String token = t.getToken(mockserverBaseUrl + "valid-response", null, true); + String token = t.getToken(getURI() + "valid-response", null, true); assertEquals("1234", token); } @Test public void testMultipleCachedTokens() throws IOException { OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - String token1 = t.getToken(mockserverBaseUrl + "valid-response", null, true); - String token2 = t.getToken(mockserverBaseUrl + "valid-response2", null, true); - String token3 = t.getToken(mockserverBaseUrl + "valid-response", null, true); + String token1 = t.getToken(getURI() + "valid-response", null, true); + String token2 = t.getToken(getURI() + "valid-response2", null, true); + String token3 = t.getToken(getURI() + "valid-response", null, true); assertEquals("1234", token1); assertEquals("1235", token2); assertEquals("1234", token3); @@ -71,7 +74,7 @@ public void testBadStatusCode() throws IOException { expectedEx.expectMessage("The response from the OAuth server was invalid: The OAuth service didn't respond with a redirection but with '400: Bad Request'"); OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - t.getToken(mockserverBaseUrl + "bad-response", null, true); + t.getToken(getURI() + "bad-response", null, true); } @Test @@ -80,7 +83,7 @@ public void testMissingLocation() throws IOException { expectedEx.expectMessage("The response from the OAuth server was invalid: The OAuth service didn't respond with location header"); OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - t.getToken(mockserverBaseUrl + "missing-location", null, true); + t.getToken(getURI() + "missing-location", null, true); } @Test @@ -89,7 +92,7 @@ public void testBadLocation() throws IOException { expectedEx.expectMessage("The response from the OAuth server was invalid: The response contained no token"); OpenShiftBearerTokenCredentialImpl t = new OpenShiftBearerTokenCredentialImpl(CredentialsScope.GLOBAL, CREDENTIAL_ID, "sample", USERNAME, PASSWORD); - t.getToken(mockserverBaseUrl + "bad-location", null, true); + t.getToken(getURI() + "bad-location", null, true); } @Test From cc67e8bac9eb17b9fa942a43e30a356569181a8d Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 07:58:14 -0700 Subject: [PATCH 12/17] Make tests consistent with each other --- ...tractOpenShiftBearerTokenCredentialFIPSTest.java | 13 ++++++++----- .../OpenShiftBearerTokenCredentialTest.java | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java index 60cbd9b..8629eb7 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java @@ -11,6 +11,7 @@ import org.jvnet.hudson.test.FlagRule; import java.io.IOException; +import java.io.InputStream; import java.net.InetSocketAddress; import java.net.URL; import java.security.KeyStore; @@ -63,16 +64,16 @@ public void prepareFakeOAuthServer() throws Exception { fail("Unable to find keystore.jks"); } + InetSocketAddress address = new InetSocketAddress("localhost", 0); if ("https".equals(scheme)) { - server = HttpsServer.create(new InetSocketAddress("localhost", 0), 0); + server = HttpsServer.create(address, 0); setupHttps((HttpsServer) server); OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); } else { - server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + server = HttpServer.create(address, 0); OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); } - server.setExecutor(null); // Creates a default executor server.start(); } @@ -80,7 +81,9 @@ private void setupHttps(HttpsServer httpsServer) throws Exception { SSLContext sslContext = SSLContext.getInstance("TLS"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(keystore.openStream(), "unittest".toCharArray()); + try (InputStream is = keystore.openStream()) { + ks.load(is, "unittest".toCharArray()); + } kmf.init(ks, "unittest".toCharArray()); sslContext.init(kmf.getKeyManagers(), null, null); @@ -88,7 +91,7 @@ private void setupHttps(HttpsServer httpsServer) throws Exception { } @After - public void unprepareFakeOAuthServer() throws Exception { + public void unprepareFakeOAuthServer() { server.stop(0); } diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java index 08d5020..c62adde 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialTest.java @@ -35,7 +35,8 @@ public class OpenShiftBearerTokenCredentialTest { @Before public void prepareFakeOAuthServer() throws Exception { - server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + InetSocketAddress address = new InetSocketAddress("localhost", 0); + server = HttpServer.create(address, 0); OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); server.start(); } From 1fd801c2368081a1c52fd3d4694e1b54f1c2fbfd Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 08:15:21 -0700 Subject: [PATCH 13/17] Code cleanup --- ...nShiftBearerTokenCredentialMockServer.java | 117 +++++++----------- 1 file changed, 45 insertions(+), 72 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java index 7eac9a9..46cc5cf 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java @@ -1,12 +1,12 @@ package org.jenkinsci.plugins.kubernetes.credentials; import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsServer; import java.io.IOException; import java.io.OutputStream; -import java.util.function.BiConsumer; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -15,30 +15,27 @@ */ public class OpenShiftBearerTokenCredentialMockServer { - public static void registerHttpHandlers(HttpServer server) throws IOException { - BiConsumer register = server::createContext; - - register.accept( + public static void registerHttpHandlers(HttpServer server) { + server.createContext( "/bad-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::badLocationHandler); - register.accept( + server.createContext( "/missing-location/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::missingLocationHandler); - register.accept( + server.createContext( "/bad-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::badResponseHandler); - register.accept( + server.createContext( "/valid-response/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler1); - register.accept( + server.createContext( "/valid-response2/oauth/authorize", OpenShiftBearerTokenCredentialMockServer::validResponseHandler2); - register.accept("/", OpenShiftBearerTokenCredentialMockServer::defaultHandler); + server.createContext("/", OpenShiftBearerTokenCredentialMockServer::defaultHandler); } private static void badLocationHandler(HttpExchange he) throws IOException { - String redirectURL = "bad"; - he.getResponseHeaders().set("Location", redirectURL); + he.getResponseHeaders().set("Location", "bad"); he.sendResponseHeaders(302, -1); } @@ -51,14 +48,12 @@ private static void badResponseHandler(HttpExchange he) throws IOException { } private static void validResponseHandler1(HttpExchange he) throws IOException { - String redirectURL = "http://my-service/#access_token=1234&expires_in=86400"; - he.getResponseHeaders().set("Location", redirectURL); + he.getResponseHeaders().set("Location", "http://my-service/#access_token=1234&expires_in=86400"); he.sendResponseHeaders(302, -1); } private static void validResponseHandler2(HttpExchange he) throws IOException { - String redirectURL = "http://my-service/#access_token=1235&expires_in=86400"; - he.getResponseHeaders().set("Location", redirectURL); + he.getResponseHeaders().set("Location", "http://my-service/#access_token=1235&expires_in=86400"); he.sendResponseHeaders(302, -1); } @@ -67,68 +62,46 @@ private static void defaultHandler(HttpExchange he) throws IOException { Pattern pattern = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); Matcher matcher = pattern.matcher(path); - String scheme = "http"; - if (he.getHttpContext().getServer() instanceof HttpsServer) { - scheme = "https"; - } - - String hostname = "localhost"; - int port = he.getLocalAddress().getPort(); + String scheme = he.getHttpContext().getServer() instanceof HttpsServer ? "https" : "http"; + String rootURL = scheme + "://localhost:" + he.getLocalAddress().getPort() + "/"; if (matcher.find()) { - String responseToClient = - "{\n" - + " \"issuer\": \"" - + scheme - + "://" - + hostname - + ":" - + port - + "/\",\n" - + " \"authorization_endpoint\": \"" - + scheme - + "://" - + hostname - + ":" - + port - + matcher.group(1) - + "/oauth/authorize\",\n" - + " \"token_endpoint\": \"" - + scheme - + "://" - + hostname - + ":" - + port - + "/oauth/token\",\n" - + " \"scopes_supported\": [\n" - + " \"user:check-access\",\n" - + " \"user:full\",\n" - + " \"user:info\",\n" - + " \"user:list-projects\",\n" - + " \"user:list-scoped-projects\"\n" - + " ],\n" - + " \"response_types_supported\": [\n" - + " \"code\",\n" - + " \"token\"\n" - + " ],\n" - + " \"grant_types_supported\": [\n" - + " \"authorization_code\",\n" - + " \"implicit\"\n" - + " ],\n" - + " \"code_challenge_methods_supported\": [\n" - + " \"plain\",\n" - + " \"S256\"\n" - + " ]\n" - + "}"; - - byte[] responseBytes = responseToClient.getBytes(); + String responseToClient = "{\n" + + " \"issuer\": \"" + rootURL + "\",\n" + + " \"authorization_endpoint\": \"" + rootURL + "/" + matcher.group(1) + "/oauth/authorize\",\n" + + " \"token_endpoint\": \"" + rootURL + "/oauth/token\",\n" + + " \"scopes_supported\": [\n" + + " \"user:check-access\",\n" + + " \"user:full\",\n" + + " \"user:info\",\n" + + " \"user:list-projects\",\n" + + " \"user:list-scoped-projects\"\n" + + " ],\n" + + " \"response_types_supported\": [\n" + + " \"code\",\n" + + " \"token\"\n" + + " ],\n" + + " \"grant_types_supported\": [\n" + + " \"authorization_code\",\n" + + " \"implicit\"\n" + + " ],\n" + + " \"code_challenge_methods_supported\": [\n" + + " \"plain\",\n" + + " \"S256\"\n" + + " ]\n" + + "}"; + byte[] responseBytes = responseToClient.getBytes(StandardCharsets.UTF_8); he.sendResponseHeaders(200, responseBytes.length); try (OutputStream os = he.getResponseBody()) { os.write(responseBytes); } } else { - he.sendResponseHeaders(500, -1); - he.getResponseBody().write(("Bad test: unknown path " + path).getBytes()); + String responseToClient = "Bad test: unknown path " + path; + byte[] responseBytes = responseToClient.getBytes(StandardCharsets.UTF_8); + he.sendResponseHeaders(500, responseBytes.length); + try (OutputStream os = he.getResponseBody()) { + os.write(responseBytes); + } } } } From 70851f40f5e1de5caa39ae4e45e25927dbed863a Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 08:23:00 -0700 Subject: [PATCH 14/17] De-duplicate --- pom.xml | 4 +++- .../AbstractOpenShiftBearerTokenCredentialFIPSTest.java | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 367df62..c916a59 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,9 @@ jenkinsci/${project.artifactId}-plugin - 2.426.3 + 2.472 + 2254.vcff7a_d4969e5 + 17 bom-2.426.x 3208.vb_21177d4b_cd9 diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java index 4382397..74609c1 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java @@ -69,11 +69,10 @@ public void prepareFakeOAuthServer() throws Exception { if ("https".equals(scheme)) { server = HttpsServer.create(address, 0); setupHttps((HttpsServer) server); - OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); } else { server = HttpServer.create(address, 0); - OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); } + OpenShiftBearerTokenCredentialMockServer.registerHttpHandlers(server); server.start(); } From a4ee1f1f782e0b4eb8b3068b32d8388962df0a8d Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 08:25:31 -0700 Subject: [PATCH 15/17] Undo local testing changes --- pom.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c916a59..367df62 100644 --- a/pom.xml +++ b/pom.xml @@ -42,9 +42,7 @@ jenkinsci/${project.artifactId}-plugin - 2.472 - 2254.vcff7a_d4969e5 - 17 + 2.426.3 bom-2.426.x 3208.vb_21177d4b_cd9 From 2c1f59be5965cdb0f01bd8dddb58741f477be2e3 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 08:34:12 -0700 Subject: [PATCH 16/17] Reduce scope and size of code change --- .../OpenShiftBearerTokenCredentialMockServer.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java index 46cc5cf..c65d097 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/OpenShiftBearerTokenCredentialMockServer.java @@ -59,16 +59,15 @@ private static void validResponseHandler2(HttpExchange he) throws IOException { private static void defaultHandler(HttpExchange he) throws IOException { String path = he.getRequestURI().getPath(); - Pattern pattern = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); - Matcher matcher = pattern.matcher(path); - - String scheme = he.getHttpContext().getServer() instanceof HttpsServer ? "https" : "http"; - String rootURL = scheme + "://localhost:" + he.getLocalAddress().getPort() + "/"; - - if (matcher.find()) { + Pattern r = Pattern.compile("(.*)/.well-known/oauth-authorization-server"); + // Now create matcher object. + Matcher m = r.matcher(path); + if (m.find()) { + String scheme = he.getHttpContext().getServer() instanceof HttpsServer ? "https" : "http"; + String rootURL = scheme + "://localhost:" + he.getLocalAddress().getPort() + "/"; String responseToClient = "{\n" + " \"issuer\": \"" + rootURL + "\",\n" + - " \"authorization_endpoint\": \"" + rootURL + "/" + matcher.group(1) + "/oauth/authorize\",\n" + + " \"authorization_endpoint\": \"" + rootURL + "/" + m.group(1) + "/oauth/authorize\",\n" + " \"token_endpoint\": \"" + rootURL + "/oauth/token\",\n" + " \"scopes_supported\": [\n" + " \"user:check-access\",\n" + From 939395af0b904f2cdd98cc4ac3c7e34821c4395b Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Wed, 14 Aug 2024 08:42:30 -0700 Subject: [PATCH 17/17] No need to change test behavior This test was previously listening on all interfaces before this change. Keep the same behavior after this change to avoid unrelated code change during a routine refactoring. --- .../AbstractOpenShiftBearerTokenCredentialFIPSTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java index 74609c1..c10f877 100644 --- a/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java +++ b/src/test/java/org/jenkinsci/plugins/kubernetes/credentials/AbstractOpenShiftBearerTokenCredentialFIPSTest.java @@ -65,7 +65,7 @@ public void prepareFakeOAuthServer() throws Exception { fail("Unable to find keystore.jks"); } - InetSocketAddress address = new InetSocketAddress("localhost", 0); + InetSocketAddress address = new InetSocketAddress(0); if ("https".equals(scheme)) { server = HttpsServer.create(address, 0); setupHttps((HttpsServer) server);