Skip to content

Commit

Permalink
Make glv id optional (#839)
Browse files Browse the repository at this point in the history
* Skip host vendor check for cookie sync and setuid
  • Loading branch information
BraslavskiyAndrey authored and nickluck8 committed Aug 9, 2021
1 parent a0f686a commit 603f85a
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 9 deletions.
26 changes: 22 additions & 4 deletions src/main/java/org/prebid/server/handler/CookieSyncHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.prebid.server.metric.Metrics;
import org.prebid.server.privacy.gdpr.TcfDefinerService;
import org.prebid.server.privacy.gdpr.model.PrivacyEnforcementAction;
import org.prebid.server.privacy.gdpr.model.TcfContext;
import org.prebid.server.privacy.gdpr.model.TcfResponse;
import org.prebid.server.privacy.model.Privacy;
import org.prebid.server.privacy.model.PrivacyContext;
Expand Down Expand Up @@ -96,7 +97,7 @@ public CookieSyncHandler(String externalUrl,
this.activeBidders = activeBidders(bidderCatalog);
this.tcfDefinerService = Objects.requireNonNull(tcfDefinerService);
this.privacyEnforcementService = Objects.requireNonNull(privacyEnforcementService);
this.gdprHostVendorId = gdprHostVendorId;
this.gdprHostVendorId = validateHostVendorId(gdprHostVendorId);
this.defaultCoopSync = defaultCoopSync;
this.listOfCoopSyncBidders = CollectionUtils.isNotEmpty(listOfCoopSyncBidders)
? listOfCoopSyncBidders
Expand All @@ -111,6 +112,13 @@ private static Set<String> activeBidders(BidderCatalog bidderCatalog) {
return bidderCatalog.names().stream().filter(bidderCatalog::isActive).collect(Collectors.toSet());
}

private static Integer validateHostVendorId(Integer gdprHostVendorId) {
if (gdprHostVendorId == null) {
logger.warn("gdpr.host-vendor-id not specified. Will skip host company GDPR checks");
}
return gdprHostVendorId;
}

@Override
public void handle(RoutingContext context) {
metrics.updateCookieSyncRequestMetric();
Expand Down Expand Up @@ -165,9 +173,8 @@ public void handle(RoutingContext context) {
.compose(account -> privacyEnforcementService.contextFromCookieSyncRequest(
cookieSyncRequest, context.request(), account, timeout)
.map(privacyContext -> Tuple2.of(account, privacyContext)))
.map((Tuple2<Account, PrivacyContext> accountAndPrivacy) -> tcfDefinerService.resultForVendorIds(
vendorIds, accountAndPrivacy.getRight().getTcfContext())
.compose(this::handleVendorIdResult)
.map((Tuple2<Account, PrivacyContext> accountAndPrivacy) -> allowedForVendorId(vendorIds,
accountAndPrivacy.getRight().getTcfContext())
.compose(ignored -> tcfDefinerService.resultForBidderNames(
biddersToSync,
accountAndPrivacy.getRight().getTcfContext(),
Expand Down Expand Up @@ -208,6 +215,17 @@ private Set<String> biddersToSync(List<String> requestBidders, Boolean requestCo
return new HashSet<>(requestBidders);
}

/**
* Returns failed future if vendor is not allowed for cookie sync.
* If host vendor id is null, host allowed to sync cookies.
*/
private Future<Void> allowedForVendorId(Set<Integer> vendorIds, TcfContext tcfContext) {
return gdprHostVendorId != null
? tcfDefinerService.resultForVendorIds(vendorIds, tcfContext)
.compose(this::handleVendorIdResult)
: Future.succeededFuture();
}

private Set<String> addAllCoopSyncBidders(List<String> bidders) {
final Set<String> updatedBidders = listOfCoopSyncBidders.stream()
.flatMap(Collection::stream)
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/org/prebid/server/handler/SetuidHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public SetuidHandler(long defaultTimeout,
this.applicationSettings = Objects.requireNonNull(applicationSettings);
this.privacyEnforcementService = Objects.requireNonNull(privacyEnforcementService);
this.tcfDefinerService = Objects.requireNonNull(tcfDefinerService);
this.gdprHostVendorId = gdprHostVendorId;
this.gdprHostVendorId = validateHostVendorId(gdprHostVendorId);
this.analyticsReporter = Objects.requireNonNull(analyticsReporter);
this.metrics = Objects.requireNonNull(metrics);
this.timeoutFactory = Objects.requireNonNull(timeoutFactory);
Expand All @@ -84,6 +84,13 @@ public SetuidHandler(long defaultTimeout,
.collect(Collectors.toSet());
}

private static Integer validateHostVendorId(Integer gdprHostVendorId) {
if (gdprHostVendorId == null) {
logger.warn("gdpr.host-vendor-id not specified. Will skip host company GDPR checks");
}
return gdprHostVendorId;
}

@Override
public void handle(RoutingContext context) {
final UidsCookie uidsCookie = uidsCookieService.parseFromRequest(context);
Expand All @@ -106,6 +113,11 @@ public void handle(RoutingContext context) {
return;
}

if (gdprHostVendorId == null) {
respondWithCookie(context, cookieName, uidsCookie);
return;
}

final Set<Integer> vendorIds = Collections.singleton(gdprHostVendorId);
final String requestAccount = context.request().getParam(ACCOUNT_PARAM);
final Timeout timeout = timeoutFactory.create(defaultTimeout);
Expand Down
44 changes: 42 additions & 2 deletions src/test/java/org/prebid/server/handler/CookieSyncHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,46 @@ public void shouldTolerateBiddersWithoutUsersyncUrl() throws IOException {
assertThat(cookieSyncResponse).isEqualTo(CookieSyncResponse.of("ok", emptyList()));
}

@Test
public void shouldSkipVendorHostCheckAndContinueWithBiddersCheckWhenHostVendorIdIsMissing() throws IOException {
// given
cookieSyncHandler = new CookieSyncHandler("http://external-url", 2000, uidsCookieService, applicationSettings,
bidderCatalog, tcfDefinerService, privacyEnforcementService, null, false, emptyList(),
analyticsReporter, metrics, timeoutFactory, jacksonMapper);
given(uidsCookieService.parseFromRequest(any())).willReturn(new UidsCookie(
Uids.builder().uids(singletonMap(RUBICON, UidWithExpiry.live("J5VLCWQP-26-CWFT"))).build(),
jacksonMapper));

given(routingContext.getBody())
.willReturn(givenRequestBody(
CookieSyncRequest.builder().bidders(asList(RUBICON, APPNEXUS)).build()));

rubiconUsersyncer = new Usersyncer(RUBICON, "", null, null, null, false);
appnexusUsersyncer = new Usersyncer(APPNEXUS_COOKIE, "", null, null, null, false);
givenUsersyncersReturningFamilyName();

given(bidderCatalog.isActive(RUBICON)).willReturn(true);
given(bidderCatalog.isActive(APPNEXUS)).willReturn(true);

given(bidderCatalog.bidderInfoByName(APPNEXUS))
.willReturn(BidderInfo.create(true, null, null,
null, null, 2, true, true, false));

givenTcfServiceReturningVendorIdResult(singleton(1));
givenTcfServiceReturningBidderNamesResult(singleton(RUBICON));

// when
cookieSyncHandler.handle(routingContext);

// then
verify(tcfDefinerService, never()).resultForVendorIds(anySet(), any());
final CookieSyncResponse cookieSyncResponse = captureCookieSyncResponse();
assertThat(cookieSyncResponse.getStatus()).isEqualTo("ok");
assertThat(cookieSyncResponse.getBidderStatus()).hasSize(1)
.extracting(BidderUsersyncStatus::getBidder, BidderUsersyncStatus::getError)
.containsOnly(tuple(APPNEXUS, "Rejected by TCF"));
}

@Test
public void shouldUpdateCookieSyncSetAndRejectByTcfMetricForEachRejectedAndSyncedBidder() {
// given
Expand Down Expand Up @@ -685,7 +725,7 @@ public void shouldUpdateCookieSyncMatchesMetricForEachAlreadySyncedBidder() {
public void shouldRespondWithNoCookieStatusIfHostVendorRejectedByTcf() throws IOException {
// given
cookieSyncHandler = new CookieSyncHandler("http://external-url", 2000, uidsCookieService, applicationSettings,
bidderCatalog, tcfDefinerService, privacyEnforcementService, null, false, emptyList(),
bidderCatalog, tcfDefinerService, privacyEnforcementService, 1, false, emptyList(),
analyticsReporter, metrics, timeoutFactory, jacksonMapper);

given(uidsCookieService.parseFromRequest(any()))
Expand All @@ -701,7 +741,7 @@ bidderCatalog, tcfDefinerService, privacyEnforcementService, null, false, emptyL
given(bidderCatalog.isActive(RUBICON)).willReturn(true);
given(bidderCatalog.isActive(APPNEXUS)).willReturn(true);

givenTcfServiceReturningVendorIdResult(singleton(1));
givenTcfServiceReturningVendorIdResult(emptySet());
givenTcfServiceReturningBidderNamesResult(set(RUBICON, APPNEXUS));

// when
Expand Down
40 changes: 38 additions & 2 deletions src/test/java/org/prebid/server/handler/SetuidHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public class SetuidHandlerTest extends VertxTest {

@Before
public void setUp() {
final Map<Integer, PrivacyEnforcementAction> vendorIdToGdpr = singletonMap(null,
final Map<Integer, PrivacyEnforcementAction> vendorIdToGdpr = singletonMap(1,
PrivacyEnforcementAction.allowAll());

given(privacyEnforcementService.contextFromSetuidRequest(any(), any(), any()))
Expand Down Expand Up @@ -118,7 +118,7 @@ public void setUp() {
bidderCatalog,
privacyEnforcementService,
tcfDefinerService,
null,
1,
analyticsReporter,
metrics,
timeoutFactory);
Expand Down Expand Up @@ -452,6 +452,42 @@ public void shouldRespondWithCookieIfUserIsNotInGdprScope() throws IOException {
assertThat(decodedUids.getUids().get(RUBICON).getUid()).isEqualTo("J5VLCWQP-26-CWFT");
}

@Test
public void shouldSkipTcfChecksAndRespondWithCookieIfHostVendorIdNotDefined() throws IOException {
// given
final Clock clock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
setuidHandler = new SetuidHandler(2000, uidsCookieService, applicationSettings,
bidderCatalog, privacyEnforcementService, tcfDefinerService, null, analyticsReporter, metrics,
new TimeoutFactory(clock));
given(tcfDefinerService.resultForVendorIds(anySet(), any()))
.willReturn(Future.succeededFuture(TcfResponse.of(false, emptyMap(), null)));

given(uidsCookieService.parseFromRequest(any()))
.willReturn(new UidsCookie(Uids.builder().uids(emptyMap()).build(), jacksonMapper));

// {"tempUIDs":{"rubicon":{"uid":"J5VLCWQP-26-CWFT"}}}
given(uidsCookieService.toCookie(any())).willReturn(Cookie
.cookie("uids", "eyJ0ZW1wVUlEcyI6eyJydWJpY29uIjp7InVpZCI6Iko1VkxDV1FQLTI2LUNXRlQifX19"));

given(httpRequest.getParam("bidder")).willReturn(RUBICON);
given(httpRequest.getParam("uid")).willReturn("J5VLCWQP-26-CWFT");

given(httpResponse.setStatusCode(anyInt())).willReturn(httpResponse);

// when
setuidHandler.handle(routingContext);

// then
verify(tcfDefinerService, never()).resultForVendorIds(anySet(), any());
verify(routingContext, never()).addCookie(any(Cookie.class));
verify(httpResponse).end();

final String uidsCookie = getUidsCookie();
final Uids decodedUids = decodeUids(uidsCookie);
assertThat(decodedUids.getUids()).hasSize(1);
assertThat(decodedUids.getUids().get(RUBICON).getUid()).isEqualTo("J5VLCWQP-26-CWFT");
}

@Test
public void shouldUpdateOptOutsMetricIfOptedOut() {
// given
Expand Down

0 comments on commit 603f85a

Please sign in to comment.