Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 47 additions & 57 deletions src/main/java/org/prebid/server/bidder/UsersyncInfoFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,70 +6,73 @@
import org.prebid.server.privacy.model.Privacy;
import org.prebid.server.proto.response.UsersyncInfo;
import org.prebid.server.util.HttpUtil;
import org.prebid.server.util.Uri;

import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

public class UsersyncInfoFactory {

private static final String CALLBACK_URL_TEMPLATE = """
{{base_url}}/setuid?\
bidder={{bidder}}\
&gdpr={{gdpr}}\
&gdpr_consent={{gdpr_consent}}\
&us_privacy={{us_privacy}}\
&gpp={{gpp}}\
&gpp_sid={{gpp_sid}}\
&f={{format}}\
&uid={{uid}}""";

private static final String BASE_URL_PLACEHOLDER = "{{base_url}}";
private static final String BIDDER_PLACEHOLDER = "{{bidder}}";
private static final String GDPR_PLACEHOLDER = "{{gdpr}}";
private static final String GDPR_CONSENT_PLACEHOLDER = "{{gdpr_consent}}";
private static final String US_PRIVACY_PLACEHOLDER = "{{us_privacy}}";
private static final String GPP_PLACEHOLDER = "{{gpp}}";
private static final String GPP_SID_PLACEHOLDER = "{{gpp_sid}}";
private static final String REDIRECT_URL_PLACEHOLDER = "{{redirect_url}}";
private static final String FORMAT_PLACEHOLDER = "{{format}}";
private static final String UID_PLACEHOLDER = "{{uid}}";

private final String externalUrl;
private static final String CALLBACK_RELATIVE_URL_TEMPLATE = """
/setuid?\
bidder={bidder}\
&gdpr={gdpr}\
&gdpr_consent={gdpr_consent}\
&us_privacy={us_privacy}\
&gpp={gpp}\
&gpp_sid={gpp_sid}\
&f={format}""";

private static final String BIDDER_PLACEHOLDER = "bidder";
private static final String GDPR_PLACEHOLDER = "gdpr";
private static final String GDPR_CONSENT_PLACEHOLDER = "gdpr_consent";
private static final String US_PRIVACY_PLACEHOLDER = "us_privacy";
private static final String GPP_PLACEHOLDER = "gpp";
private static final String GPP_SID_PLACEHOLDER = "gpp_sid";
private static final String REDIRECT_URL_PLACEHOLDER = "redirect_url";
private static final String FORMAT_PLACEHOLDER = "format";

private final Uri callbackUrlTemplate;

public UsersyncInfoFactory(String externalUrl) {
this.externalUrl = HttpUtil.validateUrl(Objects.requireNonNull(externalUrl));
this.callbackUrlTemplate = Uri.of(Objects.requireNonNull(externalUrl) + CALLBACK_RELATIVE_URL_TEMPLATE);
}

public UsersyncInfo build(String bidder,
String hostCookieUid,
UsersyncMethod usersyncMethod,
Privacy privacy) {

final String usersyncUrl = hostCookieUid == null
? StringUtils.defaultString(usersyncMethod.getUsersyncUrl())
: buildRedirectUrl(bidder, hostCookieUid, usersyncMethod);

final String redirectUrl = hostCookieUid == null
? buildRedirectUrl(bidder, usersyncMethod.getUidMacro(), usersyncMethod)
: StringUtils.EMPTY;

final Map<String, String> privacyParams = preparePrivacyParams(privacy);
final String usersyncUrlWithPrivacy = applyParams(usersyncUrl, encodeParams(privacyParams));
final String redirectUrlWithPrivacy = applyParams(redirectUrl, privacyParams);
return UsersyncInfo.of(
hostCookieUid == null
? buildSyncUrl(bidder, usersyncMethod, privacy)
: buildSetUidUrl(bidder, HttpUtil.encodeUrl(hostCookieUid), usersyncMethod, privacy),
usersyncMethod.getType(),
usersyncMethod.isSupportCORS());
}

final String finalUrl = usersyncUrlWithPrivacy.replace(
REDIRECT_URL_PLACEHOLDER, HttpUtil.encodeUrl(redirectUrlWithPrivacy));
private String buildSyncUrl(String bidder, UsersyncMethod usersyncMethod, Privacy privacy) {
return usersyncMethod.getUsersyncUrl().parameterized()
.replaceMacros(preparePrivacyParams(privacy))
.replaceMacro(
REDIRECT_URL_PLACEHOLDER,
buildSetUidUrl(bidder, usersyncMethod.getUidMacro(), usersyncMethod, privacy))
.expand();
}

return UsersyncInfo.of(finalUrl, usersyncMethod.getType(), usersyncMethod.isSupportCORS());
private String buildSetUidUrl(String bidder, String uid, UsersyncMethod usersyncMethod, Privacy privacy) {
return callbackUrlTemplate
.replaceMacros(prepareRedirectParams(bidder, uid, usersyncMethod))
.replaceMacros(preparePrivacyParams(privacy))
.expand()
+ "&uid=" + StringUtils.defaultString(uid); // uid macro should not be url-encoded
}

private String buildRedirectUrl(String bidder, String uid, UsersyncMethod method) {
return CALLBACK_URL_TEMPLATE
.replace(BASE_URL_PLACEHOLDER, externalUrl)
.replace(BIDDER_PLACEHOLDER, HttpUtil.encodeUrl(bidder))
.replace(UID_PLACEHOLDER, StringUtils.defaultString(uid))
.replace(FORMAT_PLACEHOLDER, resolveFormat(method).name);
private Map<String, String> prepareRedirectParams(String bidder, String uid, UsersyncMethod method) {
return Map.of(
BIDDER_PLACEHOLDER, bidder,
FORMAT_PLACEHOLDER, resolveFormat(method).name);
}

private static UsersyncFormat resolveFormat(UsersyncMethod method) {
Expand All @@ -86,17 +89,4 @@ private static Map<String, String> preparePrivacyParams(Privacy privacy) {
.map(String::valueOf)
.collect(Collectors.joining(",")));
}

private static Map<String, String> encodeParams(Map<String, String> params) {
return params.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> HttpUtil.encodeUrl(entry.getValue())));
}

