Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ipv6 for geo location call if ipv4 is not defined #1256

Merged
merged 6 commits into from
May 18, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.auction.model.AuctionContext;
import org.prebid.server.auction.model.BidderPrivacyResult;
import org.prebid.server.auction.model.IpAddress;
import org.prebid.server.bidder.BidderCatalog;
import org.prebid.server.execution.Timeout;
import org.prebid.server.metric.MetricName;
Expand All @@ -32,7 +34,6 @@
import org.prebid.server.proto.request.CookieSyncRequest;
import org.prebid.server.settings.model.Account;
import org.prebid.server.settings.model.AccountGdprConfig;
import org.prebid.server.util.HttpUtil;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
Expand Down Expand Up @@ -62,6 +63,7 @@ public class PrivacyEnforcementService {
private final BidderCatalog bidderCatalog;
private final PrivacyExtractor privacyExtractor;
private final TcfDefinerService tcfDefinerService;
private final ImplicitParametersExtractor implicitParametersExtractor;
private final IpAddressHelper ipAddressHelper;
private final Metrics metrics;
private final boolean ccpaEnforce;
Expand All @@ -70,6 +72,7 @@ public class PrivacyEnforcementService {
public PrivacyEnforcementService(BidderCatalog bidderCatalog,
PrivacyExtractor privacyExtractor,
TcfDefinerService tcfDefinerService,
ImplicitParametersExtractor implicitParametersExtractor,
IpAddressHelper ipAddressHelper,
Metrics metrics,
boolean ccpaEnforce,
Expand All @@ -78,6 +81,7 @@ public PrivacyEnforcementService(BidderCatalog bidderCatalog,
this.bidderCatalog = Objects.requireNonNull(bidderCatalog);
this.privacyExtractor = Objects.requireNonNull(privacyExtractor);
this.tcfDefinerService = Objects.requireNonNull(tcfDefinerService);
this.implicitParametersExtractor = Objects.requireNonNull(implicitParametersExtractor);
this.ipAddressHelper = Objects.requireNonNull(ipAddressHelper);
this.metrics = Objects.requireNonNull(metrics);
this.ccpaEnforce = ccpaEnforce;
Expand All @@ -94,14 +98,11 @@ public Future<PrivacyContext> contextFromBidRequest(AuctionContext auctionContex
final Privacy privacy = privacyExtractor.validPrivacyFrom(bidRequest, errors);

final Device device = bidRequest.getDevice();
final String ipAddress = device != null ? device.getIp() : null;

final Geo geo = device != null ? device.getGeo() : null;
final String country = geo != null ? geo.getCountry() : null;

final String effectiveIpAddress = isCoppaMaskingRequired(privacy) || isLmtEnabled(device)
? ipAddressHelper.maskIpv4(ipAddress)
: ipAddress;
final String effectiveIpAddress = resolveIpAddress(device, privacy);

final AccountGdprConfig accountGdpr = account.getGdpr();
final String accountId = account.getId();
Expand All @@ -112,11 +113,27 @@ public Future<PrivacyContext> contextFromBidRequest(AuctionContext auctionContex
.map(tcfContext -> PrivacyContext.of(privacy, tcfContext, tcfContext.getIpAddress()));
}

private String resolveIpAddress(Device device, Privacy privacy) {
final boolean shouldBeMasked = isCoppaMaskingRequired(privacy) || isLmtEnabled(device);

final String ipV4Address = device != null ? device.getIp() : null;
if (StringUtils.isNotBlank(ipV4Address)) {
return shouldBeMasked ? ipAddressHelper.maskIpv4(ipV4Address) : ipV4Address;
}

final String ipV6Address = device != null ? device.getIpv6() : null;
if (StringUtils.isNotBlank(ipV6Address)) {
return shouldBeMasked ? ipAddressHelper.anonymizeIpv6(ipV6Address) : ipV6Address;
}

return null;
}

public Future<PrivacyContext> contextFromSetuidRequest(
HttpServerRequest httpRequest, Account account, Timeout timeout) {

final Privacy privacy = privacyExtractor.validPrivacyFromSetuidRequest(httpRequest);
final String ipAddress = HttpUtil.ipFrom(httpRequest);
final String ipAddress = resolveIpFromRequest(httpRequest);
final AccountGdprConfig accountGdpr = account.getGdpr();
final String accountId = account.getId();
final RequestLogInfo requestLogInfo = requestLogInfo(MetricName.setuid, null, accountId);
Expand All @@ -130,7 +147,7 @@ public Future<PrivacyContext> contextFromCookieSyncRequest(
CookieSyncRequest cookieSyncRequest, HttpServerRequest httpRequest, Account account, Timeout timeout) {

final Privacy privacy = privacyExtractor.validPrivacyFrom(cookieSyncRequest);
final String ipAddress = HttpUtil.ipFrom(httpRequest);
final String ipAddress = resolveIpFromRequest(httpRequest);
final AccountGdprConfig accountGdpr = account.getGdpr();
final String accountId = account.getId();
final RequestLogInfo requestLogInfo = requestLogInfo(MetricName.cookiesync, null, accountId);
Expand All @@ -140,6 +157,16 @@ public Future<PrivacyContext> contextFromCookieSyncRequest(
.map(tcfContext -> PrivacyContext.of(privacy, tcfContext));
}

private String resolveIpFromRequest(HttpServerRequest request) {
final List<String> requestIps = implicitParametersExtractor.ipFrom(request);
return requestIps.stream()
.map(ipAddressHelper::toIpAddress)
.filter(Objects::nonNull)
.map(IpAddress::getIp)
.findFirst()
.orElse(null);
}

private static RequestLogInfo requestLogInfo(MetricName requestType, BidRequest bidRequest, String accountId) {
if (Objects.equals(requestType, MetricName.openrtb2web)) {
final Site site = bidRequest.getSite();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.auction.IpAddressHelper;
import org.prebid.server.auction.model.IpAddress;
import org.prebid.server.bidder.BidderCatalog;
import org.prebid.server.execution.Timeout;
import org.prebid.server.geolocation.GeoLocationService;
Expand Down Expand Up @@ -83,6 +84,9 @@ public TcfDefinerService(GdprConfig gdprConfig,
this.metrics = Objects.requireNonNull(metrics);
}

/**
* Used for auctions.
*/
public Future<TcfContext> resolveTcfContext(Privacy privacy,
String country,
String ipAddress,
Expand All @@ -99,6 +103,9 @@ public Future<TcfContext> resolveTcfContext(Privacy privacy,
.map(this::updateTcfGeoMetrics);
}

/**
* Used for cookie sync and setuid.
*/
public Future<TcfContext> resolveTcfContext(Privacy privacy,
String ipAddress,
AccountGdprConfig accountGdprConfig,
Expand Down Expand Up @@ -234,7 +241,18 @@ private Future<TcfContext> toTcfContext(Privacy privacy,
}

private String maybeMaskIp(String ipAddress, TCString consent) {
return shouldMaskIp(consent) ? ipAddressHelper.maskIpv4(ipAddress) : ipAddress;
if (!shouldMaskIp(consent)) {
return ipAddress;
}

final IpAddress ip = ipAddressHelper.toIpAddress(ipAddress);
if (ip == null) {
return ipAddress;
}

return ip.getVersion() == IpAddress.IP.v4
? ipAddressHelper.maskIpv4(ipAddress)
: ipAddressHelper.anonymizeIpv6(ipAddress);
}

private static boolean shouldMaskIp(TCString consent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,13 +585,21 @@ PrivacyEnforcementService privacyEnforcementService(
BidderCatalog bidderCatalog,
PrivacyExtractor privacyExtractor,
TcfDefinerService tcfDefinerService,
ImplicitParametersExtractor implicitParametersExtractor,
IpAddressHelper ipAddressHelper,
Metrics metrics,
@Value("${ccpa.enforce}") boolean ccpaEnforce,
@Value("${lmt.enforce}") boolean lmtEnforce) {

return new PrivacyEnforcementService(
bidderCatalog, privacyExtractor, tcfDefinerService, ipAddressHelper, metrics, ccpaEnforce, lmtEnforce);
bidderCatalog,
privacyExtractor,
tcfDefinerService,
implicitParametersExtractor,
ipAddressHelper,
metrics,
ccpaEnforce,
lmtEnforce);
}

@Bean
Expand Down
20 changes: 1 addition & 19 deletions src/main/java/org/prebid/server/util/HttpUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.vertx.core.MultiMap;
import io.vertx.core.http.Cookie;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.RoutingContext;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -109,23 +108,6 @@ public static void addHeaderIfValueIsNotEmpty(MultiMap headers, CharSequence hea
}
}

/**
* Determines IP-Address by checking "X-Forwarded-For", "X-Real-IP" http headers or remote host address
* if both are empty.
*/
public static String ipFrom(HttpServerRequest request) {
// X-Forwarded-For: client1, proxy1, proxy2
String ip = StringUtils.trimToNull(
StringUtils.substringBefore(request.headers().get("X-Forwarded-For"), ","));
if (ip == null) {
ip = StringUtils.trimToNull(request.headers().get("X-Real-IP"));
}
if (ip == null) {
ip = StringUtils.trimToNull(request.remoteAddress().host());
}
return ip;
}

public static String getDomainFromUrl(String url) {
if (StringUtils.isBlank(url)) {
return null;
Expand All @@ -147,7 +129,7 @@ public static String toSetCookieHeaderValue(Cookie cookie) {
}

/**
* Sends HTTP response according to the given status and body
* Sends HTTP response according to the given status and body.
*/
public static void respondWith(RoutingContext context, HttpResponseStatus status, String body) {
final HttpServerResponse response = context.response().setStatusCode(status.code());
Expand Down
Loading