Skip to content

Commit

Permalink
Merged main
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasm-ttd committed Dec 10, 2024
2 parents 15a9c96 + 1b72e55 commit 3c269f8
Show file tree
Hide file tree
Showing 28 changed files with 120 additions and 270 deletions.
3 changes: 0 additions & 3 deletions .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,3 @@

# https://thetradedesk.atlassian.net/browse/UID2-4460
CVE-2024-47535

# https://thetradedesk.atlassian.net/browse/UID2-4461
CVE-2024-7254
1 change: 0 additions & 1 deletion conf/docker-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"storage_mock": true,
"refresh_token_expires_after_seconds": 86400,
"refresh_identity_token_after_seconds": 900,
"advertising_token_v3": false,
"refresh_token_v3": false,
"identity_v3": false,
"identity_scope": "uid2",
Expand Down
3 changes: 0 additions & 3 deletions conf/local-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
"identity_token_expires_after_seconds": 3600,
"refresh_token_expires_after_seconds": 86400,
"refresh_identity_token_after_seconds": 900,
"advertising_token_v3": false,
"advertising_token_v4_percentage": 0,
"site_ids_using_v4_tokens": "",
"refresh_token_v3": false,
"identity_v3": false,
"identity_scope": "uid2",
Expand Down
1 change: 0 additions & 1 deletion conf/local-e2e-docker-private-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"identity_token_expires_after_seconds": 3600,
"refresh_token_expires_after_seconds": 86400,
"refresh_identity_token_after_seconds": 900,
"advertising_token_v3": false,
"refresh_token_v3": true,
"identity_v3": false,
"identity_scope": "uid2",
Expand Down
1 change: 0 additions & 1 deletion conf/local-e2e-docker-public-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"identity_token_expires_after_seconds": 3600,
"refresh_token_expires_after_seconds": 86400,
"refresh_identity_token_after_seconds": 900,
"advertising_token_v3": false,
"refresh_token_v3": true,
"identity_v3": false,
"identity_scope": "uid2",
Expand Down
1 change: 0 additions & 1 deletion conf/local-e2e-private-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"identity_token_expires_after_seconds": 3600,
"refresh_token_expires_after_seconds": 86400,
"refresh_identity_token_after_seconds": 900,
"advertising_token_v3": false,
"refresh_token_v3": true,
"identity_v3": false,
"identity_scope": "uid2",
Expand Down
1 change: 0 additions & 1 deletion conf/local-e2e-public-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"identity_token_expires_after_seconds": 3600,
"refresh_token_expires_after_seconds": 86400,
"refresh_identity_token_after_seconds": 900,
"advertising_token_v3": false,
"refresh_token_v3": true,
"identity_v3": false,
"identity_scope": "uid2",
Expand Down
1 change: 0 additions & 1 deletion conf/validator-latest-e2e-docker-public-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"identity_token_expires_after_seconds": 3600,
"refresh_token_expires_after_seconds": 86400,
"refresh_identity_token_after_seconds": 900,
"advertising_token_v3": false,
"refresh_token_v3": true,
"identity_v3": false,
"identity_scope": "uid2",
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

<groupId>com.uid2</groupId>
<artifactId>uid2-operator</artifactId>
<version>5.42.18-alpha-85-SNAPSHOT</version>
<version>5.43.4</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<vertx.version>4.5.3</vertx.version>
<vertx.version>4.5.11</vertx.version>
<vertx-maven-plugin.version>1.0.22</vertx-maven-plugin.version>
<junit-jupiter.version>5.11.2</junit-jupiter.version>
<junit-vintage.version>5.11.2</junit-vintage.version>
Expand All @@ -22,7 +22,7 @@
<enclave-aws.version>2.1.0</enclave-aws.version>
<enclave-azure.version>2.1.0</enclave-azure.version>
<enclave-gcp.version>2.1.0</enclave-gcp.version>
<uid2-shared.version>7.20.4</uid2-shared.version>
<uid2-shared.version>8.0.9</uid2-shared.version>
<image.version>${project.version}</image.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
Expand Down
2 changes: 0 additions & 2 deletions scripts/aws/conf/default-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,5 @@
"failure_shutdown_wait_hours": 120,
"sharing_token_expiry_seconds": 2592000,
"validate_service_links": false,
"advertising_token_v4_percentage": 100,
"site_ids_using_v4_tokens": "",
"operator_type": "private"
}
1 change: 0 additions & 1 deletion scripts/aws/conf/prod-euid-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"refresh_identity_token_after_seconds": 3600,
"allow_legacy_api": false,
"identity_scope": "euid",
"advertising_token_v3": true,
"refresh_token_v3": true,
"enable_phone_support": true,
"enable_v1_phone_support": false,
Expand Down
2 changes: 0 additions & 2 deletions scripts/azure-cc/conf/default-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,5 @@
"failure_shutdown_wait_hours": 120,
"sharing_token_expiry_seconds": 2592000,
"validate_service_links": false,
"advertising_token_v4_percentage": 100,
"site_ids_using_v4_tokens": "",
"operator_type": "private"
}
2 changes: 0 additions & 2 deletions scripts/gcp-oidc/conf/default-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,5 @@
"failure_shutdown_wait_hours": 120,
"sharing_token_expiry_seconds": 2592000,
"validate_service_links": false,
"advertising_token_v4_percentage": 100,
"site_ids_using_v4_tokens": "",
"operator_type": "private"
}
2 changes: 1 addition & 1 deletion src/main/java/com/uid2/operator/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ private static Vertx createVertx() {
}

