Skip to content

Commit 06cccdd

Browse files
committed
tests
1 parent 6dedcb8 commit 06cccdd

File tree

3 files changed

+406
-2
lines changed

3 files changed

+406
-2
lines changed

.basic-auth-env

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ quarkus.oidc.tenant-enabled=false
33

44
# Enable Basic Auth
55
quarkus.http.auth.basic=true
6-
apicurio.authn.basic-client-credentials.enabled=true
76

87
# Enable Role Based Auth
98
apicurio.auth.role-based-authorization=true
109

1110
# Enable Testing Embedded Users
12-
quarkus.security.users.embedded.enabled=true
11+
# TODO: check but should be redundant
12+
# quarkus.security.users.embedded.enabled=true
1313
quarkus.security.users.embedded.plain-text=true
1414

1515
# Users configuration
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
package io.apicurio.registry.auth;
2+
3+
import io.apicurio.registry.AbstractResourceTestBase;
4+
import io.apicurio.registry.rest.client.RegistryClient;
5+
import io.apicurio.registry.rest.client.models.*;
6+
import io.apicurio.registry.rules.compatibility.CompatibilityLevel;
7+
import io.apicurio.registry.rules.validity.ValidityLevel;
8+
import io.apicurio.registry.types.ArtifactType;
9+
import io.apicurio.registry.utils.tests.*;
10+
import io.kiota.http.vertx.VertXRequestAdapter;
11+
import io.quarkus.test.junit.QuarkusTest;
12+
import io.quarkus.test.junit.TestProfile;
13+
import org.junit.jupiter.api.Assertions;
14+
import org.junit.jupiter.api.Tag;
15+
import org.junit.jupiter.api.Test;
16+
17+
import java.util.Base64;
18+
import java.util.UUID;
19+
20+
import static io.apicurio.registry.client.auth.VertXAuthFactory.buildSimpleAuthWebClient;
21+
import static org.junit.jupiter.api.Assertions.*;
22+
23+
@QuarkusTest
24+
@TestProfile(BasicAuthWithPropertiesTestProfile.class)
25+
@Tag(ApicurioTestTags.SLOW)
26+
public class BasicAuthWithPropertiesTest extends AbstractResourceTestBase {
27+
28+
private static final String ARTIFACT_CONTENT = "{\"name\":\"redhat\"}";
29+
30+
final String groupId = "authTestGroupId";
31+
32+
public static final String ADMIN_USERNAME = "alice";
33+
public static final String ADMIN_PASSWORD = "alice";
34+
public static final String DEVELOPER_USERNAME = "bob1";
35+
public static final String DEVELOPER_PASSWORD = "bob1";
36+
public static final String DEVELOPER_2_USERNAME = "bob2";
37+
public static final String DEVELOPER_2_PASSWORD = "bob2";
38+
public static final String READONLY_USERNAME = "duncan";
39+
public static final String READONLY_PASSWORD = "duncan";
40+
41+
42+
@Override
43+
protected RegistryClient createRestClientV3() {
44+
var adapter =new VertXRequestAdapter(buildSimpleAuthWebClient(ADMIN_USERNAME, ADMIN_PASSWORD));
45+
adapter.setBaseUrl(registryV3ApiUrl);
46+
return new RegistryClient(adapter);
47+
}
48+
49+
private static final ArtifactContent content = new ArtifactContent();
50+
static {
51+
content.setContent("{}");
52+
}
53+
54+
protected void assertArtifactNotFound(Exception exception) {
55+
Assertions.assertEquals(io.apicurio.registry.rest.client.models.Error.class, exception.getClass());
56+
Assertions.assertEquals("ArtifactNotFoundException", ((io.apicurio.registry.rest.client.models.Error)exception).getName());
57+
Assertions.assertEquals(404, ((io.apicurio.registry.rest.client.models.Error)exception).getErrorCode());
58+
}
59+
60+
@Test
61+
public void testWrongCreds() throws Exception {
62+
var adapter = new VertXRequestAdapter(buildSimpleAuthWebClient(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
63+
adapter.setBaseUrl(registryV3ApiUrl);
64+
RegistryClient client = new RegistryClient(adapter);
65+
var exception = Assertions.assertThrows(Exception.class, () -> {
66+
client.groups().byGroupId(groupId).artifacts().get();
67+
});
68+
assertTrue(exception.getMessage().contains("Unauthorized"));
69+
}
70+
71+
@Test
72+
public void testReadOnly() throws Exception {
73+
var adapter = new VertXRequestAdapter(buildSimpleAuthWebClient(READONLY_USERNAME, READONLY_PASSWORD));
74+
adapter.setBaseUrl(registryV3ApiUrl);
75+
RegistryClient client = new RegistryClient(adapter);
76+
String artifactId = TestUtils.generateArtifactId();
77+
client.groups().byGroupId(groupId).artifacts().get();
78+
var exception1 = Assertions.assertThrows(Exception.class, () -> {
79+
client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get();
80+
});
81+
assertArtifactNotFound(exception1);
82+
var exception2 = Assertions.assertThrows(Exception.class, () -> {
83+
client.groups().byGroupId("abc").artifacts().byArtifactId(artifactId).get();
84+
});
85+
assertArtifactNotFound(exception2);
86+
var exception3 = Assertions.assertThrows(Exception.class, () -> {
87+
client.groups().byGroupId("testReadOnly").artifacts().post(content, config -> {
88+
config.headers.add("X-Registry-ArtifactId", artifactId);
89+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
90+
});
91+
});
92+
assertForbidden(exception3);
93+
94+
var devAdapter = new VertXRequestAdapter(buildSimpleAuthWebClient(DEVELOPER_USERNAME, DEVELOPER_PASSWORD));
95+
devAdapter.setBaseUrl(registryV3ApiUrl);
96+
RegistryClient devClient = new RegistryClient(devAdapter);
97+
98+
VersionMetaData meta = devClient.groups().byGroupId(groupId).artifacts().post(content, config -> {
99+
config.headers.add("X-Registry-ArtifactId", artifactId);
100+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
101+
});
102+
103+
TestUtils.retry(() -> devClient.groups().byGroupId(groupId).artifacts().byArtifactId(meta.getArtifactId()).get());
104+
105+
assertNotNull(client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get());
106+
107+
UserInfo userInfo = client.users().me().get();
108+
assertNotNull(userInfo);
109+
Assertions.assertEquals("readonly-client", userInfo.getUsername());
110+
Assertions.assertFalse(userInfo.getAdmin());
111+
Assertions.assertFalse(userInfo.getDeveloper());
112+
Assertions.assertTrue(userInfo.getViewer());
113+
}
114+
115+
@Test
116+
public void testDevRole() throws Exception {
117+
var adapter = new VertXRequestAdapter(buildSimpleAuthWebClient(DEVELOPER_USERNAME, DEVELOPER_PASSWORD));
118+
adapter.setBaseUrl(registryV3ApiUrl);
119+
RegistryClient client = new RegistryClient(adapter);
120+
String artifactId = TestUtils.generateArtifactId();
121+
try {
122+
client.groups().byGroupId(groupId).artifacts().get();
123+
124+
client.groups().byGroupId(groupId).artifacts().post(content, config -> {
125+
config.headers.add("X-Registry-ArtifactId", artifactId);
126+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
127+
});
128+
TestUtils.retry(() -> client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get());
129+
130+
assertTrue(client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).versions().byVersionExpression("branch=latest").content().get().readAllBytes().length > 0);
131+
132+
Rule ruleConfig = new Rule();
133+
ruleConfig.setType(RuleType.VALIDITY);
134+
ruleConfig.setConfig(ValidityLevel.NONE.name());
135+
client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).rules().post(ruleConfig);
136+
137+
var exception = Assertions.assertThrows(Exception.class, () -> {
138+
client.admin().rules().post(ruleConfig);
139+
});
140+
assertForbidden(exception);
141+
142+
UserInfo userInfo = client.users().me().get();
143+
assertNotNull(userInfo);
144+
Assertions.assertEquals("developer-client", userInfo.getUsername());
145+
Assertions.assertFalse(userInfo.getAdmin());
146+
Assertions.assertTrue(userInfo.getDeveloper());
147+
Assertions.assertFalse(userInfo.getViewer());
148+
} finally {
149+
client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).delete();
150+
}
151+
}
152+
153+
@Test
154+
public void testAdminRole() throws Exception {
155+
var adapter = new VertXRequestAdapter(buildSimpleAuthWebClient(ADMIN_USERNAME, ADMIN_PASSWORD));
156+
adapter.setBaseUrl(registryV3ApiUrl);
157+
RegistryClient client = new RegistryClient(adapter);
158+
String artifactId = TestUtils.generateArtifactId();
159+
try {
160+
client.groups().byGroupId(groupId).artifacts().get();
161+
162+
client.groups().byGroupId(groupId).artifacts().post(content, config -> {
163+
config.headers.add("X-Registry-ArtifactId", artifactId);
164+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
165+
});
166+
TestUtils.retry(() -> client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get());
167+
168+
assertTrue(client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).versions().byVersionExpression("branch=latest").content().get().readAllBytes().length > 0);
169+
170+
Rule ruleConfig = new Rule();
171+
ruleConfig.setType(RuleType.VALIDITY);
172+
ruleConfig.setConfig(ValidityLevel.NONE.name());
173+
client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).rules().post(ruleConfig);
174+
175+
client.admin().rules().post(ruleConfig);
176+
177+
UserInfo userInfo = client.users().me().get();
178+
assertNotNull(userInfo);
179+
Assertions.assertEquals("admin-client", userInfo.getUsername());
180+
Assertions.assertTrue(userInfo.getAdmin());
181+
Assertions.assertFalse(userInfo.getDeveloper());
182+
Assertions.assertFalse(userInfo.getViewer());
183+
} finally {
184+
client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).delete();
185+
}
186+
}
187+
188+
@Test
189+
public void testOwnerOnlyAuthorization() throws Exception {
190+
var devAdapter = new VertXRequestAdapter(buildSimpleAuthWebClient(DEVELOPER_USERNAME, DEVELOPER_PASSWORD));
191+
devAdapter.setBaseUrl(registryV3ApiUrl);
192+
RegistryClient clientDev = new RegistryClient(devAdapter);
193+
194+
var adminAdapter = new VertXRequestAdapter(buildSimpleAuthWebClient(ADMIN_USERNAME, ADMIN_PASSWORD));
195+
adminAdapter.setBaseUrl(registryV3ApiUrl);
196+
RegistryClient clientAdmin = new RegistryClient(adminAdapter);
197+
198+
// Admin user will create an artifact
199+
String artifactId = TestUtils.generateArtifactId();
200+
clientAdmin.groups().byGroupId(groupId).artifacts().post(content, config -> {
201+
config.headers.add("X-Registry-ArtifactId", artifactId);
202+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
203+
});
204+
205+
EditableArtifactMetaData updatedMetaData = new EditableArtifactMetaData();
206+
updatedMetaData.setName("Updated Name");
207+
// Dev user cannot edit the same artifact because Dev user is not the owner
208+
var exception1 = Assertions.assertThrows(Exception.class, () -> {
209+
clientDev.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).put(updatedMetaData);
210+
});
211+
assertForbidden(exception1);
212+
213+
// But the admin user CAN make the change.
214+
clientAdmin.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).put(updatedMetaData);
215+
216+
217+
// Now the Dev user will create an artifact
218+
String artifactId2 = TestUtils.generateArtifactId();
219+
clientDev.groups().byGroupId(groupId).artifacts().post(content, config -> {
220+
config.headers.add("X-Registry-ArtifactId", artifactId2);
221+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
222+
});
223+
224+
// And the Admin user will modify it (allowed because it's the Admin user)
225+
Rule rule = new Rule();
226+
rule.setType(RuleType.COMPATIBILITY);
227+
rule.setConfig(CompatibilityLevel.BACKWARD.name());
228+
clientAdmin.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId2).rules().post(rule);
229+
}
230+
231+
@Test
232+
public void testGetArtifactOwner() throws Exception {
233+
var adapter = new VertXRequestAdapter(buildSimpleAuthWebClient(DEVELOPER_USERNAME, DEVELOPER_PASSWORD));
234+
adapter.setBaseUrl(registryV3ApiUrl);
235+
RegistryClient client = new RegistryClient(adapter);
236+
237+
//Preparation
238+
final String groupId = "testGetArtifactOwner";
239+
final String artifactId = generateArtifactId();
240+
final String version = "1";
241+
242+
//Execution
243+
var artifactContent = new ArtifactContent();
244+
artifactContent.setContent(ARTIFACT_CONTENT);
245+
final VersionMetaData created = client.groups().byGroupId(groupId).artifacts().post(content, config -> {
246+
config.queryParameters.ifExists = IfExists.FAIL;
247+
config.headers.add("X-Registry-ArtifactId", artifactId);
248+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
249+
});
250+
251+
//Assertions
252+
assertNotNull(created);
253+
assertEquals(groupId, created.getGroupId());
254+
assertEquals(artifactId, created.getArtifactId());
255+
assertEquals(version, created.getVersion());
256+
assertEquals("developer-client", created.getOwner());
257+
258+
//Get the artifact owner via the REST API and verify it
259+
ArtifactMetaData amd = client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get();
260+
assertEquals("developer-client", amd.getOwner());
261+
}
262+
263+
@Test
264+
public void testUpdateArtifactOwner() throws Exception {
265+
var adapter = new VertXRequestAdapter(buildSimpleAuthWebClient(DEVELOPER_USERNAME, DEVELOPER_PASSWORD));
266+
adapter.setBaseUrl(registryV3ApiUrl);
267+
RegistryClient client = new RegistryClient(adapter);
268+
269+
//Preparation
270+
final String groupId = "testUpdateArtifactOwner";
271+
final String artifactId = generateArtifactId();
272+
273+
final String version = "1.0";
274+
final String name = "testUpdateArtifactOwnerName";
275+
final String description = "testUpdateArtifactOwnerDescription";
276+
277+
//Execution
278+
var artifactContent = new ArtifactContent();
279+
artifactContent.setContent(ARTIFACT_CONTENT);
280+
final VersionMetaData created = client.groups().byGroupId(groupId).artifacts().post(content, config -> {
281+
config.queryParameters.ifExists = IfExists.FAIL;
282+
config.headers.add("X-Registry-ArtifactId", artifactId);
283+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
284+
config.headers.add("X-Registry-Version", version);
285+
config.headers.add("X-Registry-Name-Encoded", Base64.getEncoder().encodeToString(name.getBytes()));
286+
config.headers.add("X-Registry-Description-Encoded", Base64.getEncoder().encodeToString(description.getBytes()));
287+
});
288+
289+
//Assertions
290+
assertNotNull(created);
291+
assertEquals(groupId, created.getGroupId());
292+
assertEquals(artifactId, created.getArtifactId());
293+
assertEquals(version, created.getVersion());
294+
assertEquals("developer-client", created.getOwner());
295+
296+
//Get the artifact owner via the REST API and verify it
297+
ArtifactMetaData amd = client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get();
298+
assertEquals("developer-client", amd.getOwner());
299+
300+
//Update the owner
301+
EditableArtifactMetaData eamd = new EditableArtifactMetaData();
302+
eamd.setOwner("developer-2-client");
303+
client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).put(eamd);
304+
305+
//Check that the update worked
306+
amd = client.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get();
307+
assertEquals("developer-2-client", amd.getOwner());
308+
}
309+
310+
@Test
311+
public void testUpdateArtifactOwnerOnlyByOwner() throws Exception {
312+
var adapter_dev1 = new VertXRequestAdapter(buildSimpleAuthWebClient(DEVELOPER_USERNAME, DEVELOPER_PASSWORD));
313+
adapter_dev1.setBaseUrl(registryV3ApiUrl);
314+
RegistryClient client_dev1 = new RegistryClient(adapter_dev1);
315+
var adapter_dev2 = new VertXRequestAdapter(buildSimpleAuthWebClient(DEVELOPER_2_USERNAME, DEVELOPER_2_PASSWORD));
316+
adapter_dev2.setBaseUrl(registryV3ApiUrl);
317+
RegistryClient client_dev2 = new RegistryClient(adapter_dev2);
318+
319+
//Preparation
320+
final String groupId = "testUpdateArtifactOwnerOnlyByOwner";
321+
final String artifactId = generateArtifactId();
322+
323+
final String version = "1.0";
324+
final String name = "testUpdateArtifactOwnerOnlyByOwnerName";
325+
final String description = "testUpdateArtifactOwnerOnlyByOwnerDescription";
326+
327+
//Execution
328+
var artifactContent = new ArtifactContent();
329+
artifactContent.setContent(ARTIFACT_CONTENT);
330+
final VersionMetaData created = client_dev1.groups().byGroupId(groupId).artifacts().post(content, config -> {
331+
config.queryParameters.ifExists = IfExists.FAIL;
332+
config.headers.add("X-Registry-ArtifactId", artifactId);
333+
config.headers.add("X-Registry-ArtifactType", ArtifactType.JSON);
334+
config.headers.add("X-Registry-Version", version);
335+
config.headers.add("X-Registry-Name-Encoded", Base64.getEncoder().encodeToString(name.getBytes()));
336+
config.headers.add("X-Registry-Description-Encoded", Base64.getEncoder().encodeToString(description.getBytes()));
337+
});
338+
339+
//Assertions
340+
assertNotNull(created);
341+
assertEquals(groupId, created.getGroupId());
342+
assertEquals(artifactId, created.getArtifactId());
343+
assertEquals(version, created.getVersion());
344+
assertEquals("developer-client", created.getOwner());
345+
346+
//Get the artifact owner via the REST API and verify it
347+
ArtifactMetaData amd = client_dev1.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get();
348+
assertEquals("developer-client", amd.getOwner());
349+
350+
//Try to update the owner by dev2 (should fail)
351+
var exception1 = assertThrows(Exception.class, () -> {
352+
EditableArtifactMetaData eamd = new EditableArtifactMetaData();
353+
eamd.setOwner("developer-2-client");
354+
client_dev2.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).put(eamd);
355+
});
356+
assertForbidden(exception1);
357+
358+
//Should still be the original owner
359+
amd = client_dev1.groups().byGroupId(groupId).artifacts().byArtifactId(artifactId).get();
360+
assertEquals("developer-client", amd.getOwner());
361+
}
362+
363+
}
364+

0 commit comments

Comments
 (0)