Skip to content

Commit 6c750b4

Browse files
committed
Added validation that vendor list is not deleted in requested GVL
1 parent 844a3cb commit 6c750b4

5 files changed

Lines changed: 51 additions & 10 deletions

File tree

src/main/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListService.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,12 @@ private VendorList processResponse(HttpClientResponse response) {
9393
Set<Integer> extractDeletedVendorIds(VendorList vendorList) {
9494
final Instant now = clock.instant();
9595
return vendorList.getVendors().values().stream()
96-
.filter(vendor -> isDeletedAt(vendor, now))
96+
.filter(vendor -> VendorListUtil.vendorIsDeletedAt(vendor, now))
9797
.map(Vendor::getId)
9898
.filter(Objects::nonNull)
9999
.collect(Collectors.toUnmodifiableSet());
100100
}
101101

102-
private static boolean isDeletedAt(Vendor vendor, Instant now) {
103-
final Instant deletedDate = vendor.getDeletedDate();
104-
return deletedDate != null && deletedDate.isBefore(now);
105-
}
106-
107102
private Void updateDeletedVendorIds(Set<Integer> ids) {
108103
deletedVendorIds = ids;
109104
metrics.updatePrivacyTcfVendorListLatestOkMetric();

src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtil.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList;
1010

1111
import java.io.IOException;
12+
import java.time.Instant;
1213
import java.util.Collection;
1314

1415
public class VendorListUtil {
@@ -47,4 +48,9 @@ private static boolean vendorsAreValid(Collection<Vendor> vendors) {
4748
&& vendor.getFeatures() != null
4849
&& vendor.getSpecialFeatures() != null);
4950
}
51+
52+
public static boolean vendorIsDeletedAt(Vendor vendor, Instant now) {
53+
final Instant deletedDate = vendor.getDeletedDate();
54+
return deletedDate != null && deletedDate.isBefore(now);
55+
}
5056
}

src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListService.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import io.vertx.core.Future;
55
import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor;
66

7+
import java.time.Clock;
8+
import java.time.Instant;
79
import java.util.Map;
810
import java.util.Objects;
911
import java.util.stream.Collectors;
@@ -13,14 +15,17 @@ public class VersionedVendorListService {
1315
private final VendorListService vendorListServiceV2;
1416
private final VendorListService vendorListServiceV3;
1517
private final LiveVendorListService liveVendorListService;
18+
private final Clock clock;
1619

1720
public VersionedVendorListService(VendorListService vendorListServiceV2,
1821
VendorListService vendorListServiceV3,
19-
LiveVendorListService liveVendorListService) {
22+
LiveVendorListService liveVendorListService,
23+
Clock clock) {
2024

2125
this.vendorListServiceV2 = Objects.requireNonNull(vendorListServiceV2);
2226
this.vendorListServiceV3 = Objects.requireNonNull(vendorListServiceV3);
2327
this.liveVendorListService = Objects.requireNonNull(liveVendorListService);
28+
this.clock = Objects.requireNonNull(clock);
2429
}
2530

2631
public Future<Map<Integer, Vendor>> forConsent(TCString consent) {
@@ -35,7 +40,9 @@ public Future<Map<Integer, Vendor>> forConsent(TCString consent) {
3540
}
3641

3742
private Map<Integer, Vendor> filterDeletedVendors(Map<Integer, Vendor> vendors) {
43+
Instant now = clock.instant();
3844
return vendors.entrySet().stream()
45+
.filter(entry -> !VendorListUtil.vendorIsDeletedAt(entry.getValue(), now))
3946
.filter(entry -> !liveVendorListService.isDeleted(entry.getKey()))
4047
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
4148
}

src/main/java/org/prebid/server/spring/config/PrivacyServiceConfiguration.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,11 @@ LiveVendorListService liveVendorListService(
171171
@Bean
172172
VersionedVendorListService versionedVendorListService(VendorListService vendorListServiceV2,
173173
VendorListService vendorListServiceV3,
174-
LiveVendorListService liveVendorListService) {
174+
LiveVendorListService liveVendorListService,
175+
Clock clock) {
175176

176177
return new VersionedVendorListService(
177-
vendorListServiceV2, vendorListServiceV3, liveVendorListService);
178+
vendorListServiceV2, vendorListServiceV3, liveVendorListService, clock);
178179
}
179180

180181
@Bean

src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListServiceTest.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import org.mockito.junit.jupiter.MockitoExtension;
1111
import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor;
1212

13+
import java.time.Clock;
14+
import java.time.Instant;
15+
import java.time.ZoneOffset;
1316
import java.util.Map;
1417
import java.util.concurrent.ThreadLocalRandom;
1518

@@ -23,6 +26,8 @@
2326
@ExtendWith(MockitoExtension.class)
2427
public class VersionedVendorListServiceTest {
2528

29+
private static final Instant NOW = Instant.parse("2024-06-01T12:00:00Z");
30+
2631
private VersionedVendorListService target;
2732

2833
@Mock
@@ -35,7 +40,7 @@ public class VersionedVendorListServiceTest {
3540
@BeforeEach
3641
public void setUp() {
3742
target = new VersionedVendorListService(
38-
vendorListServiceV2, vendorListServiceV3, liveVendorListService);
43+
vendorListServiceV2, vendorListServiceV3, liveVendorListService, Clock.fixed(NOW, ZoneOffset.UTC));
3944
}
4045

4146
@Test
@@ -74,6 +79,33 @@ public void versionedVendorListServiceShouldTreatTcfPolicyGreaterOrEqualFourAsVe
7479
verify(vendorListServiceV3).forVersion(12);
7580
}
7681

82+
@Test
83+
public void forConsentShouldRemoveVendorsMarkedDeletedInRequestedGvl() {
84+
// given
85+
final Vendor deletedVendor = Vendor.empty(1).toBuilder()
86+
.deletedDate(Instant.parse("2024-01-01T00:00:00Z"))
87+
.build();
88+
final Vendor activeVendor = Vendor.empty(52);
89+
final Map<Integer, Vendor> vendorList = Map.of(1, deletedVendor, 52, activeVendor);
90+
final TCString consent = TCStringEncoder.newBuilder()
91+
.version(2)
92+
.tcfPolicyVersion(3)
93+
.vendorListVersion(12)
94+
.toTCString();
95+
96+
given(vendorListServiceV2.forVersion(anyInt())).willReturn(Future.succeededFuture(vendorList));
97+
given(liveVendorListService.isDeleted(anyInt())).willReturn(false);
98+
99+
// when and then
100+
assertThat(target.forConsent(consent))
101+
.isSucceeded()
102+
.unwrap()
103+
.satisfies(result -> {
104+
assertThat(result).containsOnlyKeys(52);
105+
assertThat(result.get(52)).isSameAs(activeVendor);
106+
});
107+
}
108+
77109
@Test
78110
public void forConsentShouldRemoveVendorsMarkedDeletedInLiveGvl() {
79111
// given

0 commit comments

Comments
 (0)