private static void setupMetrics(MicrometerMetricsOptions metricOptions) {
BackendRegistries.setupBackend(metricOptions);
BackendRegistries.setupBackend(metricOptions, null);

MeterRegistry backendRegistry = BackendRegistries.getDefaultNow();
if (backendRegistry instanceof PrometheusMeterRegistry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public static JsonArray parseArray(JsonObject object, String key, RoutingContext
try {
outArray = object.getJsonArray(key);
} catch (ClassCastException e) {
ResponseUtil.ClientError(rc, String.format("%s must be an array", key));
ResponseUtil.LogInfoAndSend400Response(rc, String.format("%s must be an array", key));
return null;
}
return outArray;
Expand Down
91 changes: 43 additions & 48 deletions src/main/java/com/uid2/operator/service/ResponseUtil.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.uid2.operator.service;

import com.uid2.operator.monitoring.TokenResponseStatsCollector;
import com.uid2.operator.vertx.UIDOperatorVerticle;
import com.uid2.shared.model.TokenVersion;
import com.uid2.shared.store.ISiteStore;
import io.vertx.core.http.HttpHeaders;
Expand Down Expand Up @@ -64,19 +63,28 @@ public static void SuccessV2(RoutingContext rc, Object body) {
rc.data().put("response", json);
}

public static void ClientError(RoutingContext rc, String message) {
Warning(ResponseStatus.ClientError, 400, rc, message);
public static void LogInfoAndSend400Response(RoutingContext rc, String message) {
LogInfoAndSendResponse(ResponseStatus.ClientError, 400, rc, message);
}

public static void SendClientErrorResponseAndRecordStats(String errorStatus, int statusCode, RoutingContext rc, String message, Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider, TokenResponseStatsCollector.PlatformType platformType)
{
Warning(errorStatus, statusCode, rc, message);
if (ResponseStatus.ClientError.equals(errorStatus) ||
ResponseStatus.InvalidAppName.equals(errorStatus) ||
ResponseStatus.InvalidHttpOrigin.equals(errorStatus))
{
LogInfoAndSendResponse(errorStatus, statusCode, rc, message);
}
else {
LogWarningAndSendResponse(errorStatus, statusCode, rc, message);
}

recordTokenResponseStats(siteId, endpoint, responseStatus, siteProvider, null, platformType);
}

public static void SendServerErrorResponseAndRecordStats(RoutingContext rc, String message, Integer siteId, TokenResponseStatsCollector.Endpoint endpoint, TokenResponseStatsCollector.ResponseStatus responseStatus, ISiteStore siteProvider, Exception exception, TokenResponseStatsCollector.PlatformType platformType)
{
Error(ResponseStatus.UnknownError, 500, rc, message, exception);
LogErrorAndSendResponse(ResponseStatus.UnknownError, 500, rc, message, exception);
rc.fail(500);
recordTokenResponseStats(siteId, endpoint, responseStatus, siteProvider, null, platformType);
}
Expand All @@ -97,62 +105,40 @@ public static JsonObject Response(String status, String message) {
return json;
}

public static void Error(String errorStatus, int statusCode, RoutingContext rc, String message) {
logError(errorStatus, statusCode, message, new RoutingContextReader(rc), rc.request().remoteAddress().hostAddress());
public static void LogErrorAndSendResponse(String errorStatus, int statusCode, RoutingContext rc, String message) {
String msg = ComposeMessage(errorStatus, statusCode, message, new RoutingContextReader(rc), rc.request().remoteAddress().hostAddress());
LOGGER.error(msg);
final JsonObject json = Response(errorStatus, message);
rc.response().setStatusCode(statusCode).putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.end(json.encode());
}

public static void Error(String errorStatus, int statusCode, RoutingContext rc, String message, Exception exception) {
logError(errorStatus, statusCode, message, new RoutingContextReader(rc), rc.request().remoteAddress().hostAddress(), exception);
public static void LogErrorAndSendResponse(String errorStatus, int statusCode, RoutingContext rc, String message, Exception exception) {
String msg = ComposeMessage(errorStatus, statusCode, message, new RoutingContextReader(rc), rc.request().remoteAddress().hostAddress());
LOGGER.error(msg, exception);
final JsonObject json = Response(errorStatus, message);
rc.response().setStatusCode(statusCode).putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.end(json.encode());
}

public static void Warning(String status, int statusCode, RoutingContext rc, String message) {
logWarning(status, statusCode, message, new RoutingContextReader(rc), rc.request().remoteAddress().hostAddress());
public static void LogInfoAndSendResponse(String status, int statusCode, RoutingContext rc, String message) {
String msg = ComposeMessage(status, statusCode, message, new RoutingContextReader(rc), rc.request().remoteAddress().hostAddress());
LOGGER.info(msg);
final JsonObject json = Response(status, message);
rc.response().setStatusCode(statusCode).putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.end(json.encode());
}

private static void logError(String errorStatus, int statusCode, String message, RoutingContextReader contextReader, String clientAddress) {
JsonObject errorJsonObj = JsonObject.of(
"errorStatus", errorStatus,
"contact", contextReader.getContact(),
"siteId", contextReader.getSiteId(),
"statusCode", statusCode,
"clientAddress", clientAddress,
"message", message
);
final String linkName = contextReader.getLinkName();
if (!linkName.isBlank()) {
errorJsonObj.put(SecureLinkValidatorService.SERVICE_LINK_NAME, linkName);
}
final String serviceName = contextReader.getServiceName();
if (!serviceName.isBlank()) {
errorJsonObj.put(SecureLinkValidatorService.SERVICE_NAME, serviceName);
}
LOGGER.error("Error response to http request. " + errorJsonObj.encode());
}

private static void logError(String errorStatus, int statusCode, String message, RoutingContextReader contextReader, String clientAddress, Exception exception) {
String errorMessage = "Error response to http request. " + JsonObject.of(
"errorStatus", errorStatus,
"contact", contextReader.getContact(),
"siteId", contextReader.getSiteId(),
"path", contextReader.getPath(),
"statusCode", statusCode,
"clientAddress", clientAddress,
"message", message
).encode();
LOGGER.error(errorMessage, exception);
public static void LogWarningAndSendResponse(String status, int statusCode, RoutingContext rc, String message) {
String msg = ComposeMessage(status, statusCode, message, new RoutingContextReader(rc), rc.request().remoteAddress().hostAddress());
LOGGER.warn(msg);
final JsonObject json = Response(status, message);
rc.response().setStatusCode(statusCode).putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.end(json.encode());
}

private static void logWarning(String status, int statusCode, String message, RoutingContextReader contextReader, String clientAddress) {
JsonObject warnMessageJsonObject = JsonObject.of(
private static String ComposeMessage(String status, int statusCode, String message, RoutingContextReader contextReader, String clientAddress) {
JsonObject msgJsonObject = JsonObject.of(
"errorStatus", status,
"contact", contextReader.getContact(),
"siteId", contextReader.getSiteId(),
Expand All @@ -165,14 +151,22 @@ private static void logWarning(String status, int statusCode, String message, Ro
final String origin = contextReader.getOrigin();
if (statusCode >= 400 && statusCode < 500) {
if (referer != null) {
warnMessageJsonObject.put("referer", referer);
msgJsonObject.put("referer", referer);
}
if (origin != null) {
warnMessageJsonObject.put("origin", origin);
msgJsonObject.put("origin", origin);
}
}
String warnMessage = "Warning response to http request. " + warnMessageJsonObject.encode();
LOGGER.warn(warnMessage);

final String linkName = contextReader.getLinkName();
if (!linkName.isBlank()) {
msgJsonObject.put(SecureLinkValidatorService.SERVICE_LINK_NAME, linkName);
}
final String serviceName = contextReader.getServiceName();
if (!serviceName.isBlank()) {
msgJsonObject.put(SecureLinkValidatorService.SERVICE_NAME, serviceName);
}
return "Response to http request. " + msgJsonObject.encode();
}

public static class ResponseStatus {
Expand All @@ -183,6 +177,7 @@ public static class ResponseStatus {
public static final String InvalidToken = "invalid_token";
public static final String ExpiredToken = "expired_token";
public static final String GenericError = "error";
public static final String InvalidClient = "invalid_client";
public static final String UnknownError = "unknown";
public static final String InsufficientUserConsent = "insufficient_user_consent";
public static final String InvalidHttpOrigin = "invalid_http_origin";
Expand Down
17 changes: 0 additions & 17 deletions src/main/java/com/uid2/operator/service/TokenUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,4 @@ public static byte encodeIdentityScope(IdentityScope identityScope) {
public static byte encodeIdentityType(IdentityType identityType) {
return (byte) (identityType.value << 2);
}

public static Set<Integer> getSiteIdsUsingV4Tokens(String siteIdsUsingV4TokensInString) {
String[] siteIdsV4TokensList = siteIdsUsingV4TokensInString.split(",");

Set<Integer> siteIdsV4TokensSet = new HashSet<>();
try {
for (String siteId : siteIdsV4TokensList) {
String siteIdTrimmed = siteId.trim();
if (!siteIdTrimmed.isEmpty()) {
siteIdsV4TokensSet.add(Integer.parseInt(siteIdTrimmed));
}
}
} catch (NumberFormatException ex) {
throw new IllegalArgumentException(String.format("Invalid integer format found in site_ids_using_v4_tokens: %s", siteIdsUsingV4TokensInString));
}
return siteIdsV4TokensSet;
}
}
23 changes: 1 addition & 22 deletions src/main/java/com/uid2/operator/service/UIDOperatorService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.*;

import static com.uid2.operator.IdentityConst.*;
import static com.uid2.operator.service.TokenUtils.getSiteIdsUsingV4Tokens;

public class UIDOperatorService implements IUIDOperatorService {
public static final String IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS = "identity_token_expires_after_seconds";
Expand All @@ -47,9 +46,6 @@ public class UIDOperatorService implements IUIDOperatorService {
private final Duration refreshIdentityAfter;

private final OperatorIdentity operatorIdentity;
protected final TokenVersion tokenVersionToUseIfNotV4;
protected final int advertisingTokenV4Percentage;
protected final Set<Integer> siteIdsUsingV4Tokens;
private final TokenVersion refreshTokenVersion;
private final boolean identityV3Enabled;

Expand Down Expand Up @@ -93,10 +89,6 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv
throw new IllegalStateException(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS + " must be >= " + REFRESH_IDENTITY_TOKEN_AFTER_SECONDS);
}

this.advertisingTokenV4Percentage = config.getInteger("advertising_token_v4_percentage", 0); //0 indicates token v4 will not be used
this.siteIdsUsingV4Tokens = getSiteIdsUsingV4Tokens(config.getString("site_ids_using_v4_tokens", ""));
this.tokenVersionToUseIfNotV4 = config.getBoolean("advertising_token_v3", false) ? TokenVersion.V3 : TokenVersion.V2;

this.refreshTokenVersion = TokenVersion.V3;
this.identityV3Enabled = config.getBoolean("identity_v3", false);
}
Expand Down Expand Up @@ -270,20 +262,7 @@ private RefreshToken createRefreshToken(PublisherIdentity publisherIdentity, Use
}

private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdentity, UserIdentity userIdentity, Instant now) {
TokenVersion tokenVersion;
if (siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) {
tokenVersion = TokenVersion.V4;
} else {
int pseudoRandomNumber = 1;
final var rawUid = userIdentity.id;
if (rawUid.length > 2)
{
int hash = ((rawUid[0] & 0xFF) << 12) | ((rawUid[1] & 0xFF) << 4) | ((rawUid[2] & 0xFF) & 0xF); //using same logic as ModBasedSaltEntryIndexer.getIndex() in uid2-shared
pseudoRandomNumber = (hash % 100) + 1; //1 to 100
}
tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4;
}
return new AdvertisingToken(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, userIdentity);
return new AdvertisingToken(TokenVersion.V4, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, userIdentity);
}

static protected class GlobalOptoutResult {
Expand Down
Loading

0 comments on commit 3c269f8

Please sign in to comment.