private static String applyParams(String url, Map<String, String> params) {
String result = url;
for (Map.Entry<String, String> param: params.entrySet()) {
result = result.replace(param.getKey(), param.getValue());
}
return result;
}
}
3 changes: 2 additions & 1 deletion src/main/java/org/prebid/server/bidder/UsersyncMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import lombok.Builder;
import lombok.Value;
import org.prebid.server.util.Uri;

@Value
@Builder
public class UsersyncMethod {

UsersyncMethodType type;

String usersyncUrl;
Uri usersyncUrl;

String uidMacro;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.prebid.server.bidder;

import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.proto.request.CookieSyncRequest;
import org.prebid.server.util.StreamUtil;

Expand Down Expand Up @@ -52,7 +51,7 @@ private boolean methodValidAndAllowed(UsersyncMethod usersyncMethod, String bidd
}

private boolean methodValid(UsersyncMethod usersyncMethod) {
return usersyncMethod != null && StringUtils.isNotBlank(usersyncMethod.getUsersyncUrl());
return usersyncMethod != null;
}

private boolean methodAllowed(UsersyncMethod usersyncMethod, String bidder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import org.prebid.server.spring.config.bidder.model.usersync.UsersyncBidderRegulationScopeProperties;
import org.prebid.server.spring.config.bidder.model.usersync.UsersyncConfigurationProperties;
import org.prebid.server.spring.config.bidder.model.usersync.UsersyncMethodConfigurationProperties;

import java.util.Objects;
import org.prebid.server.util.Uri;

public class UsersyncerUtil {

Expand Down Expand Up @@ -37,7 +36,7 @@ private static UsersyncMethod toMethod(UsersyncMethodType type,

return UsersyncMethod.builder()
.type(type)
.usersyncUrl(Objects.requireNonNull(properties.getUrl()))
.usersyncUrl(Uri.of(properties.getUrl()))
.uidMacro(properties.getUidMacro())
.supportCORS(properties.getSupportCors())
.formatOverride(properties.getFormatOverride())
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/prebid/server/util/Uri.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
import io.vertx.uritemplate.ExpandOptions;
import io.vertx.uritemplate.UriTemplate;
import io.vertx.uritemplate.Variables;
import lombok.EqualsAndHashCode;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.stream.Collectors;

@EqualsAndHashCode
public class Uri {

private static final ExpandOptions REQUIRE_ALL_PARAMS = new ExpandOptions().setAllowVariableMiss(false);
Expand All @@ -19,9 +22,12 @@ public class Uri {
private static final String DYNAMIC_QUERY_START_MACRO = "{?" + DYNAMIC_QUERY_PARAM + "*}";
private static final String DYNAMIC_QUERY_CONTINUATION_MACRO = "{&" + DYNAMIC_QUERY_PARAM + "*}";

private final String baseUri;
@EqualsAndHashCode.Exclude
private final UriTemplate template;

private Uri(String uri) {
this.baseUri = uri;
this.template = UriTemplate.of(uri + chooseMacro(uri));
}

Expand Down Expand Up @@ -58,6 +64,10 @@ public ParameterizedUri replaceMacro(String key, List<String> value) {
return parameterized().replaceMacro(key, value);
}

public ParameterizedUri replaceMacros(Map<String, String> values) {
return parameterized().replaceMacros(values);
}

public ParameterizedUri addQueryParam(String key, String value) {
return parameterized().addQueryParam(key, value);
}
Expand Down Expand Up @@ -96,6 +106,11 @@ public ParameterizedUri replaceMacro(String key, List<String> value) {
return this;
}

public ParameterizedUri replaceMacros(Map<String, String> values) {
values.forEach(this::replaceMacro);
return this;
}

public ParameterizedUri addQueryParam(String key, String value) {
if (value != null) {
variables.getMap(DYNAMIC_QUERY_PARAM).put(key, value);
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/aax.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ adapters:
usersync:
cookie-family-name: aax
redirect:
url: https://c.aaxads.com/aacxc.php?fv=1&wbsh=psa&ryvlg=setstatuscode&redirect={{redirect_url}}
url: https://c.aaxads.com/aacxc.php?fv=1&wbsh=psa&ryvlg=setstatuscode&redirect={redirect_url}
support-cors: false
uid-macro: '<vsid>'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/acuityads.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ adapters:
usersync:
cookie-family-name: acuityads
redirect:
url: https://cs.admanmedia.com/sync/prebid?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&redir={{redirect_url}}
url: https://cs.admanmedia.com/sync/prebid?gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&redir={redirect_url}
support-cors: false
uid-macro: '[UID]'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adagio.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ adapters:
usersync:
cookie-family-name: adagio
iframe:
url: https://u-REGION.4dex.io/pbserver/usync.html?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&&gpp_sid={{gpp_sid}}&r={{redirect_url}}
url: https://u-REGION.4dex.io/pbserver/usync.html?gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&gpp={gpp}&&gpp_sid={gpp_sid}&r={redirect_url}
support-cors: false
uid-macro: '{UID}'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ adapters:
usersync:
cookie-family-name: adf
redirect:
url: https://c1.adform.net/cookie?redirect_url={{redirect_url}}
url: https://c1.adform.net/cookie?redirect_url={redirect_url}
support-cors: false
uid-macro: '$UID'
6 changes: 3 additions & 3 deletions src/main/resources/bidder-config/adkernel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ adapters:
enabled: true
cookie-family-name: xapads
redirect:
url: https://sync.adkernel.com/user-sync?t=image&zone=284803&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&gpp_sid={{gpp_sid}}&r={{redirect_url}}
url: https://sync.adkernel.com/user-sync?t=image&zone=284803&gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&gpp={gpp}&gpp_sid={gpp_sid}&r={redirect_url}
support-cors: false
uid-macro: '{UID}'
iframe:
url: https://sync.adkernel.com/user-sync?t=iframe&zone=284803&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&gpp_sid={{gpp_sid}}&r={{redirect_url}}
url: https://sync.adkernel.com/user-sync?t=iframe&zone=284803&gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&gpp={gpp}&gpp_sid={gpp_sid}&r={redirect_url}
support-cors: false
uid-macro: '{UID}'
meta-info:
Expand All @@ -37,6 +37,6 @@ adapters:
usersync:
cookie-family-name: adkernel
redirect:
url: https://sync.adkernel.com/user-sync?t=image&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&gpp_sid={{gpp_sid}}&r={{redirect_url}}
url: https://sync.adkernel.com/user-sync?t=image&gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&gpp={gpp}&gpp_sid={gpp_sid}&r={redirect_url}
support-cors: false
uid-macro: '{UID}'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adkerneladn.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ adapters:
usersync:
cookie-family-name: adkernelAdn
redirect:
url: https://tag.adkernel.com/syncr?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&r={{redirect_url}}
url: https://tag.adkernel.com/syncr?gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&r={redirect_url}
support-cors: false
uid-macro: '${UID}'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adman.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ adapters:
usersync:
cookie-family-name: adman
redirect:
url: https://sync.admanmedia.com/pbs.gif?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&redir={{redirect_url}}
url: https://sync.admanmedia.com/pbs.gif?gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&redir={redirect_url}
support-cors: false
uid-macro: '[UID]'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/admixer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ adapters:
usersync:
cookie-family-name: admixer
redirect:
url: https://inv-nets.admixer.net/adxcm.aspx?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&redir=1&rurl={{redirect_url}}
url: https://inv-nets.admixer.net/adxcm.aspx?gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&redir=1&rurl={redirect_url}
support-cors: false
uid-macro: '$$visitor_cookie$$'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ adapters:
usersync:
cookie-family-name: adot
redirect:
url: https://sync.adotmob.com/cookie/pbs?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&r={{redirect_url}}
url: https://sync.adotmob.com/cookie/pbs?gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&r={redirect_url}
support-cors: false
uid-macro: '{amob_user_id}'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adpone.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ adapters:
usersync:
cookie-family-name: adpone
redirect:
url: https://usersync.adpone.com/csync?redir={{redirect_url}}
url: https://usersync.adpone.com/csync?redir={redirect_url}
support-cors: false
uid-macro: '{uid}'
4 changes: 2 additions & 2 deletions src/main/resources/bidder-config/adprime.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ adapters:
usersync:
cookie-family-name: adprime
iframe:
url: https://sync.adprime.com/pbserverIframe?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&ccpa={{us_privacy}}&gpp={{gpp}}&gpp_sid={{gpp_sid}}&pbserverUrl={{redirect_url}}
url: https://sync.adprime.com/pbserverIframe?gdpr={gdpr}&gdpr_consent={gdpr_consent}&ccpa={us_privacy}&gpp={gpp}&gpp_sid={gpp_sid}&pbserverUrl={redirect_url}
support-cors: false
uid-macro: '[UID]'
redirect:
url: https://sync.adprime.com/pbserver?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&ccpa={{us_privacy}}&gpp={{gpp}}&gpp_sid={{gpp_sid}}&redir={{redirect_url}}
url: https://sync.adprime.com/pbserver?gdpr={gdpr}&gdpr_consent={gdpr_consent}&ccpa={us_privacy}&gpp={gpp}&gpp_sid={gpp_sid}&redir={redirect_url}
support-cors: false
uid-macro: '[UID]'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adquery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ adapters:
usersync:
cookie-family-name: adquery
iframe:
url: https://api.adquery.io/storage?gdpr={{gdpr}}&consent={{gdpr_consent}}&ccpa_consent={{us_privacy}}&redirect={{redirect_url}}
url: https://api.adquery.io/storage?gdpr={gdpr}&consent={gdpr_consent}&ccpa_consent={us_privacy}&redirect={redirect_url}
support-cors: false
uid-macro: '$UID'
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/adtonos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ adapters:
usersync:
cookie-family-name: adtonos
redirect:
url: https://play.adtonos.com/redir?to={{redirect_url}}
url: https://play.adtonos.com/redir?to={redirect_url}
support-cors: false
uid-macro: '@UUID@'
4 changes: 2 additions & 2 deletions src/main/resources/bidder-config/aduptech.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ adapters:
usersync:
cookie-family-name: aduptech
iframe:
url: https://rtb.d.adup-tech.com/service/sync?iframe=1&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&redirect={{redirect_url}}
url: https://rtb.d.adup-tech.com/service/sync?iframe=1&gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&redirect={redirect_url}
support-cors: false
uid-macro: '[UID]'
redirect:
url: https://rtb.d.adup-tech.com/service/sync?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&redirect={{redirect_url}}
url: https://rtb.d.adup-tech.com/service/sync?gdpr={gdpr}&gdpr_consent={gdpr_consent}&us_privacy={us_privacy}&redirect={redirect_url}
support-cors: false
uid-macro: '[UID]'
target-currency: "EUR"
2 changes: 1 addition & 1 deletion src/main/resources/bidder-config/advangelists.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ adapters:
usersync:
cookie-family-name: advangelists
iframe:
url: https://nep.advangelists.com/xp/user-sync?acctid={aid}&&redirect={{redirect_url}}
url: https://nep.advangelists.com/xp/user-sync?acctid=%7Baid%7D&&redirect={redirect_url}
support-cors: false
uid-macro: '$UID'
Loading
Loading