1 package io.apicurio.registry.maven;
2
3 import com.github.tomakehurst.wiremock.WireMockServer;
4 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
5 import io.apicurio.registry.rest.v3.beans.IfArtifactExists;
6 import io.apicurio.registry.types.ArtifactType;
7 import org.apache.maven.plugin.MojoExecutionException;
8 import org.junit.jupiter.api.AfterEach;
9 import org.junit.jupiter.api.BeforeEach;
10 import org.junit.jupiter.api.Test;
11
12 import java.io.File;
13 import java.nio.file.Files;
14 import java.util.Collections;
15
16 import static com.github.tomakehurst.wiremock.client.WireMock.*;
17 import static org.junit.jupiter.api.Assertions.*;
18
19
20
21
22
23 public class TlsIntegrationTest {
24
25 private static final String CERTS_DIR = "src/test/resources/certs";
26 private static final String PASSWORD = "changeit";
27
28 private WireMockServer wireMockServer;
29 private RegisterRegistryMojo mojo;
30 private File tempSchemaFile;
31
32 @BeforeEach
33 void setup() throws Exception {
34
35 tempSchemaFile = Files.createTempFile("test-schema", ".avsc").toFile();
36 Files.writeString(tempSchemaFile.toPath(), """
37 {
38 "type": "record",
39 "name": "TestRecord",
40 "namespace": "io.apicurio.test",
41 "fields": [
42 {"name": "id", "type": "string"}
43 ]
44 }
45 """);
46 tempSchemaFile.deleteOnExit();
47
48 mojo = new RegisterRegistryMojo();
49 }
50
51 @AfterEach
52 void tearDown() {
53 if (wireMockServer != null && wireMockServer.isRunning()) {
54 wireMockServer.stop();
55 }
56 if (tempSchemaFile != null) {
57 tempSchemaFile.delete();
58 }
59 }
60
61 private void startHttpsServer() {
62 WireMockConfiguration config = WireMockConfiguration.wireMockConfig()
63 .dynamicHttpsPort()
64 .httpDisabled(true)
65 .keystorePath(getResourcePath("server-keystore.jks"))
66 .keystorePassword(PASSWORD)
67 .keyManagerPassword(PASSWORD)
68 .keystoreType("JKS");
69
70 wireMockServer = new WireMockServer(config);
71 wireMockServer.start();
72
73
74 wireMockServer.stubFor(post(urlPathMatching("/apis/registry/v3/groups/.*/artifacts"))
75 .willReturn(aResponse()
76 .withStatus(200)
77 .withHeader("Content-Type", "application/json")
78 .withBody("""
79 {
80 "version": {
81 "version": "1",
82 "globalId": 12345,
83 "contentId": 67890
84 },
85 "artifact": {
86 "groupId": "test-group",
87 "artifactId": "TestRecord"
88 }
89 }
90 """)));
91 }
92
93 private String getResourcePath(String filename) {
94 return new File(CERTS_DIR, filename).getAbsolutePath();
95 }
96
97 private RegisterArtifact createTestArtifact() {
98 RegisterArtifact artifact = new RegisterArtifact();
99 artifact.setGroupId("test-group");
100 artifact.setArtifactId("TestRecord");
101 artifact.setArtifactType(ArtifactType.AVRO);
102 artifact.setFile(tempSchemaFile);
103 artifact.setIfExists(IfArtifactExists.FIND_OR_CREATE_VERSION);
104 return artifact;
105 }
106
107
108
109
110
111 @Test
112 void testTlsWithPkcs12TrustStore() throws Exception {
113 startHttpsServer();
114
115 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
116 mojo.setTrustStorePath(getResourcePath("truststore.p12"));
117 mojo.setTrustStorePassword(PASSWORD);
118 mojo.setArtifacts(Collections.singletonList(createTestArtifact()));
119
120
121 assertDoesNotThrow(() -> mojo.execute());
122
123
124 wireMockServer.verify(postRequestedFor(urlPathMatching("/apis/registry/v3/groups/.*/artifacts")));
125 }
126
127 @Test
128 void testTlsWithJksTrustStore() throws Exception {
129 startHttpsServer();
130
131 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
132 mojo.setTrustStorePath(getResourcePath("truststore.jks"));
133 mojo.setTrustStorePassword(PASSWORD);
134 mojo.setArtifacts(Collections.singletonList(createTestArtifact()));
135
136
137 assertDoesNotThrow(() -> mojo.execute());
138
139 wireMockServer.verify(postRequestedFor(urlPathMatching("/apis/registry/v3/groups/.*/artifacts")));
140 }
141
142 @Test
143 void testTlsWithPemTrustStore() throws Exception {
144 startHttpsServer();
145
146 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
147 mojo.setTrustStorePath(getResourcePath("ca-cert.pem"));
148 mojo.setArtifacts(Collections.singletonList(createTestArtifact()));
149
150
151 assertDoesNotThrow(() -> mojo.execute());
152
153 wireMockServer.verify(postRequestedFor(urlPathMatching("/apis/registry/v3/groups/.*/artifacts")));
154 }
155
156 @Test
157 void testTlsWithoutTrustStore_Fails() throws Exception {
158 startHttpsServer();
159
160 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
161
162 mojo.setArtifacts(Collections.singletonList(createTestArtifact()));
163
164
165 assertThrows(MojoExecutionException.class, () -> mojo.execute());
166 }
167
168 @Test
169 void testTlsWithTrustAll() throws Exception {
170 startHttpsServer();
171
172 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
173 mojo.setTrustAll(true);
174 mojo.setArtifacts(Collections.singletonList(createTestArtifact()));
175
176
177 assertDoesNotThrow(() -> mojo.execute());
178
179 wireMockServer.verify(postRequestedFor(urlPathMatching("/apis/registry/v3/groups/.*/artifacts")));
180 }
181
182
183
184
185
186 @Test
187 void testTlsWithBasicAuth() throws Exception {
188 startHttpsServer();
189
190
191 wireMockServer.stubFor(post(urlPathMatching("/apis/registry/v3/groups/.*/artifacts"))
192 .withBasicAuth("testuser", "testpass")
193 .willReturn(aResponse()
194 .withStatus(200)
195 .withHeader("Content-Type", "application/json")
196 .withBody("""
197 {
198 "version": {
199 "version": "1",
200 "globalId": 12345,
201 "contentId": 67890
202 },
203 "artifact": {
204 "groupId": "test-group",
205 "artifactId": "TestRecord"
206 }
207 }
208 """)));
209
210 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
211 mojo.setTrustStorePath(getResourcePath("truststore.p12"));
212 mojo.setTrustStorePassword(PASSWORD);
213 mojo.setUsername("testuser");
214 mojo.setPassword("testpass");
215 mojo.setArtifacts(Collections.singletonList(createTestArtifact()));
216
217
218 assertDoesNotThrow(() -> mojo.execute());
219
220 wireMockServer.verify(postRequestedFor(urlPathMatching("/apis/registry/v3/groups/.*/artifacts"))
221 .withBasicAuth(new com.github.tomakehurst.wiremock.client.BasicCredentials("testuser", "testpass")));
222 }
223
224
225
226
227
228 @Test
229 void testExplicitTrustStoreType() throws Exception {
230 startHttpsServer();
231
232
233 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
234 mojo.setTrustStorePath(getResourcePath("truststore.p12"));
235 mojo.setTrustStorePassword(PASSWORD);
236 mojo.setTrustStoreType("PKCS12");
237 mojo.setArtifacts(Collections.singletonList(createTestArtifact()));
238
239 assertDoesNotThrow(() -> mojo.execute());
240
241 wireMockServer.verify(postRequestedFor(urlPathMatching("/apis/registry/v3/groups/.*/artifacts")));
242 }
243 }