diff --git a/pom.xml b/pom.xml
index a6e03eb5..6d003d43 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.uid2
uid2-admin
- 6.13.0
+ 6.13.1-alpha-227-SNAPSHOT
UTF-8
diff --git a/src/main/java/com/uid2/admin/managers/KeysetManager.java b/src/main/java/com/uid2/admin/managers/KeysetManager.java
index 17b03576..89011064 100644
--- a/src/main/java/com/uid2/admin/managers/KeysetManager.java
+++ b/src/main/java/com/uid2/admin/managers/KeysetManager.java
@@ -53,7 +53,7 @@ public static Integer getMaxKeyset(Map keysets) {
return max(Collections.max(keysets.keySet()), 3);
}
- public static AdminKeyset createDefaultKeyset(int siteId, int keysetId) {
+ public static AdminKeyset createKeysetSharedWithDsps(int siteId, int keysetId) {
String name = "";
//only set if both siteId and keysetId match our expectation according to the requirements
@@ -67,8 +67,8 @@ else if(siteId == Const.Data.RefreshKeySiteId && keysetId == Const.Data.RefreshK
else if(siteId == Const.Data.AdvertisingTokenSiteId && keysetId == Const.Data.FallbackPublisherKeysetId) {
name = FallbackPublisherKeysetName;
}
- return new AdminKeyset(keysetId, siteId, name, null, Instant.now().getEpochSecond(),
- true, true, new HashSet<>());
+ return new AdminKeyset(keysetId, siteId, name, new HashSet<>(), Instant.now().getEpochSecond(),
+ true, true, new HashSet<>(Set.of(ClientType.DSP)));
}
public static Keyset adminKeysetToKeyset(AdminKeyset adminKeyset, Map> siteIdsByType) {
@@ -138,7 +138,7 @@ private AdminKeyset createAndAddDefaultKeyset(Integer siteId) throws Exception{
this.keysetProvider.loadContent();
int newKeysetId = getNextKeysetId();
- AdminKeyset newKeyset = KeysetManager.createDefaultKeyset(siteId, newKeysetId);
+ AdminKeyset newKeyset = KeysetManager.createKeysetSharedWithDsps(siteId, newKeysetId);
addOrReplaceKeyset(newKeyset);
return newKeyset;
}
diff --git a/src/main/java/com/uid2/admin/vertx/service/EncryptionKeyService.java b/src/main/java/com/uid2/admin/vertx/service/EncryptionKeyService.java
index a07551b7..530b9929 100644
--- a/src/main/java/com/uid2/admin/vertx/service/EncryptionKeyService.java
+++ b/src/main/java/com/uid2/admin/vertx/service/EncryptionKeyService.java
@@ -548,7 +548,7 @@ else if(siteId == Const.Data.RefreshKeySiteId) {
else if(siteId == Const.Data.AdvertisingTokenSiteId) {
newKeysetId = Const.Data.FallbackPublisherKeysetId;
}
- keyset = createDefaultKeyset(siteId, newKeysetId);
+ keyset = createKeysetSharedWithDsps(siteId, newKeysetId);
currentKeysets.put(newKeysetId, keyset);
keysetStoreWriter.upload(currentKeysets, null);
}
diff --git a/src/main/java/com/uid2/admin/vertx/service/SharingService.java b/src/main/java/com/uid2/admin/vertx/service/SharingService.java
index e202c459..37f6ecc0 100644
--- a/src/main/java/com/uid2/admin/vertx/service/SharingService.java
+++ b/src/main/java/com/uid2/admin/vertx/service/SharingService.java
@@ -380,7 +380,7 @@ private void handleSetAllowedSites(RoutingContext rc) {
AdminKeyset newKeyset = setAdminKeyset(rc, allowedSites, allowedTypes, siteId, keysetId, name);
if(newKeyset == null) return;
JsonObject jo = new JsonObject();
- jo.put("allowed_sites", allowedSites);
+ jo.put("allowed_sites", newKeyset.getAllowedSites());
jo.put("allowed_types", newKeyset.getAllowedTypes());
jo.put("hash", newKeyset.hashCode());
@@ -430,7 +430,7 @@ private AdminKeyset setAdminKeyset(RoutingContext rc, JsonArray allowedSites, Js
.boxed()
.collect(Collectors.toSet());
} else {
- newlist = null;
+ newlist = new HashSet<>();
}
Set newAllowedTypes = null;
diff --git a/src/test/java/com/uid2/admin/managers/KeysetManagerTest.java b/src/test/java/com/uid2/admin/managers/KeysetManagerTest.java
index 5b52a982..8d33b2a0 100644
--- a/src/test/java/com/uid2/admin/managers/KeysetManagerTest.java
+++ b/src/test/java/com/uid2/admin/managers/KeysetManagerTest.java
@@ -58,16 +58,16 @@ public void testAddOrReplaceKeyset() throws Exception{
keysetKeyManager, true);
Map keysets = new HashMap() {{
- put(1, KeysetManager.createDefaultKeyset(3, 1));
- put(2, KeysetManager.createDefaultKeyset(4, 2));
- put(3, KeysetManager.createDefaultKeyset(5, 3));
- put(4, KeysetManager.createDefaultKeyset(6, 4));
+ put(1, KeysetManager.createKeysetSharedWithDsps(3, 1));
+ put(2, KeysetManager.createKeysetSharedWithDsps(4, 2));
+ put(3, KeysetManager.createKeysetSharedWithDsps(5, 3));
+ put(4, KeysetManager.createKeysetSharedWithDsps(6, 4));
}};
setKeysets(keysets);
final int keysetId = 5;
// add new keyset
- AdminKeyset keyset1 = KeysetManager.createDefaultKeyset(7, keysetId);
+ AdminKeyset keyset1 = KeysetManager.createKeysetSharedWithDsps(7, keysetId);
keysetManager.addOrReplaceKeyset(keyset1);
assertTrue(keysets.containsKey(5));
assertTrue(keyset1.equals(keysets.get(5)));
@@ -102,7 +102,7 @@ public void createsKeysetWhenNoneExists() throws Exception {
@Test
public void doesNotCreateKeysetWhenOneExists() throws Exception {
- final AdminKeyset keyset = KeysetManager.createDefaultKeyset(1, 1);
+ final AdminKeyset keyset = KeysetManager.createKeysetSharedWithDsps(1, 1);
final HashMap keysets = new HashMap<>();
keysets.put(1, keyset);
@@ -135,10 +135,10 @@ public void testCreateKeysetForClient() throws Exception {
keysetKeyManager, true);
Map keysets = new HashMap() {{
- put(1, KeysetManager.createDefaultKeyset(3, 1));
- put(2, KeysetManager.createDefaultKeyset(4, 2));
- put(3, KeysetManager.createDefaultKeyset(5, 3));
- put(4, KeysetManager.createDefaultKeyset(6, 4));
+ put(1, KeysetManager.createKeysetSharedWithDsps(3, 1));
+ put(2, KeysetManager.createKeysetSharedWithDsps(4, 2));
+ put(3, KeysetManager.createKeysetSharedWithDsps(5, 3));
+ put(4, KeysetManager.createKeysetSharedWithDsps(6, 4));
}};
setKeysets(keysets);
@@ -149,12 +149,13 @@ public void testCreateKeysetForClient() throws Exception {
assertTrue(sharerKeyset.equals(returnedKeyset));
assertEquals(sharerKeyset.getAllowedSites(), Set.of());
- // Generator makes a null list
+ // Generator makes an empty allowed_sites list with default allowed_types [DSP]
ClientKey generator = new ClientKey("", "", "", "", "", Instant.now(), Set.of(Role.GENERATOR), 8, false, "key-id-8");
returnedKeyset = keysetManager.createKeysetForClient(generator);
AdminKeyset generatorKeyset = keysets.get(returnedKeyset.getKeysetId());
assertTrue(generatorKeyset.equals(returnedKeyset));
- assertNull(generatorKeyset.getAllowedSites());
+ assertEquals(Set.of(), generatorKeyset.getAllowedSites());
+ assertEquals(Set.of(ClientType.DSP), generatorKeyset.getAllowedTypes());
// Generator takes priority of sharer
ClientKey sharerGenerator = new ClientKey("", "", "", "", "", Instant.now(), Set.of(Role.SHARER, Role.GENERATOR), 9, false, "key-id-9");
@@ -162,7 +163,8 @@ public void testCreateKeysetForClient() throws Exception {
returnedKeyset = keysetManager.createKeysetForClient(sharerGenerator);
AdminKeyset bothKeyset = keysets.get(returnedKeyset.getKeysetId());
assertTrue(bothKeyset.equals(returnedKeyset));
- assertNull(bothKeyset.getAllowedSites());
+ assertEquals(Set.of(), bothKeyset.getAllowedSites());
+ assertEquals(Set.of(ClientType.DSP), bothKeyset.getAllowedTypes());
// If keyset already exists none gets added
returnedKeyset = keysetManager.createKeysetForClient(sharer);
@@ -172,6 +174,30 @@ public void testCreateKeysetForClient() throws Exception {
assertEquals(7, keysets.keySet().size());
}
+ @Test
+ public void createKeysetForSite_newKeyset_hasNonNullEmptyAllowedSitesAndDspType() throws Exception {
+ setKeysets(new HashMap<>());
+ KeysetManager keysetManager = new KeysetManager(keysetProvider, keysetStoreWriter, keysetKeyManager, true);
+
+ AdminKeyset created = keysetManager.createKeysetForSite(99);
+
+ assertNotNull(created.getAllowedSites());
+ assertTrue(created.getAllowedSites().isEmpty());
+ assertTrue(created.getAllowedTypes().contains(ClientType.DSP));
+ }
+
+ @Test
+ public void createAndAddKeyset_emptyAllowedSites_nullAllowedTypes_hasEmptySitesAndNullAllowedTypes()
+ throws Exception {
+ setKeysets(new HashMap<>());
+ KeysetManager keysetManager = new KeysetManager(keysetProvider, keysetStoreWriter, keysetKeyManager, true);
+
+ AdminKeyset created = keysetManager.createAndAddKeyset(42, new HashSet<>(), null);
+
+ assertNotNull(created.getAllowedSites());
+ assertTrue(created.getAllowedSites().isEmpty());
+ assertNull(created.getAllowedTypes());
+ }
@Test
public void testLookUpKeyset() {
@@ -228,33 +254,33 @@ public void testGetMaxKeyset() {
public void testKeysetNameCreation() {
//expected cases of special keysets when site id and keyset id match our expectations
- AdminKeyset keyset = createDefaultKeyset(-1, -1);
+ AdminKeyset keyset = createKeysetSharedWithDsps(-1, -1);
assertEquals(keyset.getName(), KeysetManager.MasterKeysetName);
- keyset = createDefaultKeyset(-2, -2);
+ keyset = createKeysetSharedWithDsps(-2, -2);
assertEquals(keyset.getName(), KeysetManager.RefreshKeysetName);
- keyset = createDefaultKeyset(2, 2);
+ keyset = createKeysetSharedWithDsps(2, 2);
assertEquals(keyset.getName(), KeysetManager.FallbackPublisherKeysetName);
//only site id matches but keyset id aren't the same as what we expected
- keyset = createDefaultKeyset(-1, 3);
+ keyset = createKeysetSharedWithDsps(-1, 3);
assertEquals(keyset.getName(), "");
- keyset = createDefaultKeyset(-2, 34);
+ keyset = createKeysetSharedWithDsps(-2, 34);
assertEquals(keyset.getName(), "");
- keyset = createDefaultKeyset(2, 56);
+ keyset = createKeysetSharedWithDsps(2, 56);
assertEquals(keyset.getName(), "");
//only keyset id matches but site Id aren't the same as what we expected
- keyset = createDefaultKeyset(-5, 1);
+ keyset = createKeysetSharedWithDsps(-5, 1);
assertEquals(keyset.getName(), "");
- keyset = createDefaultKeyset(-3, 2);
+ keyset = createKeysetSharedWithDsps(-3, 2);
assertEquals(keyset.getName(), "");
- keyset = createDefaultKeyset(20, 3);
+ keyset = createKeysetSharedWithDsps(20, 3);
assertEquals(keyset.getName(), "");
//for any other normal keyset creation
- keyset = createDefaultKeyset(6, 7);
+ keyset = createKeysetSharedWithDsps(6, 7);
assertEquals(keyset.getName(), "");
- keyset = createDefaultKeyset(9, 23);
+ keyset = createKeysetSharedWithDsps(9, 23);
assertEquals(keyset.getName(), "");
}
diff --git a/src/test/java/com/uid2/admin/vertx/ClientKeyServiceTest.java b/src/test/java/com/uid2/admin/vertx/ClientKeyServiceTest.java
index 6f321641..9ea3798a 100644
--- a/src/test/java/com/uid2/admin/vertx/ClientKeyServiceTest.java
+++ b/src/test/java/com/uid2/admin/vertx/ClientKeyServiceTest.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.uid2.admin.auth.AdminKeyset;
import com.uid2.admin.auth.RevealedKey;
import com.uid2.admin.legacy.LegacyClientKey;
import com.uid2.admin.managers.KeysetManager;
@@ -10,6 +11,7 @@
import com.uid2.admin.vertx.test.ServiceTestBase;
import com.uid2.shared.auth.ClientKey;
import com.uid2.shared.auth.Role;
+import com.uid2.shared.model.ClientType;
import com.uid2.shared.model.Site;
import com.uid2.shared.util.Mapper;
import io.vertx.core.Vertx;
@@ -21,6 +23,10 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
@@ -97,6 +103,94 @@ public void clientAdd(Vertx vertx, VertxTestContext testContext) {
});
}
+ @Test
+ public void clientAddWithSharer_createsKeysetWithEmptyAllowedSitesAndTypes(Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.MAINTAINER);
+
+ Map keysetsById = new HashMap<>();
+ setAdminKeysets(keysetsById);
+
+ post(vertx, testContext, "api/client/add?name=test_sharer&roles=sharer&site_id=999", "", response -> {
+ assertEquals(200, response.statusCode());
+
+ Optional keysetForSite =
+ keysetsById.values().stream().filter(k -> k.getSiteId() == 999).findFirst();
+ assertTrue(keysetForSite.isPresent());
+ AdminKeyset keyset = keysetForSite.get();
+ assertTrue(keyset.getAllowedSites().isEmpty());
+ assertTrue(keyset.getAllowedTypes().isEmpty());
+
+ verify(keysetKeyManager).addKeysetKey(keyset.getKeysetId());
+ verify(clientKeyStoreWriter).upload(collectionOfSize(1), isNull());
+ testContext.completeNow();
+ });
+ }
+
+ @Test
+ public void clientAddWithGenerator_createsKeysetWithEmptyAllowedSitesAndDspAllowedType(Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.MAINTAINER);
+
+ Map keysetsById = new HashMap<>();
+ setAdminKeysets(keysetsById);
+
+ post(vertx, testContext, "api/client/add?name=test_generator&roles=generator&site_id=999", "", response -> {
+ assertEquals(200, response.statusCode());
+
+ Optional keysetForSite =
+ keysetsById.values().stream().filter(k -> k.getSiteId() == 999).findFirst();
+ assertTrue(keysetForSite.isPresent());
+ AdminKeyset keyset = keysetForSite.get();
+ assertTrue(keyset.getAllowedSites().isEmpty());
+ assertEquals(Set.of(ClientType.DSP), keyset.getAllowedTypes());
+
+ verify(keysetKeyManager).addKeysetKey(keyset.getKeysetId());
+ verify(clientKeyStoreWriter).upload(collectionOfSize(1), isNull());
+ testContext.completeNow();
+ });
+ }
+
+ @Test
+ public void clientAddWithMapper_onAdvertiserTypedSite_doesNotCreateKeyset(Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.MAINTAINER);
+ setSites(new Site(999, "test_site", true, Set.of(ClientType.ADVERTISER), Collections.emptySet()));
+
+ Map keysetsById = new HashMap<>();
+ setAdminKeysets(keysetsById);
+
+ post(vertx, testContext, "api/client/add?name=test_mapper_adv&roles=mapper&site_id=999", "", response -> {
+ assertEquals(200, response.statusCode());
+
+ assertTrue(
+ keysetsById.values().stream().noneMatch(k -> k.getSiteId() == 999),
+ "KeysetManager.createKeysetForClient returns null for MAPPER-only keys");
+
+ verifyNoInteractions(keysetKeyManager);
+ verify(clientKeyStoreWriter).upload(collectionOfSize(1), isNull());
+ testContext.completeNow();
+ });
+ }
+
+ @Test
+ public void clientAddWithMapper_onDataProviderTypedSite_doesNotCreateKeyset(Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.MAINTAINER);
+ setSites(new Site(999, "test_site", true, Set.of(ClientType.DATA_PROVIDER), Collections.emptySet()));
+
+ Map keysetsById = new HashMap<>();
+ setAdminKeysets(keysetsById);
+
+ post(vertx, testContext, "api/client/add?name=test_mapper_dp&roles=mapper&site_id=999", "", response -> {
+ assertEquals(200, response.statusCode());
+
+ assertTrue(
+ keysetsById.values().stream().noneMatch(k -> k.getSiteId() == 999),
+ "KeysetManager.createKeysetForClient returns null for MAPPER-only keys");
+
+ verifyNoInteractions(keysetKeyManager);
+ verify(clientKeyStoreWriter).upload(collectionOfSize(1), isNull());
+ testContext.completeNow();
+ });
+ }
+
@ParameterizedTest
@MethodSource("createSiteKeyIfNoneExistsTestData")
public void clientAddCreatesSiteKeyIfNoneExists(Set roles, boolean siteKeyShouldBeCreatedIfNoneExists, Vertx vertx, VertxTestContext testContext) {
diff --git a/src/test/java/com/uid2/admin/vertx/ClientSideKeypairServiceTest.java b/src/test/java/com/uid2/admin/vertx/ClientSideKeypairServiceTest.java
index 88c0cfe7..771146e6 100644
--- a/src/test/java/com/uid2/admin/vertx/ClientSideKeypairServiceTest.java
+++ b/src/test/java/com/uid2/admin/vertx/ClientSideKeypairServiceTest.java
@@ -1,5 +1,6 @@
package com.uid2.admin.vertx;
+import com.uid2.admin.auth.AdminKeyset;
import com.uid2.admin.secret.SecureKeypairGenerator;
import com.uid2.admin.store.Clock;
import com.uid2.admin.vertx.service.ClientSideKeypairService;
@@ -7,6 +8,7 @@
import com.uid2.admin.vertx.test.ServiceTestBase;
import com.uid2.shared.auth.Role;
import com.uid2.shared.model.ClientSideKeypair;
+import com.uid2.shared.model.ClientType;
import com.uid2.shared.model.Site;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonArray;
@@ -17,13 +19,12 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
-import org.mockito.ArgumentCaptor;
-
import java.time.Instant;
import java.util.*;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.*;
public class ClientSideKeypairServiceTest extends ServiceTestBase {
@@ -253,18 +254,14 @@ void addKeypair(Vertx vertx, VertxTestContext testContext) throws Exception {
setKeypairs(new ArrayList<>(expectedKeypairs.values()));
setSites(new Site(123, "test", true));
+ Map adminKeysets = new HashMap<>();
+ setAdminKeysets(adminKeysets);
+
JsonObject jo = new JsonObject();
jo.put("site_id", 123);
jo.put("contact", "email@email.com");
post(vertx, testContext, "api/client_side_keypairs/add", jo.encode(), response -> {
- final ArgumentCaptor siteId = ArgumentCaptor.forClass(Integer.class);
- try {
- verify(this.keysetManager).createKeysetForSite(siteId.capture());
- } catch (Exception e) {
- fail(e);
- }
- assertEquals(123, siteId.getValue());
assertEquals(200, response.statusCode());
JsonObject resp = response.bodyAsJsonObject();
assertEquals(123, resp.getInteger("site_id"));
@@ -276,6 +273,46 @@ void addKeypair(Vertx vertx, VertxTestContext testContext) throws Exception {
assertEquals("UID2-X-L-", resp.getString("public_key").substring(0, 9));
assertEquals(KEY_CREATE_TIME_IN_SECONDS, resp.getLong("created"));
assertEquals(false, resp.getBoolean("disabled"));
+ AdminKeyset keyset = adminKeysets.values().stream()
+ .filter(k -> k.getSiteId() == 123)
+ .findFirst()
+ .orElseThrow();
+ assertTrue(keyset.getAllowedSites().isEmpty());
+ assertEquals(Set.of(ClientType.DSP), keyset.getAllowedTypes());
+ assertTrue(keyset.isDefault());
+ verify(keysetKeyManager).addKeysetKey(keyset.getKeysetId());
+ verify(adminKeysetWriter).upload(any(), isNull());
+ verify(keypairStoreWriter, times(1)).upload(any(), isNull());
+ testContext.completeNow();
+ });
+ }
+
+ @Test
+ void addKeypair_createsKeysetForSiteWhenNoneExists(Vertx vertx, VertxTestContext testContext) throws Exception {
+ fakeAuth(Role.MAINTAINER);
+ setSites(new Site(456, "csp_keyset_site", true));
+ setKeypairs(new ArrayList<>());
+
+ Map adminKeysets = new HashMap<>();
+ setAdminKeysets(adminKeysets);
+
+ JsonObject jo = new JsonObject();
+ jo.put("site_id", 456);
+ jo.put("contact", "keyset-check@example.com");
+
+ post(vertx, testContext, "api/client_side_keypairs/add", jo.encode(), response -> {
+ assertEquals(200, response.statusCode());
+
+ AdminKeyset keyset = adminKeysets.values().stream()
+ .filter(k -> k.getSiteId() == 456)
+ .findFirst()
+ .orElseThrow();
+ assertTrue(keyset.getAllowedSites().isEmpty());
+ assertEquals(Set.of(ClientType.DSP), keyset.getAllowedTypes());
+ assertTrue(keyset.isDefault());
+
+ verify(keysetKeyManager).addKeysetKey(keyset.getKeysetId());
+ verify(adminKeysetWriter).upload(any(), isNull());
verify(keypairStoreWriter, times(1)).upload(any(), isNull());
testContext.completeNow();
});
diff --git a/src/test/java/com/uid2/admin/vertx/EncryptionKeyServiceTest.java b/src/test/java/com/uid2/admin/vertx/EncryptionKeyServiceTest.java
index 6a839cdb..f16b6cff 100644
--- a/src/test/java/com/uid2/admin/vertx/EncryptionKeyServiceTest.java
+++ b/src/test/java/com/uid2/admin/vertx/EncryptionKeyServiceTest.java
@@ -7,6 +7,7 @@
import com.uid2.admin.vertx.test.ServiceTestBase;
import com.uid2.shared.Const;
import com.uid2.shared.auth.Role;
+import com.uid2.shared.model.ClientType;
import com.uid2.shared.model.EncryptionKey;
import com.uid2.shared.model.KeysetKey;
import io.vertx.core.Vertx;
@@ -150,7 +151,7 @@ void addSiteKeyAddsKeysetAndKey() throws Exception {
setKeysetKeys(123);
final EncryptionKey key = keyService.addSiteKey(5);
- AdminKeyset expected = new AdminKeyset(4, 5, "", null, Instant.now().getEpochSecond(), true, true, new HashSet<>());
+ AdminKeyset expected = new AdminKeyset(4, 5, "", new HashSet<>(), Instant.now().getEpochSecond(), true, true, Set.of(ClientType.DSP));
assertNotNull(keysets.get(4));
assertEquals(expected, keysets.get(4));
verify(keysetKeyStoreWriter).upload(collectionOfSize(1), eq(124));
diff --git a/src/test/java/com/uid2/admin/vertx/SharingServiceTest.java b/src/test/java/com/uid2/admin/vertx/SharingServiceTest.java
index ee6758d7..963d7162 100644
--- a/src/test/java/com/uid2/admin/vertx/SharingServiceTest.java
+++ b/src/test/java/com/uid2/admin/vertx/SharingServiceTest.java
@@ -17,6 +17,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
@@ -26,8 +27,7 @@
import java.util.stream.Stream;
import static com.uid2.admin.vertx.Endpoints.API_SHARING_KEYSETS_RELATED;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
public class SharingServiceTest extends ServiceTestBase {
@@ -52,7 +52,7 @@ private void compareKeysetTypeListToResult(AdminKeyset keyset, JsonArray actualL
.collect(Collectors.toSet());
assertEquals(keyset.getAllowedTypes(), actualSet);
}
-
+
private void mockSiteExistence(Integer... sites){
for(Integer site : sites) {
doReturn(new Site(site, "test-name", true, null)).when(siteProvider).getSite(site);
@@ -250,6 +250,37 @@ void listSiteSetNew(Vertx vertx, VertxTestContext testContext) {
});
}
+ @Test
+ void listSiteSetNewAllowedSitesMissingInRequest(Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.SHARING_PORTAL);
+
+ Map keysets = new HashMap() {{
+ put(3, new AdminKeyset(3, 5, "test", Set.of(4, 6, 7), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ put(4, new AdminKeyset(4, 7, "test", Set.of(12), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ put(5, new AdminKeyset(5, 4, "test", Set.of(5), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ }};
+
+ setAdminKeysets(keysets);
+ mockSiteExistence(5, 7, 4, 8);
+
+ String body = " {\n" +
+ " \"hash\": 0\n" +
+ " }";
+
+ post(vertx, testContext, "api/sharing/list/8", body, response -> {
+ assertEquals(200, response.statusCode());
+
+ AdminKeyset expected = new AdminKeyset(6, 8, "", Set.of(), Instant.now().getEpochSecond(), true, true, new HashSet<>());
+ compareKeysetListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ compareKeysetTypeListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_types"));
+ assertEquals(expected.getAllowedSites(), keysets.get(6).getAllowedSites());
+ assertEquals(expected.getAllowedTypes(), keysets.get(6).getAllowedTypes());
+
+ verify(keysetKeyManager).addKeysetKey(6);
+ testContext.completeNow();
+ });
+ }
+
@Test
void listSiteSetNewWithType(Vertx vertx, VertxTestContext testContext) {
fakeAuth(Role.SHARING_PORTAL);
@@ -1112,8 +1143,9 @@ void KeysetSetNewDisallowMultipleForSite(Vertx vertx, VertxTestContext testConte
});
}
+ // `allowed_sites = null` is no longer allowed in the admin UI. This test is retained to verify normalization: if `allowed_sites` is null or missing, it should be converted to an empty set.`
@Test
- void KeysetSetNewNullAllowedSites(Vertx vertx, VertxTestContext testContext) {
+ void KeysetSetNewAllowedSitesMissingInRequest(Vertx vertx, VertxTestContext testContext) {
fakeAuth(Role.MAINTAINER);
mockSiteExistence(5, 3);
@@ -1131,15 +1163,20 @@ void KeysetSetNewNullAllowedSites(Vertx vertx, VertxTestContext testContext) {
post(vertx, testContext, "api/sharing/keyset", body, response -> {
assertEquals(200, response.statusCode());
- AdminKeyset expected = new AdminKeyset(2, 1, "test", null, Instant.now().getEpochSecond(), true, true, new HashSet<>());
- assertEquals(null, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ // Next keyset id is max(existing ids, 3) + 1 => 4 when only keyset 1 exists
+ int newKeysetId = 4;
+ AdminKeyset expected = new AdminKeyset(newKeysetId, 3, "", new HashSet<>(), Instant.now().getEpochSecond(), true, true, new HashSet<>());
+ compareKeysetListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ compareKeysetTypeListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_types"));
+ assertEquals(expected.getAllowedSites(), keysets.get(newKeysetId).getAllowedSites());
+ assertEquals(expected.getAllowedTypes(), keysets.get(newKeysetId).getAllowedTypes());
testContext.completeNow();
});
}
@Test
- void KeysetSetNewExplicitlyNullAllowedSites(Vertx vertx, VertxTestContext testContext) {
+ void KeysetSetUsingNewExplicitlyNullAllowedSitesInput(Vertx vertx, VertxTestContext testContext) {
fakeAuth(Role.MAINTAINER);
mockSiteExistence(5, 3);
@@ -1158,8 +1195,77 @@ void KeysetSetNewExplicitlyNullAllowedSites(Vertx vertx, VertxTestContext testCo
post(vertx, testContext, "api/sharing/keyset", body, response -> {
assertEquals(200, response.statusCode());
- AdminKeyset expected = new AdminKeyset(2, 1, "test", null, Instant.now().getEpochSecond(), true, true, new HashSet<>());
- assertEquals(null, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ int newKeysetId = 4;
+ AdminKeyset expected = new AdminKeyset(newKeysetId, 3, "", new HashSet<>(), Instant.now().getEpochSecond(), true, true, new HashSet<>());
+ compareKeysetListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ compareKeysetTypeListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_types"));
+ assertEquals(expected.getAllowedSites(), keysets.get(newKeysetId).getAllowedSites());
+ assertEquals(expected.getAllowedTypes(), keysets.get(newKeysetId).getAllowedTypes());
+
+ testContext.completeNow();
+ });
+ }
+
+ @Test
+ void KeysetSetAllowedSitesMissingWithNonEmptyAllowedTypesInput(Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.MAINTAINER);
+
+ mockSiteExistence(5, 3);
+
+ Map keysets = new HashMap() {{
+ put(1, new AdminKeyset(1, 5, "test", Set.of(4, 6, 7), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ }};
+
+ setAdminKeysets(keysets);
+
+ String body = " {\n" +
+ " \"site_id\": 3,\n" +
+ " \"allowed_types\": [ \"ADVERTISER\" ]\n" +
+ " }";
+
+ post(vertx, testContext, "api/sharing/keyset", body, response -> {
+ assertEquals(200, response.statusCode());
+
+ int newKeysetId = 4;
+ AdminKeyset expected = new AdminKeyset(newKeysetId, 3, "", new HashSet<>(), Instant.now().getEpochSecond(), true, true,
+ Set.of(ClientType.ADVERTISER));
+ compareKeysetListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ compareKeysetTypeListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_types"));
+ assertEquals(expected.getAllowedSites(), keysets.get(newKeysetId).getAllowedSites());
+ assertEquals(expected.getAllowedTypes(), keysets.get(newKeysetId).getAllowedTypes());
+
+ testContext.completeNow();
+ });
+ }
+
+ @Test
+ void KeysetSetWithExplicitNullAllowedSitesAndNonEmptyAllowedTypesInput(Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.MAINTAINER);
+
+ mockSiteExistence(5, 3);
+
+ Map keysets = new HashMap() {{
+ put(1, new AdminKeyset(1, 5, "test", Set.of(4, 6, 7), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ }};
+
+ setAdminKeysets(keysets);
+
+ String body = " {\n" +
+ " \"site_id\": 3,\n" +
+ " \"allowed_sites\": null,\n" +
+ " \"allowed_types\": [ \"ADVERTISER\" ]\n" +
+ " }";
+
+ post(vertx, testContext, "api/sharing/keyset", body, response -> {
+ assertEquals(200, response.statusCode());
+
+ int newKeysetId = 4;
+ AdminKeyset expected = new AdminKeyset(newKeysetId, 3, "", new HashSet<>(), Instant.now().getEpochSecond(), true, true,
+ Set.of(ClientType.ADVERTISER));
+ compareKeysetListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ compareKeysetTypeListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_types"));
+ assertEquals(expected.getAllowedSites(), keysets.get(newKeysetId).getAllowedSites());
+ assertEquals(expected.getAllowedTypes(), keysets.get(newKeysetId).getAllowedTypes());
testContext.completeNow();
});
@@ -1184,8 +1290,11 @@ void KeysetSetUpdateNullAllowedSites(Vertx vertx, VertxTestContext testContext)
post(vertx, testContext, "api/sharing/keyset", body, response -> {
assertEquals(200, response.statusCode());
- AdminKeyset expected = new AdminKeyset(1, 5, "test", null, Instant.now().getEpochSecond(), true, true, new HashSet<>());
- assertEquals(null, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ AdminKeyset expected = new AdminKeyset(1, 5, "test", Set.of(), Instant.now().getEpochSecond(), true, true, new HashSet<>());
+ compareKeysetListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ compareKeysetTypeListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_types"));
+ assertEquals(expected.getAllowedSites(), keysets.get(1).getAllowedSites());
+ assertEquals(expected.getAllowedTypes(), keysets.get(1).getAllowedTypes());
testContext.completeNow();
});
@@ -1211,8 +1320,11 @@ void KeysetSetUpdateExplicitlyNullAllowedSites(Vertx vertx, VertxTestContext tes
post(vertx, testContext, "api/sharing/keyset", body, response -> {
assertEquals(200, response.statusCode());
- AdminKeyset expected = new AdminKeyset(1, 5, "test", null, Instant.now().getEpochSecond(), true, true, new HashSet<>());
- assertEquals(null, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ AdminKeyset expected = new AdminKeyset(1, 5, "test", Set.of(), Instant.now().getEpochSecond(), true, true, new HashSet<>());
+ compareKeysetListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_sites"));
+ compareKeysetTypeListToResult(expected, response.bodyAsJsonObject().getJsonArray("allowed_types"));
+ assertEquals(expected.getAllowedSites(), keysets.get(1).getAllowedSites());
+ assertEquals(expected.getAllowedTypes(), keysets.get(1).getAllowedTypes());
testContext.completeNow();
});
@@ -1446,4 +1558,64 @@ void RelatedKeysetSetsWithoutIdReader(Vertx vertx, VertxTestContext testContext)
testContext.completeNow();
});
}
+
+ @ParameterizedTest
+ @EnumSource(value = ClientType.class, names = {"ADVERTISER", "DATA_PROVIDER"})
+ void keysetSetNewViaHttp_forAdvertiserOrDataProvider_neverCallsCreateKeysetSharedWithDsps(
+ ClientType sharingType, Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.MAINTAINER);
+
+ Map keysets = new HashMap<>() {{
+ put(3, new AdminKeyset(3, 5, "test", Set.of(4, 6, 7), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ put(4, new AdminKeyset(4, 7, "test", Set.of(12), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ put(5, new AdminKeyset(5, 4, "test", Set.of(5), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ }};
+ setAdminKeysets(keysets);
+ mockSiteExistence(5, 7, 4, 8);
+
+ String body = "{\n"
+ + " \"site_id\": 8,\n"
+ + " \"allowed_types\": [\"" + sharingType.name() + "\"]\n"
+ + "}";
+
+ post(vertx, testContext, "api/sharing/keyset", body, response -> {
+ assertEquals(200, response.statusCode());
+ JsonArray allowedTypesJson = response.bodyAsJsonObject().getJsonArray("allowed_types");
+ compareKeysetTypeListToResult(
+ new AdminKeyset(6, 8, "", Set.of(), Instant.now().getEpochSecond(), true, true, Set.of(sharingType)),
+ allowedTypesJson);
+ assertEquals(1, allowedTypesJson.size());
+ testContext.completeNow();
+ });
+ }
+
+ @ParameterizedTest
+ @EnumSource(value = ClientType.class, names = {"ADVERTISER", "DATA_PROVIDER"})
+ void listSiteSetNewViaHttp_forAdvertiserOrDataProvider_neverCallsCreateKeysetSharedWithDsps(
+ ClientType sharingType, Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.SHARING_PORTAL);
+
+ Map keysets = new HashMap<>() {{
+ put(3, new AdminKeyset(3, 5, "test", Set.of(4, 6, 7), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ put(4, new AdminKeyset(4, 7, "test", Set.of(12), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ put(5, new AdminKeyset(5, 4, "test", Set.of(5), Instant.now().getEpochSecond(), true, true, new HashSet<>()));
+ }};
+ setAdminKeysets(keysets);
+ mockSiteExistence(5, 7, 4, 8);
+
+ String body = "{\n"
+ + " \"allowed_types\": [\"" + sharingType.name() + "\"],\n"
+ + " \"hash\": 0\n"
+ + "}";
+
+ post(vertx, testContext, "api/sharing/list/8", body, response -> {
+ assertEquals(200, response.statusCode());
+ JsonArray allowedTypesJson = response.bodyAsJsonObject().getJsonArray("allowed_types");
+ compareKeysetTypeListToResult(
+ new AdminKeyset(6, 8, "", Set.of(), Instant.now().getEpochSecond(), true, true, Set.of(sharingType)),
+ allowedTypesJson);
+ assertEquals(1, allowedTypesJson.size());
+ testContext.completeNow();
+ });
+ }
}
diff --git a/webroot/adm/keyset.html b/webroot/adm/keyset.html
index 6ad5413c..c1633c09 100644
--- a/webroot/adm/keyset.html
+++ b/webroot/adm/keyset.html
@@ -202,20 +202,6 @@ UID2 Env - Keyset Access Management
keyset_id: parseInt(inputs.keysetId)
})
}
- },
- {
- id: 'resetAllowedSitesToNull',
- title: 'Reset Allowed Sites To Null',
- role: 'maintainer',
- inputs: [keysetIdInput],
- apiCall: {
- method: 'POST',
- url: '/api/sharing/keyset',
- getPayload: (inputs) => ({
- allowed_sites: null,
- keyset_id: parseInt(inputs.keysetId)
- })
- }
}
]
};