From 1693ea8ced45349cf0afabd9a122a0c10c0fc59f Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Thu, 10 Oct 2024 17:08:06 +1100 Subject: [PATCH 01/61] Renamed IdentityToken class and variables to Identity as it's a set of variables which don't just include tokens --- .../{IdentityTokens.java => Identity.java} | 8 +- .../uid2/operator/model/MappedIdentity.java | 1 + .../uid2/operator/model/RefreshResponse.java | 28 ++-- .../TokenResponseStatsCollector.java | 8 +- .../service/EncryptedTokenEncoder.java | 4 +- .../uid2/operator/service/ITokenEncoder.java | 4 +- .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 10 +- .../operator/vertx/UIDOperatorVerticle.java | 30 ++-- .../uid2/operator/UIDOperatorServiceTest.java | 138 +++++++++--------- .../benchmark/TokenEndecBenchmark.java | 10 +- 11 files changed, 122 insertions(+), 121 deletions(-) rename src/main/java/com/uid2/operator/model/{IdentityTokens.java => Identity.java} (77%) diff --git a/src/main/java/com/uid2/operator/model/IdentityTokens.java b/src/main/java/com/uid2/operator/model/Identity.java similarity index 77% rename from src/main/java/com/uid2/operator/model/IdentityTokens.java rename to src/main/java/com/uid2/operator/model/Identity.java index 76dd2c4d7..f94ab15b2 100644 --- a/src/main/java/com/uid2/operator/model/IdentityTokens.java +++ b/src/main/java/com/uid2/operator/model/Identity.java @@ -4,8 +4,8 @@ import java.time.Instant; -public class IdentityTokens { - public static IdentityTokens LogoutToken = new IdentityTokens("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); +public class Identity { + public static Identity LogoutToken = new Identity("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; private final TokenVersion advertisingTokenVersion; private final String refreshToken; @@ -13,8 +13,8 @@ public class IdentityTokens { private final Instant refreshExpires; private final Instant refreshFrom; - public IdentityTokens(String advertisingToken, TokenVersion advertisingTokenVersion, String refreshToken, - Instant identityExpires, Instant refreshExpires, Instant refreshFrom) { + public Identity(String advertisingToken, TokenVersion advertisingTokenVersion, String refreshToken, + Instant identityExpires, Instant refreshExpires, Instant refreshFrom) { this.advertisingToken = advertisingToken; this.advertisingTokenVersion = advertisingTokenVersion; this.refreshToken = refreshToken; diff --git a/src/main/java/com/uid2/operator/model/MappedIdentity.java b/src/main/java/com/uid2/operator/model/MappedIdentity.java index dfa2899f4..f7d505fcf 100644 --- a/src/main/java/com/uid2/operator/model/MappedIdentity.java +++ b/src/main/java/com/uid2/operator/model/MappedIdentity.java @@ -2,6 +2,7 @@ public class MappedIdentity { public static MappedIdentity LogoutIdentity = new MappedIdentity(new byte[33], ""); + // AdvertisingId is the raw UID public final byte[] advertisingId; public final String bucketId; diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index fbe41f96b..586d4f274 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -4,37 +4,37 @@ public class RefreshResponse { - public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, IdentityTokens.LogoutToken); - public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityTokens.LogoutToken); - public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityTokens.LogoutToken); - public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityTokens.LogoutToken); - public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityTokens.LogoutToken); + public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, Identity.LogoutToken); + public static RefreshResponse Optout = new RefreshResponse(Status.Optout, Identity.LogoutToken); + public static RefreshResponse Expired = new RefreshResponse(Status.Expired, Identity.LogoutToken); + public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, Identity.LogoutToken); + public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, Identity.LogoutToken); private final Status status; - private final IdentityTokens tokens; + private final Identity identity; private final Duration durationSinceLastRefresh; private final boolean isCstg; - private RefreshResponse(Status status, IdentityTokens tokens, Duration durationSinceLastRefresh, boolean isCstg) { + private RefreshResponse(Status status, Identity identity, Duration durationSinceLastRefresh, boolean isCstg) { this.status = status; - this.tokens = tokens; + this.identity = identity; this.durationSinceLastRefresh = durationSinceLastRefresh; this.isCstg = isCstg; } - private RefreshResponse(Status status, IdentityTokens tokens) { - this(status, tokens, null, false); + private RefreshResponse(Status status, Identity identity) { + this(status, identity, null, false); } - public static RefreshResponse createRefreshedResponse(IdentityTokens tokens, Duration durationSinceLastRefresh, boolean isCstg) { - return new RefreshResponse(Status.Refreshed, tokens, durationSinceLastRefresh, isCstg); + public static RefreshResponse createRefreshedResponse(Identity identity, Duration durationSinceLastRefresh, boolean isCstg) { + return new RefreshResponse(Status.Refreshed, identity, durationSinceLastRefresh, isCstg); } public Status getStatus() { return status; } - public IdentityTokens getTokens() { - return tokens; + public Identity getIdentity() { + return identity; } public Duration getDurationSinceLastRefresh() { diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index a61446aa9..b2e7e56ec 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -72,14 +72,14 @@ private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoin public static void recordRefresh(ISiteStore siteStore, Integer siteId, Endpoint endpoint, RefreshResponse refreshResponse, PlatformType platformType) { if (!refreshResponse.isRefreshed()) { if (refreshResponse.isOptOut() || refreshResponse.isDeprecated()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } else if (refreshResponse.isInvalidToken()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } else if (refreshResponse.isExpired()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } } else { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getTokens().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } } } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 278b4145c..81a6fd479 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -337,12 +337,12 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi } @Override - public IdentityTokens encode(AdvertisingToken advertisingToken, RefreshToken refreshToken, Instant refreshFrom, Instant asOf) { + public Identity encode(AdvertisingToken advertisingToken, RefreshToken refreshToken, Instant refreshFrom, Instant asOf) { final byte[] advertisingTokenBytes = encode(advertisingToken, asOf); final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingToken.version); - return new IdentityTokens( + return new Identity( base64AdvertisingToken, advertisingToken.version, EncodingUtils.toBase64String(encode(refreshToken, asOf)), diff --git a/src/main/java/com/uid2/operator/service/ITokenEncoder.java b/src/main/java/com/uid2/operator/service/ITokenEncoder.java index 71ab4c5f2..c0303247e 100644 --- a/src/main/java/com/uid2/operator/service/ITokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/ITokenEncoder.java @@ -1,13 +1,13 @@ package com.uid2.operator.service; import com.uid2.operator.model.AdvertisingToken; -import com.uid2.operator.model.IdentityTokens; +import com.uid2.operator.model.Identity; import com.uid2.operator.model.RefreshToken; import java.time.Instant; public interface ITokenEncoder { - IdentityTokens encode(AdvertisingToken advertisingToken, RefreshToken refreshToken, Instant refreshFrom, Instant asOf); + Identity encode(AdvertisingToken advertisingToken, RefreshToken refreshToken, Instant refreshFrom, Instant asOf); AdvertisingToken decodeAdvertisingToken(String base64String); diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index c64e499fe..494fc531a 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -11,7 +11,7 @@ public interface IUIDOperatorService { - IdentityTokens generateIdentity(IdentityRequest request); + Identity generateIdentity(IdentityRequest request); RefreshResponse refreshIdentity(RefreshToken refreshToken); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 99d769e17..ecc5eebe2 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -102,7 +102,7 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv } @Override - public IdentityTokens generateIdentity(IdentityRequest request) { + public Identity generateIdentity(IdentityRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); final byte[] firstLevelHash = getFirstLevelHash(request.userIdentity.id, now); final UserIdentity firstLevelHashIdentity = new UserIdentity( @@ -110,7 +110,7 @@ public IdentityTokens generateIdentity(IdentityRequest request) { request.userIdentity.establishedAt, request.userIdentity.refreshedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return IdentityTokens.LogoutToken; + return Identity.LogoutToken; } else { return generateIdentity(request.publisherIdentity, firstLevelHashIdentity); } @@ -143,9 +143,9 @@ public RefreshResponse refreshIdentity(RefreshToken token) { final Duration durationSinceLastRefresh = Duration.between(token.createdAt, now); if (!optedOut) { - IdentityTokens identityTokens = this.generateIdentity(token.publisherIdentity, token.userIdentity); + Identity identity = this.generateIdentity(token.publisherIdentity, token.userIdentity); - return RefreshResponse.createRefreshedResponse(identityTokens, durationSinceLastRefresh, isCstg); + return RefreshResponse.createRefreshedResponse(identity, durationSinceLastRefresh, isCstg); } else { return RefreshResponse.Optout; } @@ -244,7 +244,7 @@ private MappedIdentity getAdvertisingId(UserIdentity firstLevelHashIdentity, Ins rotatingSalt.getHashedId()); } - private IdentityTokens generateIdentity(PublisherIdentity publisherIdentity, UserIdentity firstLevelHashIdentity) { + private Identity generateIdentity(PublisherIdentity publisherIdentity, UserIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); final MappedIdentity mappedIdentity = getAdvertisingId(firstLevelHashIdentity, nowUtc); diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 210b08571..58a88e01a 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -2,6 +2,7 @@ import com.uid2.operator.Const; import com.uid2.operator.model.*; +import com.uid2.operator.model.Identity; import com.uid2.operator.model.IdentityScope; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.StatsCollectorHandler; @@ -45,7 +46,6 @@ import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.AllowForwardHeaders; -import io.vertx.ext.web.Route; import io.vertx.ext.web.Router; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.handler.BodyHandler; @@ -458,9 +458,9 @@ else if(emailHash != null) { privacyBits.setLegacyBit(); privacyBits.setClientSideTokenGenerate(); - IdentityTokens identityTokens; + Identity identity; try { - identityTokens = this.idService.generateIdentity( + identity = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), input.toUserIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), @@ -472,12 +472,12 @@ else if(emailHash != null) { JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; - if (identityTokens.isEmptyToken()) { + if (identity.isEmptyToken()) { response = ResponseUtil.SuccessNoBodyV2(ResponseStatus.OptOut); responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } else { //user not opted out and already generated valid identity token - response = ResponseUtil.SuccessV2(toJsonV1(identityTokens)); + response = ResponseUtil.SuccessV2(toJsonV1(identity)); } //if returning an optout token or a successful identity token created originally if (responseStatus == TokenResponseStatsCollector.ResponseStatus.Success) { @@ -485,7 +485,7 @@ else if(emailHash != null) { } final byte[] encryptedResponse = AesGcm.encrypt(response.toBuffer().getBytes(), sharedSecret); rc.response().setStatusCode(200).end(Buffer.buffer(Unpooled.wrappedBuffer(Base64.getEncoder().encode(encryptedResponse)))); - recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identityTokens.getAdvertisingTokenVersion(), platformType); + recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identity.getAdvertisingTokenVersion(), platformType); } private boolean hasValidOriginOrAppName(RoutingContext rc, CstgRequest request, ClientSideKeypair keypair, TokenResponseStatsCollector.PlatformType platformType) { @@ -823,7 +823,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } } else { - ResponseUtil.Success(rc, toJsonV1(r.getTokens())); + ResponseUtil.Success(rc, toJsonV1(r.getIdentity())); this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } @@ -857,7 +857,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } } else { - ResponseUtil.SuccessV2(rc, toJsonV1(r.getTokens())); + ResponseUtil.SuccessV2(rc, toJsonV1(r.getIdentity())); this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, r, platformType); @@ -935,7 +935,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { if (!checkForInvalidTokenInput(input, rc)) { return; } else { - final IdentityTokens t = this.idService.generateIdentity( + final Identity t = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), input.toUserIdentity(this.identityScope, 1, Instant.now()), @@ -991,7 +991,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { return; } - final IdentityTokens t = this.idService.generateIdentity( + final Identity t = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), input.toUserIdentity(this.identityScope, 1, Instant.now()), @@ -1007,7 +1007,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { pb.setLegacyBit(); pb.setClientSideTokenGenerateOptout(); - final IdentityTokens optOutTokens = this.idService.generateIdentity( + final Identity optOutTokens = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), optOutTokenInput.toUserIdentity(this.identityScope, pb.getAsInt(), Instant.now()), @@ -1047,7 +1047,7 @@ else if (!input.isValid()) { try { siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); - final IdentityTokens t = this.idService.generateIdentity( + final Identity t = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), input.toUserIdentity(this.identityScope, 1, Instant.now()), @@ -1074,7 +1074,7 @@ private void handleTokenRefresh(RoutingContext rc) { try { final RefreshResponse r = this.refreshIdentity(rc, tokenList.get(0)); - sendJsonResponse(rc, toJson(r.getTokens())); + sendJsonResponse(rc, toJson(r.getIdentity())); siteId = rc.get(Const.RoutingContextData.SiteId); if (r.isRefreshed()) { @@ -1984,7 +1984,7 @@ private TransparentConsentParseResult getUserConsentV2(JsonObject req) { } } - private JsonObject toJsonV1(IdentityTokens t) { + private JsonObject toJsonV1(Identity t) { final JsonObject json = new JsonObject(); json.put("advertising_token", t.getAdvertisingToken()); json.put("refresh_token", t.getRefreshToken()); @@ -2038,7 +2038,7 @@ private static JsonObject toJson(KeysetKey key) { return json; } - private JsonObject toJson(IdentityTokens t) { + private JsonObject toJson(Identity t) { final JsonObject json = new JsonObject(); json.put("advertisement_token", t.getAdvertisingToken()); json.put("advertising_token", t.getAdvertisingToken()); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 79a8a104b..e47f4d4a7 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -154,17 +154,17 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { createUserIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), OptoutCheckPolicy.DoNotRespect ); - final IdentityTokens tokens = uid2Service.generateIdentity(identityRequest); + final Identity identity = uid2Service.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); + assertNotNull(identity); - UIDOperatorVerticleTest.validateAdvertisingToken(tokens.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(tokens.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); + UIDOperatorVerticleTest.validateAdvertisingToken(identity.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(identity.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.userIdentity, advertisingToken.userIdentity); - RefreshToken refreshToken = tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + RefreshToken refreshToken = tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); assertEquals(this.now, refreshToken.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, refreshToken.publisherIdentity.siteId); @@ -178,16 +178,16 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(refreshResponse); assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); - assertNotNull(refreshResponse.getTokens()); + assertNotNull(refreshResponse.getIdentity()); - UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingToken advertisingToken2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getTokens().getAdvertisingToken()); + UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + AdvertisingToken advertisingToken2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingToken.userIdentity, advertisingToken2.userIdentity); assertArrayEquals(advertisingToken.userIdentity.id, advertisingToken2.userIdentity.id); - RefreshToken refreshToken2 = tokenEncoder.decodeRefreshToken(refreshResponse.getTokens().getRefreshToken()); + RefreshToken refreshToken2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentity().getRefreshToken()); assertEquals(this.now, refreshToken2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken2.expiresAt); assertEquals(refreshToken.publisherIdentity.siteId, refreshToken2.publisherIdentity.siteId); @@ -204,13 +204,13 @@ public void testTestOptOutKey_DoNotRespectOptout() { inputVal.toUserIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.DoNotRespect ); - final IdentityTokens tokens = uid2Service.generateIdentity(identityRequest); + final Identity identity = uid2Service.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); - assertFalse(tokens.isEmptyToken()); + assertNotNull(identity); + assertFalse(identity.isEmptyToken()); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshToken)); } @@ -223,8 +223,8 @@ public void testTestOptOutKey_RespectOptout() { inputVal.toUserIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.RespectOptOut ); - final IdentityTokens tokens = uid2Service.generateIdentity(identityRequest); - assertTrue(tokens.isEmptyToken()); + final Identity identity = uid2Service.generateIdentity(identityRequest); + assertTrue(identity.isEmptyToken()); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); } @@ -239,12 +239,12 @@ public void testTestOptOutKeyIdentityScopeMismatch() { inputVal.toUserIdentity(IdentityScope.EUID, 0, this.now), OptoutCheckPolicy.DoNotRespect ); - final IdentityTokens tokens = euidService.generateIdentity(identityRequest); + final Identity identity = euidService.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); + assertNotNull(identity); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshToken)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -255,8 +255,8 @@ public void testTestOptOutKeyIdentityScopeMismatch() { "Email,test@example.com,EUID", "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) - public void testGenerateTokenForOptOutUser(IdentityType type, String identity, IdentityScope scope) { - final UserIdentity userIdentity = createUserIdentity(identity, scope, type); + public void testGenerateTokenForOptOutUser(IdentityType type, String id, IdentityScope scope) { + final UserIdentity userIdentity = createUserIdentity(id, scope, type); final IdentityRequest identityRequestForceGenerate = new IdentityRequest( new PublisherIdentity(123, 124, 125), @@ -272,31 +272,31 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String identity, I when(optOutStore.getLatestEntry(any(UserIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final IdentityTokens tokens; + final Identity identity; final AdvertisingToken advertisingToken; - final IdentityTokens tokensAfterOptOut; + final Identity identityAfterOptOut; if (scope == IdentityScope.UID2) { - tokens = uid2Service.generateIdentity(identityRequestForceGenerate); + identity = uid2Service.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); - tokensAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); + identityAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); } else { - tokens = euidService.generateIdentity(identityRequestForceGenerate); + identity = euidService.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); - tokensAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); + identityAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); + assertNotNull(identity); assertNotNull(advertisingToken.userIdentity); - assertNotNull(tokensAfterOptOut); - assertTrue(tokensAfterOptOut.getAdvertisingToken() == null || tokensAfterOptOut.getAdvertisingToken().isEmpty()); + assertNotNull(identityAfterOptOut); + assertTrue(identityAfterOptOut.getAdvertisingToken() == null || identityAfterOptOut.getAdvertisingToken().isEmpty()); } @@ -398,16 +398,16 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i // identity has no optout record, ensure generate still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - IdentityTokens tokens; + Identity identity; if(scope == IdentityScope.EUID) { - tokens = euidService.generateIdentity(identityRequest); + identity = euidService.generateIdentity(identityRequest); } else { - tokens = uid2Service.generateIdentity(identityRequest); + identity = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertEquals(tokens, IdentityTokens.LogoutToken); + assertEquals(identity, Identity.LogoutToken); } @ParameterizedTest @@ -461,22 +461,22 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id OptoutCheckPolicy.DoNotRespect ); - IdentityTokens tokens; + Identity identity; if(scope == IdentityScope.EUID) { - tokens = euidService.generateIdentity(identityRequest); + identity = euidService.generateIdentity(identityRequest); } else { - tokens = uid2Service.generateIdentity(identityRequest); + identity = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); - assertNotEquals(IdentityTokens.LogoutToken, tokens); + assertNotNull(identity); + assertNotEquals(Identity.LogoutToken, identity); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -503,22 +503,22 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String // identity has optout record, ensure still generates when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - IdentityTokens tokens; + Identity identity; if(scope == IdentityScope.EUID) { - tokens = euidService.generateIdentity(identityRequest); + identity = euidService.generateIdentity(identityRequest); } else { - tokens = uid2Service.generateIdentity(identityRequest); + identity = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); - assertNotEquals(IdentityTokens.LogoutToken, tokens); + assertNotNull(identity); + assertNotEquals(Identity.LogoutToken, identity); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -578,19 +578,19 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, // all identities have optout records, ensure validate identities still get generated when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - IdentityTokens tokens; + Identity identity; AdvertisingToken advertisingToken; if (scope == IdentityScope.EUID) { - tokens = euidService.generateIdentity(identityRequest); + identity = euidService.generateIdentity(identityRequest); } else { - tokens = uid2Service.generateIdentity(identityRequest); + identity = uid2Service.generateIdentity(identityRequest); } - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(tokens); - assertNotEquals(IdentityTokens.LogoutToken, tokens); + assertNotNull(identity); + assertNotEquals(Identity.LogoutToken, identity); assertNotNull(advertisingToken.userIdentity); } @@ -642,22 +642,22 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop inputVal.toUserIdentity(scope, 0, this.now), OptoutCheckPolicy.DoNotRespect ); - IdentityTokens tokens; + Identity identity; if(scope == IdentityScope.EUID) { - tokens = euidService.generateIdentity(identityRequest); + identity = euidService.generateIdentity(identityRequest); } else { - tokens = uid2Service.generateIdentity(identityRequest); + identity = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotEquals(tokens, IdentityTokens.LogoutToken); - assertNotNull(tokens); + assertNotEquals(identity, Identity.LogoutToken); + assertNotNull(identity); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); assertTrue(refreshResponse.isRefreshed()); - assertNotNull(refreshResponse.getTokens()); + assertNotNull(refreshResponse.getIdentity()); assertNotEquals(RefreshResponse.Optout, refreshResponse); } @@ -703,30 +703,30 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toUserIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut); - IdentityTokens tokens; + Identity identity; AdvertisingToken advertisingToken; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - tokens = euidService.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.EUID, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); + identity = euidService.generateIdentity(identityRequest); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); } else { - tokens = uid2Service.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, tokens.getAdvertisingToken(), IdentityScope.UID2, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); + identity = uid2Service.generateIdentity(identityRequest); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(tokens); - assertNotEquals(IdentityTokens.LogoutToken, tokens); + assertNotNull(identity); + assertNotEquals(Identity.LogoutToken, identity); assertNotNull(advertisingToken.userIdentity); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(tokens.getRefreshToken()); + final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertTrue(refreshResponse.isRefreshed()); - assertNotNull(refreshResponse.getTokens()); + assertNotNull(refreshResponse.getIdentity()); assertNotEquals(RefreshResponse.Optout, refreshResponse); final MapRequest mapRequest = new MapRequest( diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index aaa821db9..8932b414c 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -16,7 +16,7 @@ public class TokenEndecBenchmark { private static final UserIdentity[] userIdentities; private static final PublisherIdentity publisher; private static final EncryptedTokenEncoder encoder; - private static final IdentityTokens[] generatedTokens; + private static final Identity[] generatedTokens; private static int idx = 0; static { @@ -34,8 +34,8 @@ public class TokenEndecBenchmark { } } - static IdentityTokens[] createAdvertisingTokens() { - List tokens = new ArrayList<>(); + static Identity[] createAdvertisingTokens() { + List tokens = new ArrayList<>(); for (int i = 0; i < userIdentities.length; i++) { tokens.add( uidService.generateIdentity(new IdentityRequest( @@ -43,12 +43,12 @@ static IdentityTokens[] createAdvertisingTokens() { userIdentities[i], OptoutCheckPolicy.DoNotRespect))); } - return tokens.toArray(new IdentityTokens[tokens.size()]); + return tokens.toArray(new Identity[tokens.size()]); } @Benchmark @BenchmarkMode(Mode.Throughput) - public IdentityTokens TokenGenerationBenchmark() { + public Identity TokenGenerationBenchmark() { return uidService.generateIdentity(new IdentityRequest( publisher, userIdentities[(idx++) & 65535], From 14fd73381c7dfa85b0669b5ddcf6808f5b26565a Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Thu, 10 Oct 2024 17:38:04 +1100 Subject: [PATCH 02/61] Renamed Identity.LogoutToken to InvalidIdentity and added some comments for clarity --- src/main/java/com/uid2/operator/IdentityConst.java | 5 ++++- src/main/java/com/uid2/operator/model/Identity.java | 2 +- .../com/uid2/operator/model/RefreshResponse.java | 10 +++++----- .../uid2/operator/service/UIDOperatorService.java | 2 +- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 3 ++- .../com/uid2/operator/UIDOperatorServiceTest.java | 12 ++++++------ 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/uid2/operator/IdentityConst.java b/src/main/java/com/uid2/operator/IdentityConst.java index ae1ad6974..0263d4e76 100644 --- a/src/main/java/com/uid2/operator/IdentityConst.java +++ b/src/main/java/com/uid2/operator/IdentityConst.java @@ -3,15 +3,18 @@ import com.uid2.operator.service.EncodingUtils; public class IdentityConst { - public static final String OptOutTokenIdentityForEmail = "optout@unifiedid.com"; public static final String OptOutTokenIdentityForPhone = "+00000000001"; + public static final String ValidateIdentityForEmail = "validate@example.com"; public static final String ValidateIdentityForPhone = "+12345678901"; public static final byte[] ValidateIdentityForEmailHash = EncodingUtils.getSha256Bytes(IdentityConst.ValidateIdentityForEmail); public static final byte[] ValidateIdentityForPhoneHash = EncodingUtils.getSha256Bytes(IdentityConst.ValidateIdentityForPhone); + + // DIIs to use when you want to generate a optout response in token generation or identity map public static final String OptOutIdentityForEmail = "optout@example.com"; public static final String OptOutIdentityForPhone = "+00000000000"; + public static final String RefreshOptOutIdentityForEmail = "refresh-optout@example.com"; public static final String RefreshOptOutIdentityForPhone = "+00000000002"; diff --git a/src/main/java/com/uid2/operator/model/Identity.java b/src/main/java/com/uid2/operator/model/Identity.java index f94ab15b2..fa12d7f64 100644 --- a/src/main/java/com/uid2/operator/model/Identity.java +++ b/src/main/java/com/uid2/operator/model/Identity.java @@ -5,7 +5,7 @@ import java.time.Instant; public class Identity { - public static Identity LogoutToken = new Identity("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); + public static Identity InvalidIdentity = new Identity("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; private final TokenVersion advertisingTokenVersion; private final String refreshToken; diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index 586d4f274..0a62b4655 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -4,11 +4,11 @@ public class RefreshResponse { - public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, Identity.LogoutToken); - public static RefreshResponse Optout = new RefreshResponse(Status.Optout, Identity.LogoutToken); - public static RefreshResponse Expired = new RefreshResponse(Status.Expired, Identity.LogoutToken); - public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, Identity.LogoutToken); - public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, Identity.LogoutToken); + public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, Identity.InvalidIdentity); + public static RefreshResponse Optout = new RefreshResponse(Status.Optout, Identity.InvalidIdentity); + public static RefreshResponse Expired = new RefreshResponse(Status.Expired, Identity.InvalidIdentity); + public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, Identity.InvalidIdentity); + public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, Identity.InvalidIdentity); private final Status status; private final Identity identity; private final Duration durationSinceLastRefresh; diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index ecc5eebe2..9a1ea0f28 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -110,7 +110,7 @@ public Identity generateIdentity(IdentityRequest request) { request.userIdentity.establishedAt, request.userIdentity.refreshedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return Identity.LogoutToken; + return Identity.InvalidIdentity; } else { return generateIdentity(request.publisherIdentity, firstLevelHashIdentity); } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 58a88e01a..c005a1e6e 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -257,7 +257,7 @@ private Router createRoutesSetup() throws IOException { router.get(V0_IDENTITY_MAP.toString()).handler(auth.handle(this::handleIdentityMap, Role.MAPPER)); router.post(V0_IDENTITY_MAP.toString()).handler(bodyHandler).handler(auth.handle(this::handleIdentityMapBatch, Role.MAPPER)); - // Internal service APIs + // internal API to handle user optout of UID router.get(V0_TOKEN_LOGOUT.toString()).handler(auth.handle(this::handleLogoutAsync, Role.OPTOUT)); // only uncomment to do local testing @@ -286,6 +286,7 @@ private void setupV2Routes(Router mainRouter, BodyHandler bodyHandler) { rc -> v2PayloadHandler.handle(rc, this::handleKeysSharing), Role.SHARER, Role.ID_READER)); mainRouter.post(V2_KEY_BIDSTREAM.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handle(rc, this::handleKeysBidstream), Role.ID_READER)); + // internal API to handle user optout of UID mainRouter.post(V2_TOKEN_LOGOUT.toString()).handler(bodyHandler).handler(auth.handleV1( rc -> v2PayloadHandler.handleAsync(rc, this::handleLogoutAsyncV2), Role.OPTOUT)); if (this.optOutStatusApiEnabled) { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index e47f4d4a7..aacd05853 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -407,7 +407,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertEquals(identity, Identity.LogoutToken); + assertEquals(identity, Identity.InvalidIdentity); } @ParameterizedTest @@ -471,7 +471,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); - assertNotEquals(Identity.LogoutToken, identity); + assertNotEquals(Identity.InvalidIdentity, identity); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -513,7 +513,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); - assertNotEquals(Identity.LogoutToken, identity); + assertNotEquals(Identity.InvalidIdentity, identity); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -590,7 +590,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); - assertNotEquals(Identity.LogoutToken, identity); + assertNotEquals(Identity.InvalidIdentity, identity); assertNotNull(advertisingToken.userIdentity); } @@ -651,7 +651,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotEquals(identity, Identity.LogoutToken); + assertNotEquals(identity, Identity.InvalidIdentity); assertNotNull(identity); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); @@ -717,7 +717,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(identity); - assertNotEquals(Identity.LogoutToken, identity); + assertNotEquals(Identity.InvalidIdentity, identity); assertNotNull(advertisingToken.userIdentity); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); From 7dd3a69dbed3856294684345970e67f12df8b3b6 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Thu, 10 Oct 2024 18:09:02 +1100 Subject: [PATCH 03/61] Renamed Identity.LogoutToken to InvalidIdentity and added some comments for clarity --- .../java/com/uid2/operator/model/MappedIdentity.java | 12 ++++++------ .../uid2/operator/service/UIDOperatorService.java | 8 ++++---- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/MappedIdentity.java b/src/main/java/com/uid2/operator/model/MappedIdentity.java index f7d505fcf..de4b368ea 100644 --- a/src/main/java/com/uid2/operator/model/MappedIdentity.java +++ b/src/main/java/com/uid2/operator/model/MappedIdentity.java @@ -1,17 +1,17 @@ package com.uid2.operator.model; public class MappedIdentity { - public static MappedIdentity LogoutIdentity = new MappedIdentity(new byte[33], ""); - // AdvertisingId is the raw UID - public final byte[] advertisingId; + public static MappedIdentity OptoutIdentity = new MappedIdentity(new byte[33], ""); + // The raw UID is also known as Advertising Id (historically) + public final byte[] rawUid; public final String bucketId; - public MappedIdentity(byte[] advertisingId, String bucketId) { - this.advertisingId = advertisingId; + public MappedIdentity(byte[] rawUid, String bucketId) { + this.rawUid = rawUid; this.bucketId = bucketId; } public boolean isOptedOut() { - return this.equals(LogoutIdentity) || this.bucketId == null || this.bucketId.isEmpty(); + return this.equals(OptoutIdentity) || this.bucketId == null || this.bucketId.isEmpty(); } } diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 9a1ea0f28..b3f25a1fd 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -160,7 +160,7 @@ public RefreshResponse refreshIdentity(RefreshToken token) { public MappedIdentity mapIdentity(MapRequest request) { final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.userIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return MappedIdentity.LogoutIdentity; + return MappedIdentity.OptoutIdentity; } else { return getAdvertisingId(firstLevelHashIdentity, request.asOf); } @@ -192,7 +192,7 @@ public void invalidateTokensAsync(UserIdentity userIdentity, Instant asOf, Handl final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); final MappedIdentity mappedIdentity = getAdvertisingId(firstLevelHashIdentity, asOf); - this.optOutStore.addEntry(firstLevelHashIdentity, mappedIdentity.advertisingId, r -> { + this.optOutStore.addEntry(firstLevelHashIdentity, mappedIdentity.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -207,7 +207,7 @@ public boolean advertisingTokenMatches(String advertisingToken, UserIdentity use final MappedIdentity mappedIdentity = getAdvertisingId(firstLevelHashIdentity, asOf); final AdvertisingToken token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(mappedIdentity.advertisingId, token.userIdentity.id); + return Arrays.equals(mappedIdentity.rawUid, token.userIdentity.id); } @Override @@ -249,7 +249,7 @@ private Identity generateIdentity(PublisherIdentity publisherIdentity, UserIdent final MappedIdentity mappedIdentity = getAdvertisingId(firstLevelHashIdentity, nowUtc); final UserIdentity advertisingIdentity = new UserIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - mappedIdentity.advertisingId, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); + mappedIdentity.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encode( this.createAdvertisingToken(publisherIdentity, advertisingIdentity, nowUtc), diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index c005a1e6e..360263861 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1243,7 +1243,7 @@ private void handleIdentityMapV1(RoutingContext rc) { final MappedIdentity mappedIdentity = this.idService.map(input.toUserIdentity(this.identityScope, 0, now), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); - jsonObject.put("advertising_id", EncodingUtils.toBase64String(mappedIdentity.advertisingId)); + jsonObject.put("advertising_id", EncodingUtils.toBase64String(mappedIdentity.rawUid)); jsonObject.put("bucket_id", mappedIdentity.bucketId); ResponseUtil.Success(rc, jsonObject); } catch (Exception e) { @@ -1264,7 +1264,7 @@ else if (!input.isValid()) { else { final Instant now = Instant.now(); final MappedIdentity mappedIdentity = this.idService.map(input.toUserIdentity(this.identityScope, 0, now), now); - rc.response().end(EncodingUtils.toBase64String(mappedIdentity.advertisingId)); + rc.response().end(EncodingUtils.toBase64String(mappedIdentity.rawUid)); } } catch (Exception ex) { LOGGER.error("Unexpected error while mapping identity", ex); @@ -1474,7 +1474,7 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal } else { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); - resp.put("advertising_id", EncodingUtils.toBase64String(mappedIdentity.advertisingId)); + resp.put("advertising_id", EncodingUtils.toBase64String(mappedIdentity.rawUid)); resp.put("bucket_id", mappedIdentity.bucketId); mapped.add(resp); } From f2e7a873599044764d8e7b3d25dd1e358697e2ad Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 12:08:42 +1100 Subject: [PATCH 04/61] renamed getAdvertisingId to MappedIdentity --- .../uid2/operator/service/UIDOperatorService.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index b3f25a1fd..c32fe7149 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -162,14 +162,14 @@ public MappedIdentity mapIdentity(MapRequest request) { if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { return MappedIdentity.OptoutIdentity; } else { - return getAdvertisingId(firstLevelHashIdentity, request.asOf); + return generateMappedIdentity(firstLevelHashIdentity, request.asOf); } } @Override public MappedIdentity map(UserIdentity userIdentity, Instant asOf) { final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); - return getAdvertisingId(firstLevelHashIdentity, asOf); + return generateMappedIdentity(firstLevelHashIdentity, asOf); } @Override @@ -190,7 +190,7 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(UserIdentity userIdentity, Instant asOf, Handler> handler) { final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); - final MappedIdentity mappedIdentity = getAdvertisingId(firstLevelHashIdentity, asOf); + final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, asOf); this.optOutStore.addEntry(firstLevelHashIdentity, mappedIdentity.rawUid, r -> { if (r.succeeded()) { @@ -204,7 +204,7 @@ public void invalidateTokensAsync(UserIdentity userIdentity, Instant asOf, Handl @Override public boolean advertisingTokenMatches(String advertisingToken, UserIdentity userIdentity, Instant asOf) { final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); - final MappedIdentity mappedIdentity = getAdvertisingId(firstLevelHashIdentity, asOf); + final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, asOf); final AdvertisingToken token = this.encoder.decodeAdvertisingToken(advertisingToken); return Arrays.equals(mappedIdentity.rawUid, token.userIdentity.id); @@ -234,7 +234,7 @@ private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private MappedIdentity getAdvertisingId(UserIdentity firstLevelHashIdentity, Instant asOf) { + private MappedIdentity generateMappedIdentity(UserIdentity firstLevelHashIdentity, Instant asOf) { final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.id); return new MappedIdentity( @@ -247,7 +247,7 @@ private MappedIdentity getAdvertisingId(UserIdentity firstLevelHashIdentity, Ins private Identity generateIdentity(PublisherIdentity publisherIdentity, UserIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final MappedIdentity mappedIdentity = getAdvertisingId(firstLevelHashIdentity, nowUtc); + final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, nowUtc); final UserIdentity advertisingIdentity = new UserIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, mappedIdentity.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); From c0cb6df62cc139596878ec5ce223c3f379319870 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 15:14:48 +1100 Subject: [PATCH 05/61] Split UserIdentity into 3 distinct classes - HashedDiiIdentity, FirstLevelHashIdentity and RawUidIdentity as UserIdentity is a very vague term and one needs to read function calls to really understand whether the UserIdentity class has hashed DII, first level hash or raw Uid. --- .../uid2/operator/model/AdvertisingToken.java | 6 +- .../model/FirstLevelHashIdentity.java | 35 +++++ .../operator/model/HashedDiiIdentity.java | 36 ++++++ .../uid2/operator/model/IdentityRequest.java | 6 +- .../com/uid2/operator/model/MapRequest.java | 6 +- .../uid2/operator/model/RawUidIdentity.java | 35 +++++ .../com/uid2/operator/model/RefreshToken.java | 6 +- .../com/uid2/operator/model/UserIdentity.java | 29 +---- .../service/EncryptedTokenEncoder.java | 65 ++++++---- .../operator/service/IUIDOperatorService.java | 8 +- .../com/uid2/operator/service/InputUtil.java | 6 +- .../operator/service/UIDOperatorService.java | 103 ++++++++------- .../operator/store/CloudSyncOptOutStore.java | 11 +- .../com/uid2/operator/store/IOptOutStore.java | 11 +- .../operator/vertx/UIDOperatorVerticle.java | 30 ++--- .../com/uid2/operator/TokenEncodingTest.java | 16 +-- .../uid2/operator/UIDOperatorServiceTest.java | 87 +++++++------ .../operator/UIDOperatorVerticleTest.java | 120 +++++++++--------- .../operator/benchmark/BenchmarkCommon.java | 12 +- .../benchmark/IdentityMapBenchmark.java | 8 +- .../benchmark/TokenEndecBenchmark.java | 2 +- 21 files changed, 375 insertions(+), 263 deletions(-) create mode 100644 src/main/java/com/uid2/operator/model/FirstLevelHashIdentity.java create mode 100644 src/main/java/com/uid2/operator/model/HashedDiiIdentity.java create mode 100644 src/main/java/com/uid2/operator/model/RawUidIdentity.java diff --git a/src/main/java/com/uid2/operator/model/AdvertisingToken.java b/src/main/java/com/uid2/operator/model/AdvertisingToken.java index e1fcc4725..1baa4040f 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingToken.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingToken.java @@ -6,14 +6,14 @@ public class AdvertisingToken extends VersionedToken { public final OperatorIdentity operatorIdentity; public final PublisherIdentity publisherIdentity; - public final UserIdentity userIdentity; + public final RawUidIdentity rawUidIdentity; public AdvertisingToken(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - PublisherIdentity publisherIdentity, UserIdentity userIdentity) { + PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.publisherIdentity = publisherIdentity; - this.userIdentity = userIdentity; + this.rawUidIdentity = rawUidIdentity; } } diff --git a/src/main/java/com/uid2/operator/model/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/FirstLevelHashIdentity.java new file mode 100644 index 000000000..b74e51368 --- /dev/null +++ b/src/main/java/com/uid2/operator/model/FirstLevelHashIdentity.java @@ -0,0 +1,35 @@ +package com.uid2.operator.model; + +import java.time.Instant; +import java.util.Arrays; + +// Contains a first level salted computed from Hashed DII (email/phone number) and applying salt to it +public class FirstLevelHashIdentity implements UserIdentity { + public final IdentityScope identityScope; + public final IdentityType identityType; + public final byte[] firstLevelHash; + public final int privacyBits; + public final Instant establishedAt; + public final Instant refreshedAt; + + public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, int privacyBits, + Instant establishedAt, Instant refreshedAt) { + this.identityScope = identityScope; + this.identityType = identityType; + this.firstLevelHash = firstLevelHash; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; + this.refreshedAt = refreshedAt; + } + + public boolean matches(FirstLevelHashIdentity that) { + return this.identityScope.equals(that.identityScope) && + this.identityType.equals(that.identityType) && + Arrays.equals(this.firstLevelHash, that.firstLevelHash); + } + + public IdentityScope GetIdentityScope() { return identityScope; } + public IdentityType GetIdentityType() { return identityType; } + public Instant GetEstablishedAt() { return establishedAt; }; + public Instant GetIRefreshedAt() { return refreshedAt; } +} diff --git a/src/main/java/com/uid2/operator/model/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/HashedDiiIdentity.java new file mode 100644 index 000000000..500540acd --- /dev/null +++ b/src/main/java/com/uid2/operator/model/HashedDiiIdentity.java @@ -0,0 +1,36 @@ +package com.uid2.operator.model; + +import java.time.Instant; +import java.util.Arrays; + +// Contains a hash computed from a raw email/phone number DII input or the hash is provided by the UID Participant +// directly +public class HashedDiiIdentity implements UserIdentity{ + public final IdentityScope identityScope; + public final IdentityType identityType; + public final byte[] hashedDii; + public final int privacyBits; + public final Instant establishedAt; + public final Instant refreshedAt; + + public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, + Instant establishedAt, Instant refreshedAt) { + this.identityScope = identityScope; + this.identityType = identityType; + this.hashedDii = hashedDii; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; + this.refreshedAt = refreshedAt; + } + + public boolean matches(HashedDiiIdentity that) { + return this.identityScope.equals(that.identityScope) && + this.identityType.equals(that.identityType) && + Arrays.equals(this.hashedDii, that.hashedDii); + } + + public IdentityScope GetIdentityScope() { return identityScope; } + public IdentityType GetIdentityType() { return identityType; } + public Instant GetEstablishedAt() { return establishedAt; }; + public Instant GetIRefreshedAt() { return refreshedAt; } +} diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index 74d8917dd..0a60bf0cd 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -2,16 +2,16 @@ public final class IdentityRequest { public final PublisherIdentity publisherIdentity; - public final UserIdentity userIdentity; + public final HashedDiiIdentity hashedDiiIdentity; public final OptoutCheckPolicy optoutCheckPolicy; public IdentityRequest( PublisherIdentity publisherIdentity, - UserIdentity userIdentity, + HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy) { this.publisherIdentity = publisherIdentity; - this.userIdentity = userIdentity; + this.hashedDiiIdentity = hashedDiiIdentity; this.optoutCheckPolicy = tokenGeneratePolicy; } diff --git a/src/main/java/com/uid2/operator/model/MapRequest.java b/src/main/java/com/uid2/operator/model/MapRequest.java index d39e87238..f627d0703 100644 --- a/src/main/java/com/uid2/operator/model/MapRequest.java +++ b/src/main/java/com/uid2/operator/model/MapRequest.java @@ -3,16 +3,16 @@ import java.time.Instant; public final class MapRequest { - public final UserIdentity userIdentity; + public final HashedDiiIdentity hashedDiiIdentity; public final OptoutCheckPolicy optoutCheckPolicy; public final Instant asOf; public MapRequest( - UserIdentity userIdentity, + HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy optoutCheckPolicy, Instant asOf) { - this.userIdentity = userIdentity; + this.hashedDiiIdentity = hashedDiiIdentity; this.optoutCheckPolicy = optoutCheckPolicy; this.asOf = asOf; } diff --git a/src/main/java/com/uid2/operator/model/RawUidIdentity.java b/src/main/java/com/uid2/operator/model/RawUidIdentity.java new file mode 100644 index 000000000..4ae00f2cf --- /dev/null +++ b/src/main/java/com/uid2/operator/model/RawUidIdentity.java @@ -0,0 +1,35 @@ +package com.uid2.operator.model; + +import java.time.Instant; +import java.util.Arrays; + +// A raw UID is stored inside +public class RawUidIdentity implements UserIdentity { + public final IdentityScope identityScope; + public final IdentityType identityType; + public final byte[] rawUid; + public final int privacyBits; + public final Instant establishedAt; + public final Instant refreshedAt; + + public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid, int privacyBits, + Instant establishedAt, Instant refreshedAt) { + this.identityScope = identityScope; + this.identityType = identityType; + this.rawUid = rawUid; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; + this.refreshedAt = refreshedAt; + } + + public boolean matches(RawUidIdentity that) { + return this.identityScope.equals(that.identityScope) && + this.identityType.equals(that.identityType) && + Arrays.equals(this.rawUid, that.rawUid); + } + + public IdentityScope GetIdentityScope() { return identityScope; } + public IdentityType GetIdentityType() { return identityType; } + public Instant GetEstablishedAt() { return establishedAt; }; + public Instant GetIRefreshedAt() { return refreshedAt; } +} diff --git a/src/main/java/com/uid2/operator/model/RefreshToken.java b/src/main/java/com/uid2/operator/model/RefreshToken.java index 8c70b3bf9..5768fd9a8 100644 --- a/src/main/java/com/uid2/operator/model/RefreshToken.java +++ b/src/main/java/com/uid2/operator/model/RefreshToken.java @@ -6,13 +6,13 @@ public class RefreshToken extends VersionedToken { public final OperatorIdentity operatorIdentity; public final PublisherIdentity publisherIdentity; - public final UserIdentity userIdentity; + public final FirstLevelHashIdentity firstLevelHashIdentity; public RefreshToken(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - PublisherIdentity publisherIdentity, UserIdentity userIdentity) { + PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.publisherIdentity = publisherIdentity; - this.userIdentity = userIdentity; + this.firstLevelHashIdentity = firstLevelHashIdentity; } } diff --git a/src/main/java/com/uid2/operator/model/UserIdentity.java b/src/main/java/com/uid2/operator/model/UserIdentity.java index 760d0ffb6..7b01c0ed0 100644 --- a/src/main/java/com/uid2/operator/model/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/UserIdentity.java @@ -1,30 +1,11 @@ package com.uid2.operator.model; import java.time.Instant; -import java.util.Arrays; -import java.util.Objects; -public class UserIdentity { - public final IdentityScope identityScope; - public final IdentityType identityType; - public final byte[] id; - public final int privacyBits; - public final Instant establishedAt; - public final Instant refreshedAt; +public interface UserIdentity { - public UserIdentity(IdentityScope identityScope, IdentityType identityType, byte[] id, int privacyBits, - Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; - this.id = id; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; - } - - public boolean matches(UserIdentity that) { - return this.identityScope.equals(that.identityScope) && - this.identityType.equals(that.identityType) && - Arrays.equals(this.id, that.id); - } + public IdentityScope GetIdentityScope(); + public IdentityType GetIdentityType(); + public Instant GetEstablishedAt(); + public Instant GetIRefreshedAt(); } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 81a6fd479..1814946db 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -39,7 +39,7 @@ private byte[] encodeV2(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteK Buffer b2 = Buffer.buffer(); b2.appendLong(t.expiresAt.toEpochMilli()); - encodeSiteIdentityV2(b2, t.publisherIdentity, t.userIdentity, siteKey); + encodeSiteIdentityV2(b2, t.publisherIdentity, t.rawUidIdentity, siteKey); final byte[] encryptedId = AesCbc.encrypt(b2.getBytes(), masterKey).getPayload(); @@ -51,10 +51,10 @@ private byte[] encodeV2(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteK private byte[] encodeV3(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer sitePayload = Buffer.buffer(69); encodePublisherIdentityV3(sitePayload, t.publisherIdentity); - sitePayload.appendInt(t.userIdentity.privacyBits); - sitePayload.appendLong(t.userIdentity.establishedAt.toEpochMilli()); - sitePayload.appendLong(t.userIdentity.refreshedAt.toEpochMilli()); - sitePayload.appendBytes(t.userIdentity.id); // 32 or 33 bytes + sitePayload.appendInt(t.rawUidIdentity.privacyBits); + sitePayload.appendLong(t.rawUidIdentity.establishedAt.toEpochMilli()); + sitePayload.appendLong(t.rawUidIdentity.refreshedAt.toEpochMilli()); + sitePayload.appendBytes(t.rawUidIdentity.rawUid); // 32 or 33 bytes final Buffer masterPayload = Buffer.buffer(130); masterPayload.appendLong(t.expiresAt.toEpochMilli()); @@ -64,7 +64,7 @@ private byte[] encodeV3(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteK masterPayload.appendBytes(AesGcm.encrypt(sitePayload.getBytes(), siteKey).getPayload()); final Buffer b = Buffer.buffer(164); - b.appendByte(encodeIdentityTypeV3(t.userIdentity)); + b.appendByte(encodeIdentityTypeV3(t.rawUidIdentity.identityScope, t.rawUidIdentity.identityType)); b.appendByte((byte) t.version.rawVersion); b.appendInt(masterKey.getId()); b.appendBytes(AesGcm.encrypt(masterPayload.getBytes(), masterKey).getPayload()); @@ -124,7 +124,8 @@ private RefreshToken decodeRefreshTokenV2(Buffer b) { TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), new PublisherIdentity(siteId, 0, 0), - new UserIdentity(IdentityScope.UID2, IdentityType.Email, identity, privacyBits, Instant.ofEpochMilli(establishedMillis), null)); + new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, identity, privacyBits, + Instant.ofEpochMilli(establishedMillis), null)); } private RefreshToken decodeRefreshTokenV3(Buffer b, byte[] bytes) { @@ -157,7 +158,7 @@ private RefreshToken decodeRefreshTokenV3(Buffer b, byte[] bytes) { return new RefreshToken( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, publisherIdentity, - new UserIdentity(identityScope, identityType, id, privacyBits, establishedAt, null)); + new FirstLevelHashIdentity(identityScope, identityType, id, privacyBits, establishedAt, null)); } @Override @@ -225,7 +226,8 @@ public AdvertisingToken decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new PublisherIdentity(siteId, siteKeyId, 0), - new UserIdentity(IdentityScope.UID2, IdentityType.Email, advertisingId, privacyBits, Instant.ofEpochMilli(establishedMillis), null) + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, advertisingId, privacyBits, + Instant.ofEpochMilli(establishedMillis), null) ); } catch (Exception e) { @@ -265,7 +267,7 @@ public AdvertisingToken decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, Tok return new AdvertisingToken( tokenVersion, createdAt, expiresAt, operatorIdentity, publisherIdentity, - new UserIdentity(identityScope, identityType, id, privacyBits, establishedAt, refreshedAt) + new RawUidIdentity(identityScope, identityType, id, privacyBits, establishedAt, refreshedAt) ); } @@ -300,7 +302,7 @@ public byte[] encodeV2(RefreshToken t, KeysetKey serviceKey) { // give an extra minute for clients which are trying to refresh tokens close to or at the refresh expiry timestamp b.appendLong(t.expiresAt.plusSeconds(60).toEpochMilli()); b.appendInt(serviceKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(t.publisherIdentity, t.userIdentity, serviceKey); + final byte[] encryptedIdentity = encryptIdentityV2(t.publisherIdentity, t.firstLevelHashIdentity, serviceKey); b.appendBytes(encryptedIdentity); return b.getBytes(); } @@ -311,13 +313,13 @@ public byte[] encodeV3(RefreshToken t, KeysetKey serviceKey) { refreshPayload.appendLong(t.createdAt.toEpochMilli()); encodeOperatorIdentityV3(refreshPayload, t.operatorIdentity); encodePublisherIdentityV3(refreshPayload, t.publisherIdentity); - refreshPayload.appendInt(t.userIdentity.privacyBits); - refreshPayload.appendLong(t.userIdentity.establishedAt.toEpochMilli()); - refreshPayload.appendByte(encodeIdentityTypeV3(t.userIdentity)); - refreshPayload.appendBytes(t.userIdentity.id); + refreshPayload.appendInt(t.firstLevelHashIdentity.privacyBits); + refreshPayload.appendLong(t.firstLevelHashIdentity.establishedAt.toEpochMilli()); + refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHashIdentity.identityScope, t.firstLevelHashIdentity.identityType)); + refreshPayload.appendBytes(t.firstLevelHashIdentity.firstLevelHash); final Buffer b = Buffer.buffer(124); - b.appendByte(encodeIdentityTypeV3(t.userIdentity)); + b.appendByte(encodeIdentityTypeV3(t.firstLevelHashIdentity.identityScope, t.firstLevelHashIdentity.identityType)); b.appendByte((byte) t.version.rawVersion); b.appendInt(serviceKey.getId()); b.appendBytes(AesGcm.encrypt(refreshPayload.getBytes(), serviceKey).getPayload()); @@ -325,9 +327,10 @@ public byte[] encodeV3(RefreshToken t, KeysetKey serviceKey) { return b.getBytes(); } - private void encodeSiteIdentityV2(Buffer b, PublisherIdentity publisherIdentity, UserIdentity userIdentity, KeysetKey siteEncryptionKey) { + private void encodeSiteIdentityV2(Buffer b, PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, + KeysetKey siteEncryptionKey) { b.appendInt(siteEncryptionKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(publisherIdentity, userIdentity, siteEncryptionKey); + final byte[] encryptedIdentity = encryptIdentityV2(publisherIdentity, rawUidIdentity, siteEncryptionKey); b.appendBytes(encryptedIdentity); } @@ -352,23 +355,37 @@ public Identity encode(AdvertisingToken advertisingToken, RefreshToken refreshTo ); } - private byte[] encryptIdentityV2(PublisherIdentity publisherIdentity, UserIdentity identity, KeysetKey key) { + private byte[] encryptIdentityV2(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { + return encryptIdentityV2(publisherIdentity, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, + firstLevelHashIdentity.establishedAt, key); + + } + + private byte[] encryptIdentityV2(PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, + KeysetKey key) { + return encryptIdentityV2(publisherIdentity, rawUidIdentity.rawUid, rawUidIdentity.privacyBits, + rawUidIdentity.establishedAt, key); + } + + + private byte[] encryptIdentityV2(PublisherIdentity publisherIdentity, byte[] id, int privacyBits, + Instant establishedAt, KeysetKey key) { Buffer b = Buffer.buffer(); try { b.appendInt(publisherIdentity.siteId); - final byte[] identityBytes = EncodingUtils.toBase64(identity.id); + final byte[] identityBytes = EncodingUtils.toBase64(id); b.appendInt(identityBytes.length); b.appendBytes(identityBytes); - b.appendInt(identity.privacyBits); - b.appendLong(identity.establishedAt.toEpochMilli()); + b.appendInt(privacyBits); + b.appendLong(establishedAt.toEpochMilli()); return AesCbc.encrypt(b.getBytes(), key).getPayload(); } catch (Exception e) { throw new RuntimeException("Could not turn Identity into UTF-8", e); } } - static private byte encodeIdentityTypeV3(UserIdentity userIdentity) { - return (byte) (TokenUtils.encodeIdentityScope(userIdentity.identityScope) | (userIdentity.identityType.value << 2) | 3); + static private byte encodeIdentityTypeV3(IdentityScope identityScope, IdentityType identityType) { + return (byte) (TokenUtils.encodeIdentityScope(identityScope) | (identityType.value << 2) | 3); // "| 3" is used so that the 2nd char matches the version when V3 or higher. Eg "3" for V3 and "4" for V4 } diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 494fc531a..ac0dfa6c7 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -18,15 +18,15 @@ public interface IUIDOperatorService { MappedIdentity mapIdentity(MapRequest request); @Deprecated - MappedIdentity map(UserIdentity userIdentity, Instant asOf); + MappedIdentity map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); - void invalidateTokensAsync(UserIdentity userIdentity, Instant asOf, Handler> handler); + void invalidateTokensAsync(HashedDiiIdentity hashedDiiIdentity, Instant asOf, Handler> handler); - boolean advertisingTokenMatches(String advertisingToken, UserIdentity userIdentity, Instant asOf); + boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity hashedDiiIdentity, Instant asOf); - Instant getLatestOptoutEntry(UserIdentity userIdentity, Instant asOf); + Instant getLatestOptoutEntry(HashedDiiIdentity hashedDiiIdentity, Instant asOf); Duration getIdentityExpiryDuration(); } diff --git a/src/main/java/com/uid2/operator/service/InputUtil.java b/src/main/java/com/uid2/operator/service/InputUtil.java index 839e4e0f3..133d6641c 100644 --- a/src/main/java/com/uid2/operator/service/InputUtil.java +++ b/src/main/java/com/uid2/operator/service/InputUtil.java @@ -2,7 +2,7 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.IdentityType; -import com.uid2.operator.model.UserIdentity; +import com.uid2.operator.model.HashedDiiIdentity; import java.time.Instant; @@ -261,8 +261,8 @@ public boolean isValid() { return valid; } - public UserIdentity toUserIdentity(IdentityScope identityScope, int privacyBits, Instant establishedAt) { - return new UserIdentity( + public HashedDiiIdentity toHashedDiiIdentity(IdentityScope identityScope, int privacyBits, Instant establishedAt) { + return new HashedDiiIdentity( identityScope, this.identityType, getIdentityInput(), diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index c32fe7149..a3168eefe 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -36,12 +36,12 @@ public class UIDOperatorService implements IUIDOperatorService { private final ITokenEncoder encoder; private final Clock clock; private final IdentityScope identityScope; - private final UserIdentity testOptOutIdentityForEmail; - private final UserIdentity testOptOutIdentityForPhone; - private final UserIdentity testValidateIdentityForEmail; - private final UserIdentity testValidateIdentityForPhone; - private final UserIdentity testRefreshOptOutIdentityForEmail; - private final UserIdentity testRefreshOptOutIdentityForPhone; + private final FirstLevelHashIdentity testOptOutIdentityForEmail; + private final FirstLevelHashIdentity testOptOutIdentityForPhone; + private final FirstLevelHashIdentity testValidateIdentityForEmail; + private final FirstLevelHashIdentity testValidateIdentityForPhone; + private final FirstLevelHashIdentity testRefreshOptOutIdentityForEmail; + private final FirstLevelHashIdentity testRefreshOptOutIdentityForPhone; private final Duration identityExpiresAfter; private final Duration refreshExpiresAfter; private final Duration refreshIdentityAfter; @@ -104,10 +104,10 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv @Override public Identity generateIdentity(IdentityRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); - final byte[] firstLevelHash = getFirstLevelHash(request.userIdentity.id, now); - final UserIdentity firstLevelHashIdentity = new UserIdentity( - request.userIdentity.identityScope, request.userIdentity.identityType, firstLevelHash, request.userIdentity.privacyBits, - request.userIdentity.establishedAt, request.userIdentity.refreshedAt); + final byte[] firstLevelHash = getFirstLevelHash(request.hashedDiiIdentity.hashedDii, now); + final FirstLevelHashIdentity firstLevelHashIdentity = new FirstLevelHashIdentity( + request.hashedDiiIdentity.identityScope, request.hashedDiiIdentity.identityType, firstLevelHash, request.hashedDiiIdentity.privacyBits, + request.hashedDiiIdentity.establishedAt, request.hashedDiiIdentity.refreshedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { return Identity.InvalidIdentity; @@ -119,11 +119,11 @@ public Identity generateIdentity(IdentityRequest request) { @Override public RefreshResponse refreshIdentity(RefreshToken token) { // should not be possible as different scopes should be using different keys, but just in case - if (token.userIdentity.identityScope != this.identityScope) { + if (token.firstLevelHashIdentity.identityScope != this.identityScope) { return RefreshResponse.Invalid; } - if (token.userIdentity.establishedAt.isBefore(RefreshCutoff)) { + if (token.firstLevelHashIdentity.establishedAt.isBefore(RefreshCutoff)) { return RefreshResponse.Deprecated; } @@ -133,17 +133,17 @@ public RefreshResponse refreshIdentity(RefreshToken token) { return RefreshResponse.Expired; } - final PrivacyBits privacyBits = PrivacyBits.fromInt(token.userIdentity.privacyBits); + final PrivacyBits privacyBits = PrivacyBits.fromInt(token.firstLevelHashIdentity.privacyBits); final boolean isCstg = privacyBits.isClientSideTokenGenerated(); try { - final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(token.userIdentity, true); + final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(token.firstLevelHashIdentity, true); final boolean optedOut = logoutEntry.isOptedOut(); final Duration durationSinceLastRefresh = Duration.between(token.createdAt, now); if (!optedOut) { - Identity identity = this.generateIdentity(token.publisherIdentity, token.userIdentity); + Identity identity = this.generateIdentity(token.publisherIdentity, token.firstLevelHashIdentity); return RefreshResponse.createRefreshedResponse(identity, durationSinceLastRefresh, isCstg); } else { @@ -158,7 +158,8 @@ public RefreshResponse refreshIdentity(RefreshToken token) { @Override public MappedIdentity mapIdentity(MapRequest request) { - final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.userIdentity, request.asOf); + final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, + request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { return MappedIdentity.OptoutIdentity; } else { @@ -167,8 +168,8 @@ public MappedIdentity mapIdentity(MapRequest request) { } @Override - public MappedIdentity map(UserIdentity userIdentity, Instant asOf) { - final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); + public MappedIdentity map(HashedDiiIdentity diiIdentity, Instant asOf) { + final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); return generateMappedIdentity(firstLevelHashIdentity, asOf); } @@ -188,11 +189,11 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { } @Override - public void invalidateTokensAsync(UserIdentity userIdentity, Instant asOf, Handler> handler) { - final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); - final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, asOf); + public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { + final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); + final MappedIdentity mappedIdentity = generateMappedIdentity(hashedDiiIdentity, asOf); - this.optOutStore.addEntry(firstLevelHashIdentity, mappedIdentity.rawUid, r -> { + this.optOutStore.addEntry(hashedDiiIdentity, mappedIdentity.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -202,17 +203,17 @@ public void invalidateTokensAsync(UserIdentity userIdentity, Instant asOf, Handl } @Override - public boolean advertisingTokenMatches(String advertisingToken, UserIdentity userIdentity, Instant asOf) { - final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); + public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { + final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, asOf); final AdvertisingToken token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(mappedIdentity.rawUid, token.userIdentity.id); + return Arrays.equals(mappedIdentity.rawUid, token.rawUidIdentity.rawUid); } @Override - public Instant getLatestOptoutEntry(UserIdentity userIdentity, Instant asOf) { - final UserIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(userIdentity, asOf); + public Instant getLatestOptoutEntry(HashedDiiIdentity hashedDiiIdentity, Instant asOf) { + final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(hashedDiiIdentity, asOf); return this.optOutStore.getLatestEntry(firstLevelHashIdentity); } @@ -221,61 +222,65 @@ public Duration getIdentityExpiryDuration() { return this.identityExpiresAfter; } - private UserIdentity getFirstLevelHashIdentity(UserIdentity userIdentity, Instant asOf) { - return getFirstLevelHashIdentity(userIdentity.identityScope, userIdentity.identityType, userIdentity.id, asOf); + private FirstLevelHashIdentity getFirstLevelHashIdentity(HashedDiiIdentity hashedDiiIdentity, Instant asOf) { + return getFirstLevelHashIdentity(hashedDiiIdentity.identityScope, hashedDiiIdentity.identityType, hashedDiiIdentity.hashedDii, asOf); } - private UserIdentity getFirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] identityHash, Instant asOf) { + private FirstLevelHashIdentity getFirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] identityHash, Instant asOf) { final byte[] firstLevelHash = getFirstLevelHash(identityHash, asOf); - return new UserIdentity(identityScope, identityType, firstLevelHash, 0, null, null); + return new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, 0, null, null); } private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private MappedIdentity generateMappedIdentity(UserIdentity firstLevelHashIdentity, Instant asOf) { - final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.id); + private MappedIdentity generateMappedIdentity(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { + final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); return new MappedIdentity( this.identityV3Enabled - ? TokenUtils.getAdvertisingIdV3(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, firstLevelHashIdentity.id, rotatingSalt.getSalt()) - : TokenUtils.getAdvertisingIdV2(firstLevelHashIdentity.id, rotatingSalt.getSalt()), + ? TokenUtils.getAdvertisingIdV3(firstLevelHashIdentity.identityScope, + firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) + : TokenUtils.getAdvertisingIdV2(firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()), rotatingSalt.getHashedId()); } - private Identity generateIdentity(PublisherIdentity publisherIdentity, UserIdentity firstLevelHashIdentity) { + private Identity generateIdentity(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, nowUtc); - final UserIdentity advertisingIdentity = new UserIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, + final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, + firstLevelHashIdentity.identityType, mappedIdentity.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encode( - this.createAdvertisingToken(publisherIdentity, advertisingIdentity, nowUtc), + this.createAdvertisingToken(publisherIdentity, rawUidIdentity, nowUtc), this.createRefreshToken(publisherIdentity, firstLevelHashIdentity, nowUtc), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc ); } - private RefreshToken createRefreshToken(PublisherIdentity publisherIdentity, UserIdentity userIdentity, Instant now) { + private RefreshToken createRefreshToken(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity, + Instant now) { return new RefreshToken( this.refreshTokenVersion, now, now.plusMillis(refreshExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, - userIdentity); + firstLevelHashIdentity); } - private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdentity, UserIdentity userIdentity, Instant now) { + private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, + Instant now) { TokenVersion tokenVersion; if (siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) { tokenVersion = TokenVersion.V4; } else { int pseudoRandomNumber = 1; - final var rawUid = userIdentity.id; + final var rawUid = rawUidIdentity.rawUid; 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 @@ -283,7 +288,7 @@ private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdent } 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, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, rawUidIdentity); } static protected class GlobalOptoutResult { @@ -307,16 +312,16 @@ public Instant getTime() { } } - private GlobalOptoutResult getGlobalOptOutResult(UserIdentity userIdentity, boolean forRefresh) { - if (forRefresh && (userIdentity.matches(testRefreshOptOutIdentityForEmail) || userIdentity.matches(testRefreshOptOutIdentityForPhone))) { + private GlobalOptoutResult getGlobalOptOutResult(FirstLevelHashIdentity firstLevelHashIdentity, boolean forRefresh) { + if (forRefresh && (firstLevelHashIdentity.matches(testRefreshOptOutIdentityForEmail) || firstLevelHashIdentity.matches(testRefreshOptOutIdentityForPhone))) { return new GlobalOptoutResult(Instant.now()); - } else if (userIdentity.matches(testValidateIdentityForEmail) || userIdentity.matches(testValidateIdentityForPhone) - || userIdentity.matches(testRefreshOptOutIdentityForEmail) || userIdentity.matches(testRefreshOptOutIdentityForPhone)) { + } else if (firstLevelHashIdentity.matches(testValidateIdentityForEmail) || firstLevelHashIdentity.matches(testValidateIdentityForPhone) + || firstLevelHashIdentity.matches(testRefreshOptOutIdentityForEmail) || firstLevelHashIdentity.matches(testRefreshOptOutIdentityForPhone)) { return new GlobalOptoutResult(null); - } else if (userIdentity.matches(testOptOutIdentityForEmail) || userIdentity.matches(testOptOutIdentityForPhone)) { + } else if (firstLevelHashIdentity.matches(testOptOutIdentityForEmail) || firstLevelHashIdentity.matches(testOptOutIdentityForPhone)) { return new GlobalOptoutResult(Instant.now()); } - Instant result = this.optOutStore.getLatestEntry(userIdentity); + Instant result = this.optOutStore.getLatestEntry(firstLevelHashIdentity); return new GlobalOptoutResult(result); } diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 5ca87cc37..29c8a53a5 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -4,7 +4,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.uid2.operator.Const; -import com.uid2.operator.model.UserIdentity; +import com.uid2.operator.model.FirstLevelHashIdentity; +import com.uid2.operator.model.HashedDiiIdentity; import com.uid2.operator.service.EncodingUtils; import com.uid2.shared.Utils; import com.uid2.shared.cloud.CloudStorageException; @@ -74,8 +75,8 @@ public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonC } @Override - public Instant getLatestEntry(UserIdentity firstLevelHashIdentity) { - long epochSecond = this.snapshot.get().getOptOutTimestamp(firstLevelHashIdentity.id); + public Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity) { + long epochSecond = this.snapshot.get().getOptOutTimestamp(firstLevelHashIdentity.firstLevelHash); Instant instant = epochSecond > 0 ? Instant.ofEpochSecond(epochSecond) : null; return instant; } @@ -86,14 +87,14 @@ public long getOptOutTimestampByAdId(String adId) { } @Override - public void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { + public void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { if (remoteApiHost == null) { handler.handle(Future.failedFuture("remote api not set")); return; } this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath). - addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.id)) + addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.firstLevelHash)) .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) .putHeader("Authorization", remoteApiBearerToken) .as(BodyCodec.string()) diff --git a/src/main/java/com/uid2/operator/store/IOptOutStore.java b/src/main/java/com/uid2/operator/store/IOptOutStore.java index cadfd239a..20d30dda8 100644 --- a/src/main/java/com/uid2/operator/store/IOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/IOptOutStore.java @@ -1,6 +1,7 @@ package com.uid2.operator.store; -import com.uid2.operator.model.UserIdentity; +import com.uid2.operator.model.FirstLevelHashIdentity; +import com.uid2.operator.model.HashedDiiIdentity; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; @@ -10,12 +11,12 @@ public interface IOptOutStore { /** * Get latest Opt-out record with respect to the UID (hashed identity) - * @param firstLevelHashIdentity UID - * @return The timestamp of latest opt-out record. NULL if no record. + * + * @param firstLevelHashIdentity@return The timestamp of latest opt-out record. NULL if no record. */ - Instant getLatestEntry(UserIdentity firstLevelHashIdentity); + Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity); long getOptOutTimestampByAdId(String adId); - void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler); + void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler); } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 360263861..761a0f6d4 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -464,7 +464,7 @@ else if(emailHash != null) { identity = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), - input.toUserIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), + input.toHashedDiiIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), OptoutCheckPolicy.RespectOptOut)); } catch (KeyManager.NoActiveKeyException e){ SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, platformType); @@ -877,7 +877,7 @@ private void handleTokenValidateV1(RoutingContext rc) { || (Arrays.equals(ValidateIdentityForPhoneHash, input.getIdentityInput()) && input.getIdentityType() == IdentityType.Phone)) { try { final Instant now = Instant.now(); - if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toUserIdentity(this.identityScope, 0, now), now)) { + if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope, 0, now), now)) { ResponseUtil.Success(rc, Boolean.TRUE); } else { ResponseUtil.Success(rc, Boolean.FALSE); @@ -910,7 +910,7 @@ private void handleTokenValidateV2(RoutingContext rc) { final Instant now = Instant.now(); final String token = req.getString("token"); - if (this.idService.advertisingTokenMatches(token, input.toUserIdentity(this.identityScope, 0, now), now)) { + if (this.idService.advertisingTokenMatches(token, input.toHashedDiiIdentity(this.identityScope, 0, now), now)) { ResponseUtil.SuccessV2(rc, Boolean.TRUE); } else { ResponseUtil.SuccessV2(rc, Boolean.FALSE); @@ -939,7 +939,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { final Identity t = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), - input.toUserIdentity(this.identityScope, 1, Instant.now()), + input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.defaultPolicy())); //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); @@ -995,7 +995,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { final Identity t = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), - input.toUserIdentity(this.identityScope, 1, Instant.now()), + input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.respectOptOut())); if (t.isEmptyToken()) { @@ -1011,7 +1011,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { final Identity optOutTokens = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), - optOutTokenInput.toUserIdentity(this.identityScope, pb.getAsInt(), Instant.now()), + optOutTokenInput.toHashedDiiIdentity(this.identityScope, pb.getAsInt(), Instant.now()), OptoutCheckPolicy.DoNotRespect)); ResponseUtil.SuccessV2(rc, toJsonV1(optOutTokens)); @@ -1051,7 +1051,7 @@ else if (!input.isValid()) { final Identity t = this.idService.generateIdentity( new IdentityRequest( new PublisherIdentity(siteId, 0, 0), - input.toUserIdentity(this.identityScope, 1, Instant.now()), + input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.defaultPolicy())); //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); @@ -1093,7 +1093,7 @@ private void handleValidate(RoutingContext rc) { if (input != null && input.isValid() && Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput())) { try { final Instant now = Instant.now(); - if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toUserIdentity(this.identityScope, 0, now), now)) { + if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope, 0, now), now)) { rc.response().end("true"); } else { rc.response().end("false"); @@ -1114,7 +1114,7 @@ private void handleLogoutAsync(RoutingContext rc) { final InputUtil.InputVal input = this.phoneSupport ? getTokenInputV1(rc) : getTokenInput(rc); if (input.isValid()) { final Instant now = Instant.now(); - this.idService.invalidateTokensAsync(input.toUserIdentity(this.identityScope, 0, now), now, ar -> { + this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope, 0, now), now, ar -> { if (ar.succeeded()) { rc.response().end("OK"); } else { @@ -1133,7 +1133,7 @@ private Future handleLogoutAsyncV2(RoutingContext rc) { final Instant now = Instant.now(); Promise promise = Promise.promise(); - this.idService.invalidateTokensAsync(input.toUserIdentity(this.identityScope, 0, now), now, ar -> { + this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope, 0, now), now, ar -> { if (ar.succeeded()) { JsonObject body = new JsonObject(); body.put("optout", "OK"); @@ -1155,8 +1155,8 @@ private void handleOptOutGet(RoutingContext rc) { if (input.isValid()) { try { final Instant now = Instant.now(); - final UserIdentity userIdentity = input.toUserIdentity(this.identityScope, 0, now); - final Instant result = this.idService.getLatestOptoutEntry(userIdentity, now); + final HashedDiiIdentity hashedDiiIdentity = input.toHashedDiiIdentity(this.identityScope, 0, now); + final Instant result = this.idService.getLatestOptoutEntry(hashedDiiIdentity, now); long timestamp = result == null ? -1 : result.getEpochSecond(); rc.response().setStatusCode(200) .setChunked(true) @@ -1240,7 +1240,7 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final MappedIdentity mappedIdentity = this.idService.map(input.toUserIdentity(this.identityScope, 0, now), now); + final MappedIdentity mappedIdentity = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); jsonObject.put("advertising_id", EncodingUtils.toBase64String(mappedIdentity.rawUid)); @@ -1263,7 +1263,7 @@ else if (!input.isValid()) { } else { final Instant now = Instant.now(); - final MappedIdentity mappedIdentity = this.idService.map(input.toUserIdentity(this.identityScope, 0, now), now); + final MappedIdentity mappedIdentity = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); rc.response().end(EncodingUtils.toBase64String(mappedIdentity.rawUid)); } } catch (Exception ex) { @@ -1461,7 +1461,7 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal if (input != null && input.isValid()) { final MappedIdentity mappedIdentity = idService.mapIdentity( new MapRequest( - input.toUserIdentity(this.identityScope, 0, now), + input.toHashedDiiIdentity(this.identityScope, 0, now), OptoutCheckPolicy.respectOptOut(), now)); diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index c77c81b78..ef509cc70 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -57,7 +57,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), new PublisherIdentity(111, 112, 113), - new UserIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, 121, now, now.minusSeconds(122)) + new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, 121, now, now.minusSeconds(122)) ); if (tokenVersion == TokenVersion.V4) { @@ -71,9 +71,9 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { assertEquals(token.createdAt, decoded.createdAt); int addSeconds = (tokenVersion == TokenVersion.V2) ? 60 : 0; //todo: why is there a 60 second buffer in encodeV2() but not in encodeV3()? assertEquals(token.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); - assertTrue(token.userIdentity.matches(decoded.userIdentity)); - assertEquals(token.userIdentity.privacyBits, decoded.userIdentity.privacyBits); - assertEquals(token.userIdentity.establishedAt, decoded.userIdentity.establishedAt); + assertTrue(token.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); + assertEquals(token.firstLevelHashIdentity.privacyBits, decoded.firstLevelHashIdentity.privacyBits); + assertEquals(token.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); assertEquals(token.publisherIdentity.siteId, decoded.publisherIdentity.siteId); Buffer b = Buffer.buffer(encodedBytes); @@ -99,7 +99,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { now.plusSeconds(60), new OperatorIdentity(101, OperatorType.Service, 102, 103), new PublisherIdentity(111, 112, 113), - new UserIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, 121, now, now.minusSeconds(122)) + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, 121, now, now.minusSeconds(122)) ); final byte[] encodedBytes = encoder.encode(token, now); @@ -108,9 +108,9 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { assertEquals(tokenVersion, decoded.version); assertEquals(token.createdAt, decoded.createdAt); assertEquals(token.expiresAt, decoded.expiresAt); - assertTrue(token.userIdentity.matches(decoded.userIdentity)); - assertEquals(token.userIdentity.privacyBits, decoded.userIdentity.privacyBits); - assertEquals(token.userIdentity.establishedAt, decoded.userIdentity.establishedAt); + assertTrue(token.rawUidIdentity.matches(decoded.rawUidIdentity)); + assertEquals(token.rawUidIdentity.privacyBits, decoded.rawUidIdentity.privacyBits); + assertEquals(token.rawUidIdentity.establishedAt, decoded.rawUidIdentity.establishedAt); assertEquals(token.publisherIdentity.siteId, decoded.publisherIdentity.siteId); Buffer b = Buffer.buffer(encodedBytes); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index aacd05853..8f4c66021 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -123,8 +123,8 @@ private void setNow(Instant now) { when(clock.instant()).thenAnswer(i -> this.now); } - private UserIdentity createUserIdentity(String rawIdentityHash, IdentityScope scope, IdentityType type) { - return new UserIdentity( + private HashedDiiIdentity createHashedDiiIdentity(String rawIdentityHash, IdentityScope scope, IdentityType type) { + return new HashedDiiIdentity( scope, type, rawIdentityHash.getBytes(StandardCharsets.UTF_8), @@ -140,10 +140,11 @@ private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder tokenEncoder, return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); } - private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expctedUserIdentity, UserIdentity actualUserIdentity) { - assertEquals(expctedUserIdentity.identityScope, actualUserIdentity.identityScope); - assertEquals(expctedUserIdentity.identityType, actualUserIdentity.identityType); - assertEquals(expctedUserIdentity.establishedAt, actualUserIdentity.establishedAt); + private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expctedValues, + UserIdentity actualValues) { + assertEquals(expctedValues.GetIdentityScope(), actualValues.GetIdentityScope()); + assertEquals(expctedValues.GetIdentityType(), actualValues.GetIdentityType()); + assertEquals(expctedValues.GetEstablishedAt(), actualValues.GetEstablishedAt()); } @ParameterizedTest @@ -151,7 +152,7 @@ private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expcte public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(siteId, 124, 125), - createUserIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), + createHashedDiiIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), OptoutCheckPolicy.DoNotRespect ); final Identity identity = uid2Service.generateIdentity(identityRequest); @@ -162,13 +163,13 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { UIDOperatorVerticleTest.validateAdvertisingToken(identity.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(identity.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.userIdentity, advertisingToken.userIdentity); + assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, advertisingToken.rawUidIdentity); RefreshToken refreshToken = tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); assertEquals(this.now, refreshToken.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken.expiresAt); assertEquals(identityRequest.publisherIdentity.siteId, refreshToken.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.userIdentity, refreshToken.userIdentity); + assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, refreshToken.firstLevelHashIdentity); setNow(Instant.now().plusSeconds(200)); @@ -184,15 +185,17 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { AdvertisingToken advertisingToken2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingToken.userIdentity, advertisingToken2.userIdentity); - assertArrayEquals(advertisingToken.userIdentity.id, advertisingToken2.userIdentity.id); + assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingToken.rawUidIdentity, + advertisingToken2.rawUidIdentity); + assertArrayEquals(advertisingToken.rawUidIdentity.rawUid, + advertisingToken2.rawUidIdentity.rawUid); RefreshToken refreshToken2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentity().getRefreshToken()); assertEquals(this.now, refreshToken2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken2.expiresAt); assertEquals(refreshToken.publisherIdentity.siteId, refreshToken2.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(refreshToken.userIdentity, refreshToken2.userIdentity); - assertArrayEquals(refreshToken.userIdentity.id, refreshToken2.userIdentity.id); + assertIdentityScopeIdentityTypeAndEstablishedAt(refreshToken.firstLevelHashIdentity, refreshToken2.firstLevelHashIdentity); + assertArrayEquals(refreshToken.firstLevelHashIdentity.firstLevelHash, refreshToken2.firstLevelHashIdentity.firstLevelHash); } @Test @@ -201,7 +204,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(IdentityScope.UID2, 0, this.now), + inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.DoNotRespect ); final Identity identity = uid2Service.generateIdentity(identityRequest); @@ -220,7 +223,7 @@ public void testTestOptOutKey_RespectOptout() { final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(IdentityScope.UID2, 0, this.now), + inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.RespectOptOut ); final Identity identity = uid2Service.generateIdentity(identityRequest); @@ -236,7 +239,7 @@ public void testTestOptOutKeyIdentityScopeMismatch() { final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(IdentityScope.EUID, 0, this.now), + inputVal.toHashedDiiIdentity(IdentityScope.EUID, 0, this.now), OptoutCheckPolicy.DoNotRespect ); final Identity identity = euidService.generateIdentity(identityRequest); @@ -256,20 +259,20 @@ public void testTestOptOutKeyIdentityScopeMismatch() { "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) public void testGenerateTokenForOptOutUser(IdentityType type, String id, IdentityScope scope) { - final UserIdentity userIdentity = createUserIdentity(id, scope, type); + final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(id, scope, type); final IdentityRequest identityRequestForceGenerate = new IdentityRequest( new PublisherIdentity(123, 124, 125), - userIdentity, + hashedDiiIdentity, OptoutCheckPolicy.DoNotRespect); final IdentityRequest identityRequestRespectOptOut = new IdentityRequest( new PublisherIdentity(123, 124, 125), - userIdentity, + hashedDiiIdentity, OptoutCheckPolicy.RespectOptOut); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); final Identity identity; @@ -279,7 +282,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit identity = uid2Service.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); identityAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); @@ -287,14 +290,14 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit identity = euidService.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, userIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); identityAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); - assertNotNull(advertisingToken.userIdentity); + assertNotNull(advertisingToken.rawUidIdentity); assertNotNull(identityAfterOptOut); assertTrue(identityAfterOptOut.getAdvertisingToken() == null || identityAfterOptOut.getAdvertisingToken().isEmpty()); @@ -306,21 +309,21 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) public void testIdentityMapForOptOutUser(IdentityType type, String identity, IdentityScope scope) { - final UserIdentity userIdentity = createUserIdentity(identity, scope, type); + final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(identity, scope, type); final Instant now = Instant.now(); final MapRequest mapRequestForceMap = new MapRequest( - userIdentity, + hashedDiiIdentity, OptoutCheckPolicy.DoNotRespect, now); final MapRequest mapRequestRespectOptOut = new MapRequest( - userIdentity, + hashedDiiIdentity, OptoutCheckPolicy.RespectOptOut, now); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); final MappedIdentity mappedIdentity; @@ -391,7 +394,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut ); @@ -423,7 +426,7 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, InputUtil.InputVal inputVal = generateInputVal(type, id); final MapRequest mapRequestRespectOptOut = new MapRequest( - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); @@ -457,7 +460,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.DoNotRespect ); @@ -496,7 +499,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut ); @@ -537,7 +540,7 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str InputUtil.InputVal inputVal = generateInputVal(type, id); final MapRequest mapRequestRespectOptOut = new MapRequest( - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); @@ -571,7 +574,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut ); @@ -586,12 +589,12 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, else { identity = uid2Service.generateIdentity(identityRequest); } - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); assertNotEquals(Identity.InvalidIdentity, identity); - assertNotNull(advertisingToken.userIdentity); + assertNotNull(advertisingToken.rawUidIdentity); } @@ -608,7 +611,7 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i InputUtil.InputVal inputVal = generateInputVal(type, id); final MapRequest mapRequestRespectOptOut = new MapRequest( - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); @@ -639,7 +642,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.DoNotRespect ); Identity identity; @@ -700,7 +703,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String final IdentityRequest identityRequest = new IdentityRequest( new PublisherIdentity(123, 124, 125), - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut); Identity identity; @@ -708,17 +711,17 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String reset(shutdownHandler); if(scope == IdentityScope.EUID) { identity = euidService.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); } else { identity = uid2Service.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.userIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(identity); assertNotEquals(Identity.InvalidIdentity, identity); - assertNotNull(advertisingToken.userIdentity); + assertNotNull(advertisingToken.rawUidIdentity); final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); @@ -730,7 +733,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String assertNotEquals(RefreshResponse.Optout, refreshResponse); final MapRequest mapRequest = new MapRequest( - inputVal.toUserIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); final MappedIdentity mappedIdentity; diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index eafa14f9a..0fe848902 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -13,7 +13,6 @@ import com.uid2.operator.util.Tuple; import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.operator.vertx.UIDOperatorVerticle; -import com.uid2.operator.vertx.ClientInputValidationException; import com.uid2.shared.Utils; import com.uid2.shared.auth.ClientKey; import com.uid2.shared.auth.Keyset; @@ -27,9 +26,7 @@ import com.uid2.shared.secret.KeyHasher; import com.uid2.shared.store.*; import com.uid2.shared.store.reader.RotatingKeysetProvider; -import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Metrics; -import io.micrometer.core.instrument.search.MeterNotFoundException; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.core.AsyncResult; import io.vertx.core.Future; @@ -820,7 +817,7 @@ private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder encoder, Json validateAdvertisingToken(advertisingTokenString, getTokenVersion(), getIdentityScope(), identityType); AdvertisingToken advertisingToken = encoder.decodeAdvertisingToken(advertisingTokenString); if (getTokenVersion() == TokenVersion.V4) { - assertEquals(identityType, advertisingToken.userIdentity.identityType); + assertEquals(identityType, advertisingToken.rawUidIdentity.identityType); } return advertisingToken; } @@ -852,8 +849,8 @@ public static void validateAdvertisingToken(String advertisingTokenString, Token RefreshToken decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { RefreshToken refreshToken = encoder.decodeRefreshToken(refreshTokenString); - assertEquals(getIdentityScope(), refreshToken.userIdentity.identityScope); - assertEquals(identityType, refreshToken.userIdentity.identityType); + assertEquals(getIdentityScope(), refreshToken.firstLevelHashIdentity.identityScope); + assertEquals(identityType, refreshToken.firstLevelHashIdentity.identityType); return refreshToken; } RefreshToken decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString) { @@ -869,7 +866,7 @@ void identityMapNewClientNoPolicySpecified(String apiVersion, Vertx vertx, Vertx setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -896,7 +893,7 @@ void identityMapNewClientWrongPolicySpecified(String apiVersion, String policyPa setupSalts(); setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); JsonArray emails = new JsonArray(); @@ -1176,16 +1173,16 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi firstLevelSalt, rotatingSalt123.getSalt()); final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity(optOutTokenInput.getNormalized(), firstLevelSalt); - assertArrayEquals(advertisingId, advertisingToken.userIdentity.id); - assertArrayEquals(firstLevelHash, refreshToken.userIdentity.id); + assertArrayEquals(advertisingId, advertisingToken.rawUidIdentity.rawUid); + assertArrayEquals(firstLevelHash, refreshToken.firstLevelHashIdentity.firstLevelHash); String advertisingTokenString = body.getString("advertising_token"); final Instant now = Instant.now(); final String token = advertisingTokenString; - final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toUserIdentity(getIdentityScope(), 0, now), now); + final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDiiIdentity(getIdentityScope(), 0, now), now); assertTrue(matchedOptedOutIdentity); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertTrue(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertTrue(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertTokenStatusMetrics( 201, @@ -1231,14 +1228,14 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1273,14 +1270,14 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); RefreshToken refreshToken = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1317,16 +1314,16 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingToken advertisingToken = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshToken refreshToken = decodeRefreshToken(encoder, refreshTokenStringNew); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -1376,16 +1373,16 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT AdvertisingToken advertisingToken = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshToken refreshToken = decodeRefreshToken(encoder, refreshTokenStringNew); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -1554,11 +1551,11 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); testContext.completeNow(); }); @@ -1588,14 +1585,14 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2500,14 +2497,14 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2539,14 +2536,14 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2583,16 +2580,16 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC AdvertisingToken advertisingToken = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.userIdentity.id); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshToken refreshToken = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.userIdentity.id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -3021,7 +3018,7 @@ void tokenGenerateRespectOptOutOption(String policyParameterKey, Vertx vertx, Ve setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -3052,7 +3049,7 @@ void identityMapDefaultOption(String apiVersion, Vertx vertx, VertxTestContext t setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -3093,7 +3090,7 @@ void identityMapRespectOptOutOption(String apiVersion, String policyParameterKey setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -3984,11 +3981,11 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver final Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli()); // When we generate the token the user hasn't opted out. - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(null); final EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(UserIdentity.class); + final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(FirstLevelHashIdentity.class); sendCstg(vertx, "v2/token/client-generate", @@ -3999,7 +3996,8 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver testContext, response -> { verify(optOutStore, times(1)).getLatestEntry(argumentCaptor.capture()); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), argumentCaptor.getValue().id); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), + argumentCaptor.getValue().firstLevelHash); assertEquals("success", response.getString("status")); final JsonObject genBody = response.getJsonObject("body"); @@ -4010,8 +4008,8 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, id); // When we refresh the token the user has opted out. - when(optOutStore.getLatestEntry(any(UserIdentity.class))) - .thenReturn(advertisingToken.userIdentity.establishedAt.plusSeconds(1)); + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + .thenReturn(advertisingToken.rawUidIdentity.establishedAt.plusSeconds(1)); sendTokenRefresh("v2", vertx, testContext, genBody.getString("refresh_token"), genBody.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("optout", refreshRespJson.getString("status")); @@ -4039,11 +4037,11 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id if(optOutExpected) { - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); } else { //not expectedOptedOut - when(optOutStore.getLatestEntry(any(UserIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(null); } @@ -4203,8 +4201,8 @@ private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToke } private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { - final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingToken.userIdentity.privacyBits); - final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshToken.userIdentity.privacyBits); + final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits); + final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshToken.firstLevelHashIdentity.privacyBits); final byte[] advertisingId = getAdvertisingIdFromIdentity(identityType, identity, @@ -4223,8 +4221,8 @@ private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToke () -> assertEquals(siteId, advertisingToken.publisherIdentity.siteId, "Advertising token site ID is incorrect"), () -> assertEquals(siteId, refreshToken.publisherIdentity.siteId, "Refresh token site ID is incorrect"), - () -> assertArrayEquals(advertisingId, advertisingToken.userIdentity.id, "Advertising token ID is incorrect"), - () -> assertArrayEquals(firstLevelHash, refreshToken.userIdentity.id, "Refresh token ID is incorrect") + () -> assertArrayEquals(advertisingId, advertisingToken.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), + () -> assertArrayEquals(firstLevelHash, refreshToken.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") ); } diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 4cc327e9f..1082d0bba 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -148,12 +148,12 @@ static ICloudStorage make1mOptOutEntryStorage(String salt, List out_gene return storage; } - static UserIdentity[] createUserIdentities() { - UserIdentity[] arr = new UserIdentity[65536]; + static HashedDiiIdentity[] createUserIdentities() { + HashedDiiIdentity[] arr = new HashedDiiIdentity[65536]; for (int i = 0; i < 65536; i++) { final byte[] id = new byte[33]; new Random().nextBytes(id); - arr[i] = new UserIdentity(IdentityScope.UID2, IdentityType.Email, id, 0, + arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, id, 0, Instant.now().minusSeconds(120), Instant.now().minusSeconds(60)); } return arr; @@ -187,14 +187,14 @@ public StaticOptOutStore(ICloudStorage storage, JsonObject jsonConfig, Collectio } @Override - public Instant getLatestEntry(UserIdentity firstLevelHashIdentity) { - long epochSecond = this.snapshot.getOptOutTimestamp(firstLevelHashIdentity.id); + public Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity) { + long epochSecond = this.snapshot.getOptOutTimestamp(firstLevelHashIdentity.firstLevelHash); Instant instant = epochSecond > 0 ? Instant.ofEpochSecond(epochSecond) : null; return instant; } @Override - public void addEntry(UserIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { + public void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { // noop } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 6f9d19900..34e503d1b 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -10,13 +10,13 @@ public class IdentityMapBenchmark { private static final IUIDOperatorService uidService; - private static final UserIdentity[] userIdentities; + private static final HashedDiiIdentity[] firstLevelHashIdentities; private static int idx = 0; static { try { uidService = BenchmarkCommon.createUidOperatorService(); - userIdentities = BenchmarkCommon.createUserIdentities(); + firstLevelHashIdentities = BenchmarkCommon.createUserIdentities(); } catch (Exception e) { throw new RuntimeException(e); } @@ -25,12 +25,12 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) public MappedIdentity IdentityMapRawThroughput() { - return uidService.map(userIdentities[(idx++) & 65535], Instant.now()); + return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) public MappedIdentity IdentityMapWithOptOutThroughput() { - return uidService.mapIdentity(new MapRequest(userIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); + return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 8932b414c..08893ae91 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -13,7 +13,7 @@ public class TokenEndecBenchmark { private static final IUIDOperatorService uidService; - private static final UserIdentity[] userIdentities; + private static final HashedDiiIdentity[] userIdentities; private static final PublisherIdentity publisher; private static final EncryptedTokenEncoder encoder; private static final Identity[] generatedTokens; From 0fccf8c4732102a217f4b86cf6bcde8dcbe660ed Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 17:54:54 +1100 Subject: [PATCH 06/61] Added brief comment to Identity/MappedIdentity --- src/main/java/com/uid2/operator/model/Identity.java | 1 + src/main/java/com/uid2/operator/model/MappedIdentity.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/com/uid2/operator/model/Identity.java b/src/main/java/com/uid2/operator/model/Identity.java index fa12d7f64..62d1c8ea3 100644 --- a/src/main/java/com/uid2/operator/model/Identity.java +++ b/src/main/java/com/uid2/operator/model/Identity.java @@ -4,6 +4,7 @@ import java.time.Instant; +// this is the response of the /token/generate and /client/generate endpoints public class Identity { public static Identity InvalidIdentity = new Identity("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; diff --git a/src/main/java/com/uid2/operator/model/MappedIdentity.java b/src/main/java/com/uid2/operator/model/MappedIdentity.java index de4b368ea..055efc124 100644 --- a/src/main/java/com/uid2/operator/model/MappedIdentity.java +++ b/src/main/java/com/uid2/operator/model/MappedIdentity.java @@ -1,5 +1,6 @@ package com.uid2.operator.model; +// Contains the generated raw UID public class MappedIdentity { public static MappedIdentity OptoutIdentity = new MappedIdentity(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) From 113e8ca04f13ee04bb7a65e9f589fed6a1dbbad8 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 18:00:38 +1100 Subject: [PATCH 07/61] Renamed MappedIdentity to MappedIdentityResult --- ...dentity.java => MappedIdentityResult.java} | 8 +-- .../operator/service/IUIDOperatorService.java | 4 +- .../operator/service/UIDOperatorService.java | 22 +++---- .../operator/vertx/UIDOperatorVerticle.java | 18 +++--- .../uid2/operator/UIDOperatorServiceTest.java | 60 +++++++++---------- .../benchmark/IdentityMapBenchmark.java | 4 +- 6 files changed, 58 insertions(+), 58 deletions(-) rename src/main/java/com/uid2/operator/model/{MappedIdentity.java => MappedIdentityResult.java} (57%) diff --git a/src/main/java/com/uid2/operator/model/MappedIdentity.java b/src/main/java/com/uid2/operator/model/MappedIdentityResult.java similarity index 57% rename from src/main/java/com/uid2/operator/model/MappedIdentity.java rename to src/main/java/com/uid2/operator/model/MappedIdentityResult.java index 055efc124..08752115e 100644 --- a/src/main/java/com/uid2/operator/model/MappedIdentity.java +++ b/src/main/java/com/uid2/operator/model/MappedIdentityResult.java @@ -1,13 +1,13 @@ package com.uid2.operator.model; -// Contains the generated raw UID -public class MappedIdentity { - public static MappedIdentity OptoutIdentity = new MappedIdentity(new byte[33], ""); +// Contains the computed raw UID and its bucket ID from identity/map logic +public class MappedIdentityResult { + public static MappedIdentityResult OptoutIdentity = new MappedIdentityResult(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) public final byte[] rawUid; public final String bucketId; - public MappedIdentity(byte[] rawUid, String bucketId) { + public MappedIdentityResult(byte[] rawUid, String bucketId) { this.rawUid = rawUid; this.bucketId = bucketId; } diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index ac0dfa6c7..4e08d69d4 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -15,10 +15,10 @@ public interface IUIDOperatorService { RefreshResponse refreshIdentity(RefreshToken refreshToken); - MappedIdentity mapIdentity(MapRequest request); + MappedIdentityResult mapIdentity(MapRequest request); @Deprecated - MappedIdentity map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + MappedIdentityResult map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index a3168eefe..38a3d7d5c 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -157,18 +157,18 @@ public RefreshResponse refreshIdentity(RefreshToken token) { } @Override - public MappedIdentity mapIdentity(MapRequest request) { + public MappedIdentityResult mapIdentity(MapRequest request) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return MappedIdentity.OptoutIdentity; + return MappedIdentityResult.OptoutIdentity; } else { return generateMappedIdentity(firstLevelHashIdentity, request.asOf); } } @Override - public MappedIdentity map(HashedDiiIdentity diiIdentity, Instant asOf) { + public MappedIdentityResult map(HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); return generateMappedIdentity(firstLevelHashIdentity, asOf); } @@ -191,9 +191,9 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final MappedIdentity mappedIdentity = generateMappedIdentity(hashedDiiIdentity, asOf); + final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(hashedDiiIdentity, asOf); - this.optOutStore.addEntry(hashedDiiIdentity, mappedIdentity.rawUid, r -> { + this.optOutStore.addEntry(hashedDiiIdentity, mappedIdentityResult.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -205,10 +205,10 @@ public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, H @Override public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, asOf); + final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(firstLevelHashIdentity, asOf); final AdvertisingToken token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(mappedIdentity.rawUid, token.rawUidIdentity.rawUid); + return Arrays.equals(mappedIdentityResult.rawUid, token.rawUidIdentity.rawUid); } @Override @@ -235,10 +235,10 @@ private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private MappedIdentity generateMappedIdentity(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { + private MappedIdentityResult generateMappedIdentity(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); - return new MappedIdentity( + return new MappedIdentityResult( this.identityV3Enabled ? TokenUtils.getAdvertisingIdV3(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) @@ -249,10 +249,10 @@ private MappedIdentity generateMappedIdentity(FirstLevelHashIdentity firstLevelH private Identity generateIdentity(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final MappedIdentity mappedIdentity = generateMappedIdentity(firstLevelHashIdentity, nowUtc); + final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - mappedIdentity.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); + mappedIdentityResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encode( this.createAdvertisingToken(publisherIdentity, rawUidIdentity, nowUtc), diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 761a0f6d4..c73a593f5 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1240,11 +1240,11 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final MappedIdentity mappedIdentity = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + final MappedIdentityResult mappedIdentityResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); - jsonObject.put("advertising_id", EncodingUtils.toBase64String(mappedIdentity.rawUid)); - jsonObject.put("bucket_id", mappedIdentity.bucketId); + jsonObject.put("advertising_id", EncodingUtils.toBase64String(mappedIdentityResult.rawUid)); + jsonObject.put("bucket_id", mappedIdentityResult.bucketId); ResponseUtil.Success(rc, jsonObject); } catch (Exception e) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State", e); @@ -1263,8 +1263,8 @@ else if (!input.isValid()) { } else { final Instant now = Instant.now(); - final MappedIdentity mappedIdentity = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); - rc.response().end(EncodingUtils.toBase64String(mappedIdentity.rawUid)); + final MappedIdentityResult mappedIdentityResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + rc.response().end(EncodingUtils.toBase64String(mappedIdentityResult.rawUid)); } } catch (Exception ex) { LOGGER.error("Unexpected error while mapping identity", ex); @@ -1459,13 +1459,13 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal for (int i = 0; i < count; ++i) { final InputUtil.InputVal input = inputList[i]; if (input != null && input.isValid()) { - final MappedIdentity mappedIdentity = idService.mapIdentity( + final MappedIdentityResult mappedIdentityResult = idService.mapIdentity( new MapRequest( input.toHashedDiiIdentity(this.identityScope, 0, now), OptoutCheckPolicy.respectOptOut(), now)); - if (mappedIdentity.isOptedOut()) { + if (mappedIdentityResult.isOptedOut()) { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); resp.put("reason", "optout"); @@ -1474,8 +1474,8 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal } else { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); - resp.put("advertising_id", EncodingUtils.toBase64String(mappedIdentity.rawUid)); - resp.put("bucket_id", mappedIdentity.bucketId); + resp.put("advertising_id", EncodingUtils.toBase64String(mappedIdentityResult.rawUid)); + resp.put("bucket_id", mappedIdentityResult.bucketId); mapped.add(resp); } } else { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 8f4c66021..cef8e3240 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -326,27 +326,27 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final MappedIdentity mappedIdentity; - final MappedIdentity mappedIdentityShouldBeOptOut; + final MappedIdentityResult mappedIdentityResult; + final MappedIdentityResult mappedIdentityResultShouldBeOptOut; if (scope == IdentityScope.UID2) { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - mappedIdentity = uid2Service.mapIdentity(mapRequestForceMap); + mappedIdentityResult = uid2Service.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - mappedIdentityShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResultShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); } else { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - mappedIdentity = euidService.mapIdentity(mapRequestForceMap); + mappedIdentityResult = euidService.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - mappedIdentityShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResultShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentity); - assertFalse(mappedIdentity.isOptedOut()); - assertNotNull(mappedIdentityShouldBeOptOut); - assertTrue(mappedIdentityShouldBeOptOut.isOptedOut()); + assertNotNull(mappedIdentityResult); + assertFalse(mappedIdentityResult.isOptedOut()); + assertNotNull(mappedIdentityResultShouldBeOptOut); + assertTrue(mappedIdentityResultShouldBeOptOut.isOptedOut()); } private enum TestIdentityInputType { @@ -433,17 +433,17 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, // identity has no optout record, ensure map still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final MappedIdentity mappedIdentity; + final MappedIdentityResult mappedIdentityResult; if(scope == IdentityScope.EUID) { - mappedIdentity = euidService.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResult = euidService.mapIdentity(mapRequestRespectOptOut); } else { - mappedIdentity = uid2Service.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResult = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentity); - assertTrue(mappedIdentity.isOptedOut()); + assertNotNull(mappedIdentityResult); + assertTrue(mappedIdentityResult.isOptedOut()); } @ParameterizedTest @@ -547,17 +547,17 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str // all identities have optout records, ensure refresh-optout identities still map when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final MappedIdentity mappedIdentity; + final MappedIdentityResult mappedIdentityResult; if(scope == IdentityScope.EUID) { - mappedIdentity = euidService.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResult = euidService.mapIdentity(mapRequestRespectOptOut); } else { - mappedIdentity = uid2Service.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResult = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentity); - assertFalse(mappedIdentity.isOptedOut()); + assertNotNull(mappedIdentityResult); + assertFalse(mappedIdentityResult.isOptedOut()); } @ParameterizedTest @@ -618,17 +618,17 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i // all identities have optout records, ensure validate identities still get mapped when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final MappedIdentity mappedIdentity; + final MappedIdentityResult mappedIdentityResult; if(scope == IdentityScope.EUID) { - mappedIdentity = euidService.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResult = euidService.mapIdentity(mapRequestRespectOptOut); } else { - mappedIdentity = uid2Service.mapIdentity(mapRequestRespectOptOut); + mappedIdentityResult = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentity); - assertFalse(mappedIdentity.isOptedOut()); + assertNotNull(mappedIdentityResult); + assertFalse(mappedIdentityResult.isOptedOut()); } @ParameterizedTest @@ -736,18 +736,18 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); - final MappedIdentity mappedIdentity; + final MappedIdentityResult mappedIdentityResult; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - mappedIdentity = euidService.mapIdentity(mapRequest); + mappedIdentityResult = euidService.mapIdentity(mapRequest); } else { - mappedIdentity = uid2Service.mapIdentity(mapRequest); + mappedIdentityResult = uid2Service.mapIdentity(mapRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(mappedIdentity); - assertFalse(mappedIdentity.isOptedOut()); + assertNotNull(mappedIdentityResult); + assertFalse(mappedIdentityResult.isOptedOut()); } } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 34e503d1b..401ea1b82 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -24,13 +24,13 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) - public MappedIdentity IdentityMapRawThroughput() { + public MappedIdentityResult IdentityMapRawThroughput() { return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) - public MappedIdentity IdentityMapWithOptOutThroughput() { + public MappedIdentityResult IdentityMapWithOptOutThroughput() { return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } From ae03ff54aa2270efb6c9e124ee8921d1aa8506bb Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 18:29:08 +1100 Subject: [PATCH 08/61] 1. Rename AdvertisingToken class to AdvertisingTokenInput 2. Rename RefreshToken class to RefreshTokenInput 3. Rename createAdvertisingToken/createRefreshToken methods to createAdvertisingTokenInput/createRefreshTokenInput --- ...gToken.java => AdvertisingTokenInput.java} | 6 +- ...freshToken.java => RefreshTokenInput.java} | 6 +- .../service/EncryptedTokenEncoder.java | 46 ++-- .../uid2/operator/service/ITokenEncoder.java | 10 +- .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 20 +- .../operator/vertx/UIDOperatorVerticle.java | 10 +- .../com/uid2/operator/TokenEncodingTest.java | 8 +- .../uid2/operator/UIDOperatorServiceTest.java | 94 ++++---- .../operator/UIDOperatorVerticleTest.java | 224 +++++++++--------- 10 files changed, 213 insertions(+), 213 deletions(-) rename src/main/java/com/uid2/operator/model/{AdvertisingToken.java => AdvertisingTokenInput.java} (61%) rename src/main/java/com/uid2/operator/model/{RefreshToken.java => RefreshTokenInput.java} (62%) diff --git a/src/main/java/com/uid2/operator/model/AdvertisingToken.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java similarity index 61% rename from src/main/java/com/uid2/operator/model/AdvertisingToken.java rename to src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java index 1baa4040f..e8bc12748 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingToken.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java @@ -3,13 +3,13 @@ import java.time.Instant; import com.uid2.shared.model.TokenVersion; -public class AdvertisingToken extends VersionedToken { +public class AdvertisingTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; public final PublisherIdentity publisherIdentity; public final RawUidIdentity rawUidIdentity; - public AdvertisingToken(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity) { + public AdvertisingTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, + PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.publisherIdentity = publisherIdentity; diff --git a/src/main/java/com/uid2/operator/model/RefreshToken.java b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java similarity index 62% rename from src/main/java/com/uid2/operator/model/RefreshToken.java rename to src/main/java/com/uid2/operator/model/RefreshTokenInput.java index 5768fd9a8..f734a954a 100644 --- a/src/main/java/com/uid2/operator/model/RefreshToken.java +++ b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java @@ -3,13 +3,13 @@ import java.time.Instant; import com.uid2.shared.model.TokenVersion; -public class RefreshToken extends VersionedToken { +public class RefreshTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; public final PublisherIdentity publisherIdentity; public final FirstLevelHashIdentity firstLevelHashIdentity; - public RefreshToken(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity) { + public RefreshTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, + PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.publisherIdentity = publisherIdentity; diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 1814946db..d65977d74 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -22,7 +22,7 @@ public EncryptedTokenEncoder(KeyManager keyManager) { this.keyManager = keyManager; } - public byte[] encode(AdvertisingToken t, Instant asOf) { + public byte[] encode(AdvertisingTokenInput t, Instant asOf) { final KeysetKey masterKey = this.keyManager.getMasterKey(asOf); final KeysetKey siteEncryptionKey = this.keyManager.getActiveKeyBySiteIdWithFallback(t.publisherIdentity.siteId, Data.AdvertisingTokenSiteId, asOf); @@ -31,7 +31,7 @@ public byte[] encode(AdvertisingToken t, Instant asOf) { : encodeV3(t, masterKey, siteEncryptionKey); //TokenVersion.V4 also calls encodeV3() since the byte array is identical between V3 and V4 } - private byte[] encodeV2(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteKey) { + private byte[] encodeV2(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer b = Buffer.buffer(); b.appendByte((byte) t.version.rawVersion); @@ -48,7 +48,7 @@ private byte[] encodeV2(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteK return b.getBytes(); } - private byte[] encodeV3(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteKey) { + private byte[] encodeV3(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer sitePayload = Buffer.buffer(69); encodePublisherIdentityV3(sitePayload, t.publisherIdentity); sitePayload.appendInt(t.rawUidIdentity.privacyBits); @@ -73,7 +73,7 @@ private byte[] encodeV3(AdvertisingToken t, KeysetKey masterKey, KeysetKey siteK } @Override - public RefreshToken decodeRefreshToken(String s) { + public RefreshTokenInput decodeRefreshToken(String s) { if (s != null && !s.isEmpty()) { final byte[] bytes; try { @@ -92,7 +92,7 @@ public RefreshToken decodeRefreshToken(String s) { throw new ClientInputValidationException("Invalid refresh token version"); } - private RefreshToken decodeRefreshTokenV2(Buffer b) { + private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { final Instant createdAt = Instant.ofEpochMilli(b.getLong(1)); //final Instant expiresAt = Instant.ofEpochMilli(b.getLong(9)); final Instant validTill = Instant.ofEpochMilli(b.getLong(17)); @@ -120,7 +120,7 @@ private RefreshToken decodeRefreshTokenV2(Buffer b) { final int privacyBits = b2.getInt(8 + length); final long establishedMillis = b2.getLong(8 + length + 4); - return new RefreshToken( + return new RefreshTokenInput( TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), new PublisherIdentity(siteId, 0, 0), @@ -128,7 +128,7 @@ private RefreshToken decodeRefreshTokenV2(Buffer b) { Instant.ofEpochMilli(establishedMillis), null)); } - private RefreshToken decodeRefreshTokenV3(Buffer b, byte[] bytes) { + private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { final int keyId = b.getInt(2); final KeysetKey key = this.keyManager.getKey(keyId); @@ -156,13 +156,13 @@ private RefreshToken decodeRefreshTokenV3(Buffer b, byte[] bytes) { throw new ClientInputValidationException("Failed to decode refreshTokenV3: Identity type mismatch"); } - return new RefreshToken( + return new RefreshTokenInput( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, publisherIdentity, new FirstLevelHashIdentity(identityScope, identityType, id, privacyBits, establishedAt, null)); } @Override - public AdvertisingToken decodeAdvertisingToken(String base64AdvertisingToken) { + public AdvertisingTokenInput decodeAdvertisingToken(String base64AdvertisingToken) { //Logic and code copied from: https://github.com/IABTechLab/uid2-client-java/blob/0220ef43c1661ecf3b8f4ed2db524e2db31c06b5/src/main/java/com/uid2/client/Uid2Encryption.java#L37 if (base64AdvertisingToken.length() < 4) { throw new ClientInputValidationException("Advertising token is too short"); @@ -197,7 +197,7 @@ public AdvertisingToken decodeAdvertisingToken(String base64AdvertisingToken) { return decodeAdvertisingTokenV3orV4(b, bytes, tokenVersion); } - public AdvertisingToken decodeAdvertisingTokenV2(Buffer b) { + public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { try { final int masterKeyId = b.getInt(1); @@ -220,7 +220,7 @@ public AdvertisingToken decodeAdvertisingTokenV2(Buffer b) { final int privacyBits = b3.getInt(8 + length); final long establishedMillis = b3.getLong(8 + length + 4); - return new AdvertisingToken( + return new AdvertisingTokenInput( TokenVersion.V2, Instant.ofEpochMilli(establishedMillis), Instant.ofEpochMilli(expiresMillis), @@ -236,7 +236,7 @@ public AdvertisingToken decodeAdvertisingTokenV2(Buffer b) { } - public AdvertisingToken decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, TokenVersion tokenVersion) { + public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, TokenVersion tokenVersion) { final int masterKeyId = b.getInt(2); final byte[] masterPayloadBytes = AesGcm.decrypt(bytes, 6, this.keyManager.getKey(masterKeyId)); @@ -265,7 +265,7 @@ public AdvertisingToken decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, Tok } } - return new AdvertisingToken( + return new AdvertisingTokenInput( tokenVersion, createdAt, expiresAt, operatorIdentity, publisherIdentity, new RawUidIdentity(identityScope, identityType, id, privacyBits, establishedAt, refreshedAt) ); @@ -279,7 +279,7 @@ private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVer .register(Metrics.globalRegistry).increment(); } - public byte[] encode(RefreshToken t, Instant asOf) { + public byte[] encode(RefreshTokenInput t, Instant asOf) { final KeysetKey serviceKey = this.keyManager.getRefreshKey(asOf); switch (t.version) { @@ -294,7 +294,7 @@ public byte[] encode(RefreshToken t, Instant asOf) { } } - public byte[] encodeV2(RefreshToken t, KeysetKey serviceKey) { + public byte[] encodeV2(RefreshTokenInput t, KeysetKey serviceKey) { final Buffer b = Buffer.buffer(); b.appendByte((byte) t.version.rawVersion); b.appendLong(t.createdAt.toEpochMilli()); @@ -307,7 +307,7 @@ public byte[] encodeV2(RefreshToken t, KeysetKey serviceKey) { return b.getBytes(); } - public byte[] encodeV3(RefreshToken t, KeysetKey serviceKey) { + public byte[] encodeV3(RefreshTokenInput t, KeysetKey serviceKey) { final Buffer refreshPayload = Buffer.buffer(90); refreshPayload.appendLong(t.expiresAt.toEpochMilli()); refreshPayload.appendLong(t.createdAt.toEpochMilli()); @@ -340,17 +340,17 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi } @Override - public Identity encode(AdvertisingToken advertisingToken, RefreshToken refreshToken, Instant refreshFrom, Instant asOf) { + public Identity encode(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { - final byte[] advertisingTokenBytes = encode(advertisingToken, asOf); - final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingToken.version); + final byte[] advertisingTokenBytes = encode(advertisingTokenInput, asOf); + final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); return new Identity( base64AdvertisingToken, - advertisingToken.version, - EncodingUtils.toBase64String(encode(refreshToken, asOf)), - advertisingToken.expiresAt, - refreshToken.expiresAt, + advertisingTokenInput.version, + EncodingUtils.toBase64String(encode(refreshTokenInput, asOf)), + advertisingTokenInput.expiresAt, + refreshTokenInput.expiresAt, refreshFrom ); } diff --git a/src/main/java/com/uid2/operator/service/ITokenEncoder.java b/src/main/java/com/uid2/operator/service/ITokenEncoder.java index c0303247e..07811124a 100644 --- a/src/main/java/com/uid2/operator/service/ITokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/ITokenEncoder.java @@ -1,15 +1,15 @@ package com.uid2.operator.service; -import com.uid2.operator.model.AdvertisingToken; +import com.uid2.operator.model.AdvertisingTokenInput; import com.uid2.operator.model.Identity; -import com.uid2.operator.model.RefreshToken; +import com.uid2.operator.model.RefreshTokenInput; import java.time.Instant; public interface ITokenEncoder { - Identity encode(AdvertisingToken advertisingToken, RefreshToken refreshToken, Instant refreshFrom, Instant asOf); + Identity encode(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf); - AdvertisingToken decodeAdvertisingToken(String base64String); + AdvertisingTokenInput decodeAdvertisingToken(String base64String); - RefreshToken decodeRefreshToken(String base64String); + RefreshTokenInput decodeRefreshToken(String base64String); } diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 4e08d69d4..630d20423 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -13,7 +13,7 @@ public interface IUIDOperatorService { Identity generateIdentity(IdentityRequest request); - RefreshResponse refreshIdentity(RefreshToken refreshToken); + RefreshResponse refreshIdentity(RefreshTokenInput refreshTokenInput); MappedIdentityResult mapIdentity(MapRequest request); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 38a3d7d5c..b2bf55daf 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -117,7 +117,7 @@ public Identity generateIdentity(IdentityRequest request) { } @Override - public RefreshResponse refreshIdentity(RefreshToken token) { + public RefreshResponse refreshIdentity(RefreshTokenInput token) { // should not be possible as different scopes should be using different keys, but just in case if (token.firstLevelHashIdentity.identityScope != this.identityScope) { return RefreshResponse.Invalid; @@ -207,7 +207,7 @@ public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentit final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(firstLevelHashIdentity, asOf); - final AdvertisingToken token = this.encoder.decodeAdvertisingToken(advertisingToken); + final AdvertisingTokenInput token = this.encoder.decodeAdvertisingToken(advertisingToken); return Arrays.equals(mappedIdentityResult.rawUid, token.rawUidIdentity.rawUid); } @@ -255,16 +255,16 @@ private Identity generateIdentity(PublisherIdentity publisherIdentity, FirstLeve mappedIdentityResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encode( - this.createAdvertisingToken(publisherIdentity, rawUidIdentity, nowUtc), - this.createRefreshToken(publisherIdentity, firstLevelHashIdentity, nowUtc), + this.createAdvertisingTokenInput(publisherIdentity, rawUidIdentity, nowUtc), + this.createRefreshTokenInput(publisherIdentity, firstLevelHashIdentity, nowUtc), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc ); } - private RefreshToken createRefreshToken(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity, - Instant now) { - return new RefreshToken( + private RefreshTokenInput createRefreshTokenInput(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity, + Instant now) { + return new RefreshTokenInput( this.refreshTokenVersion, now, now.plusMillis(refreshExpiresAfter.toMillis()), @@ -273,8 +273,8 @@ private RefreshToken createRefreshToken(PublisherIdentity publisherIdentity, Fir firstLevelHashIdentity); } - private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, - Instant now) { + private AdvertisingTokenInput createAdvertisingTokenInput(PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, + Instant now) { TokenVersion tokenVersion; if (siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) { tokenVersion = TokenVersion.V4; @@ -288,7 +288,7 @@ private AdvertisingToken createAdvertisingToken(PublisherIdentity publisherIdent } tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } - return new AdvertisingToken(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, rawUidIdentity); + return new AdvertisingTokenInput(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, rawUidIdentity); } static protected class GlobalOptoutResult { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index c73a593f5..b4112ba2e 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1774,25 +1774,25 @@ private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVer } private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { - final RefreshToken refreshToken; + final RefreshTokenInput refreshTokenInput; try { if (AuthMiddleware.isAuthenticated(rc)) { rc.put(Const.RoutingContextData.SiteId, AuthMiddleware.getAuthClient(ClientKey.class, rc).getSiteId()); } - refreshToken = this.encoder.decodeRefreshToken(tokenStr); + refreshTokenInput = this.encoder.decodeRefreshToken(tokenStr); } catch (ClientInputValidationException cie) { LOGGER.warn("Failed to decode refresh token for site ID: " + rc.data().get(Const.RoutingContextData.SiteId), cie); return RefreshResponse.Invalid; } - if (refreshToken == null) { + if (refreshTokenInput == null) { return RefreshResponse.Invalid; } if (!AuthMiddleware.isAuthenticated(rc)) { - rc.put(Const.RoutingContextData.SiteId, refreshToken.publisherIdentity.siteId); + rc.put(Const.RoutingContextData.SiteId, refreshTokenInput.publisherIdentity.siteId); } recordRefreshTokenVersionCount(String.valueOf(rc.data().get(Const.RoutingContextData.SiteId)), this.getRefreshTokenVersion(tokenStr)); - return this.idService.refreshIdentity(refreshToken); + return this.idService.refreshIdentity(refreshTokenInput); } public static String getSiteName(ISiteStore siteStore, Integer siteId) { diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index ef509cc70..b7671149f 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -52,7 +52,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity("test@example.com", "some-salt"); - final RefreshToken token = new RefreshToken(tokenVersion, + final RefreshTokenInput token = new RefreshTokenInput(tokenVersion, now, now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), @@ -65,7 +65,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { return; //V4 not supported for RefreshTokens } final byte[] encodedBytes = encoder.encode(token, now); - final RefreshToken decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); + final RefreshTokenInput decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); assertEquals(tokenVersion, decoded.version); assertEquals(token.createdAt, decoded.createdAt); @@ -93,7 +93,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { final byte[] rawUid = UIDOperatorVerticleTest.getRawUid(IdentityType.Email, "test@example.com", IdentityScope.UID2, tokenVersion != TokenVersion.V2); - final AdvertisingToken token = new AdvertisingToken( + final AdvertisingTokenInput token = new AdvertisingTokenInput( tokenVersion, now, now.plusSeconds(60), @@ -103,7 +103,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { ); final byte[] encodedBytes = encoder.encode(token, now); - final AdvertisingToken decoded = encoder.decodeAdvertisingToken(EncryptedTokenEncoder.bytesToBase64Token(encodedBytes, tokenVersion)); + final AdvertisingTokenInput decoded = encoder.decodeAdvertisingToken(EncryptedTokenEncoder.bytesToBase64Token(encodedBytes, tokenVersion)); assertEquals(tokenVersion, decoded.version); assertEquals(token.createdAt, decoded.createdAt); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index cef8e3240..52068337b 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -134,7 +134,7 @@ private HashedDiiIdentity createHashedDiiIdentity(String rawIdentityHash, Identi ); } - private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, IdentityType type, int siteId) { + private AdvertisingTokenInput validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, IdentityType type, int siteId) { TokenVersion tokenVersion = (scope == IdentityScope.UID2) ? uid2Service.getAdvertisingTokenVersionForTests(siteId) : euidService.getAdvertisingTokenVersionForTests(siteId); UIDOperatorVerticleTest.validateAdvertisingToken(advertisingTokenString, tokenVersion, scope, type); return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); @@ -161,20 +161,20 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertNotNull(identity); UIDOperatorVerticleTest.validateAdvertisingToken(identity.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingToken advertisingToken = tokenEncoder.decodeAdvertisingToken(identity.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken.expiresAt); - assertEquals(identityRequest.publisherIdentity.siteId, advertisingToken.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, advertisingToken.rawUidIdentity); + AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identity.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); + assertEquals(identityRequest.publisherIdentity.siteId, advertisingTokenInput.publisherIdentity.siteId); + assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); - RefreshToken refreshToken = tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); - assertEquals(this.now, refreshToken.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken.expiresAt); - assertEquals(identityRequest.publisherIdentity.siteId, refreshToken.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, refreshToken.firstLevelHashIdentity); + RefreshTokenInput refreshTokenInput = tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + assertEquals(this.now, refreshTokenInput.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput.expiresAt); + assertEquals(identityRequest.publisherIdentity.siteId, refreshTokenInput.publisherIdentity.siteId); + assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, refreshTokenInput.firstLevelHashIdentity); setNow(Instant.now().plusSeconds(200)); reset(shutdownHandler); - final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshToken); + final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshTokenInput); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(refreshResponse); @@ -182,20 +182,20 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertNotNull(refreshResponse.getIdentity()); UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingToken advertisingToken2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken()); - assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingToken2.expiresAt); - assertEquals(advertisingToken.publisherIdentity.siteId, advertisingToken2.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingToken.rawUidIdentity, - advertisingToken2.rawUidIdentity); - assertArrayEquals(advertisingToken.rawUidIdentity.rawUid, - advertisingToken2.rawUidIdentity.rawUid); - - RefreshToken refreshToken2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentity().getRefreshToken()); - assertEquals(this.now, refreshToken2.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshToken2.expiresAt); - assertEquals(refreshToken.publisherIdentity.siteId, refreshToken2.publisherIdentity.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(refreshToken.firstLevelHashIdentity, refreshToken2.firstLevelHashIdentity); - assertArrayEquals(refreshToken.firstLevelHashIdentity.firstLevelHash, refreshToken2.firstLevelHashIdentity.firstLevelHash); + AdvertisingTokenInput advertisingTokenInput2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken()); + assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput2.expiresAt); + assertEquals(advertisingTokenInput.publisherIdentity.siteId, advertisingTokenInput2.publisherIdentity.siteId); + assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingTokenInput.rawUidIdentity, + advertisingTokenInput2.rawUidIdentity); + assertArrayEquals(advertisingTokenInput.rawUidIdentity.rawUid, + advertisingTokenInput2.rawUidIdentity.rawUid); + + RefreshTokenInput refreshTokenInput2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentity().getRefreshToken()); + assertEquals(this.now, refreshTokenInput2.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput2.expiresAt); + assertEquals(refreshTokenInput.publisherIdentity.siteId, refreshTokenInput2.publisherIdentity.siteId); + assertIdentityScopeIdentityTypeAndEstablishedAt(refreshTokenInput.firstLevelHashIdentity, refreshTokenInput2.firstLevelHashIdentity); + assertArrayEquals(refreshTokenInput.firstLevelHashIdentity.firstLevelHash, refreshTokenInput2.firstLevelHashIdentity.firstLevelHash); } @Test @@ -213,8 +213,8 @@ public void testTestOptOutKey_DoNotRespectOptout() { assertNotNull(identity); assertFalse(identity.isEmptyToken()); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); - assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshToken)); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenInput)); } @Test @@ -247,9 +247,9 @@ public void testTestOptOutKeyIdentityScopeMismatch() { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshToken)); + assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshTokenInput)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -276,13 +276,13 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); final Identity identity; - final AdvertisingToken advertisingToken; + final AdvertisingTokenInput advertisingTokenInput; final Identity identityAfterOptOut; if (scope == IdentityScope.UID2) { identity = uid2Service.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); identityAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); @@ -290,14 +290,14 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit identity = euidService.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); reset(shutdownHandler); identityAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); - assertNotNull(advertisingToken.rawUidIdentity); + assertNotNull(advertisingTokenInput.rawUidIdentity); assertNotNull(identityAfterOptOut); assertTrue(identityAfterOptOut.getAdvertisingToken() == null || identityAfterOptOut.getAdvertisingToken().isEmpty()); @@ -479,9 +479,9 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken)); + assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -521,9 +521,9 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken)); + assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -582,19 +582,19 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); Identity identity; - AdvertisingToken advertisingToken; + AdvertisingTokenInput advertisingTokenInput; if (scope == IdentityScope.EUID) { identity = euidService.generateIdentity(identityRequest); } else { identity = uid2Service.generateIdentity(identityRequest); } - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); assertNotEquals(Identity.InvalidIdentity, identity); - assertNotNull(advertisingToken.rawUidIdentity); + assertNotNull(advertisingTokenInput.rawUidIdentity); } @@ -657,8 +657,8 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop assertNotEquals(identity, Identity.InvalidIdentity); assertNotNull(identity); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); - RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput); assertTrue(refreshResponse.isRefreshed()); assertNotNull(refreshResponse.getIdentity()); assertNotEquals(RefreshResponse.Optout, refreshResponse); @@ -707,25 +707,25 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String OptoutCheckPolicy.RespectOptOut); Identity identity; - AdvertisingToken advertisingToken; + AdvertisingTokenInput advertisingTokenInput; reset(shutdownHandler); if(scope == IdentityScope.EUID) { identity = euidService.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); } else { identity = uid2Service.generateIdentity(identityRequest); - advertisingToken = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(identity); assertNotEquals(Identity.InvalidIdentity, identity); - assertNotNull(advertisingToken.rawUidIdentity); + assertNotNull(advertisingTokenInput.rawUidIdentity); - final RefreshToken refreshToken = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); reset(shutdownHandler); - RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshToken); + RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertTrue(refreshResponse.isRefreshed()); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 0fe848902..74652f014 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -812,14 +812,14 @@ private void assertStatsCollector(String path, String referer, String apiContact assertEquals(siteId, messageItem.getSiteId()); } - private AdvertisingToken validateAndGetToken(EncryptedTokenEncoder encoder, JsonObject body, IdentityType identityType) { //See UID2-79+Token+and+ID+format+v3 + private AdvertisingTokenInput validateAndGetToken(EncryptedTokenEncoder encoder, JsonObject body, IdentityType identityType) { //See UID2-79+Token+and+ID+format+v3 final String advertisingTokenString = body.getString("advertising_token"); validateAdvertisingToken(advertisingTokenString, getTokenVersion(), getIdentityScope(), identityType); - AdvertisingToken advertisingToken = encoder.decodeAdvertisingToken(advertisingTokenString); + AdvertisingTokenInput advertisingTokenInput = encoder.decodeAdvertisingToken(advertisingTokenString); if (getTokenVersion() == TokenVersion.V4) { - assertEquals(identityType, advertisingToken.rawUidIdentity.identityType); + assertEquals(identityType, advertisingTokenInput.rawUidIdentity.identityType); } - return advertisingToken; + return advertisingTokenInput; } public static void validateAdvertisingToken(String advertisingTokenString, TokenVersion tokenVersion, IdentityScope identityScope, IdentityType identityType) { @@ -847,13 +847,13 @@ public static void validateAdvertisingToken(String advertisingTokenString, Token } } - RefreshToken decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { - RefreshToken refreshToken = encoder.decodeRefreshToken(refreshTokenString); - assertEquals(getIdentityScope(), refreshToken.firstLevelHashIdentity.identityScope); - assertEquals(identityType, refreshToken.firstLevelHashIdentity.identityType); - return refreshToken; + RefreshTokenInput decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { + RefreshTokenInput refreshTokenInput = encoder.decodeRefreshToken(refreshTokenString); + assertEquals(getIdentityScope(), refreshTokenInput.firstLevelHashIdentity.identityScope); + assertEquals(identityType, refreshTokenInput.firstLevelHashIdentity.identityType); + return refreshTokenInput; } - RefreshToken decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString) { + RefreshTokenInput decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString) { return decodeRefreshToken(encoder, refreshTokenString, IdentityType.Email); } @@ -1166,23 +1166,23 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, identityType); - RefreshToken refreshToken = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, identityType); + RefreshTokenInput refreshTokenInput = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); final byte[] advertisingId = getAdvertisingIdFromIdentity(identityType, optOutTokenInput.getNormalized(), firstLevelSalt, rotatingSalt123.getSalt()); final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity(optOutTokenInput.getNormalized(), firstLevelSalt); - assertArrayEquals(advertisingId, advertisingToken.rawUidIdentity.rawUid); - assertArrayEquals(firstLevelHash, refreshToken.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(advertisingId, advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); String advertisingTokenString = body.getString("advertising_token"); final Instant now = Instant.now(); final String token = advertisingTokenString; final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDiiIdentity(getIdentityScope(), 0, now), now); assertTrue(matchedOptedOutIdentity); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertTrue(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertTrue(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertTokenStatusMetrics( 201, @@ -1226,16 +1226,16 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1268,16 +1268,16 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshToken refreshToken = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1312,18 +1312,18 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertNotNull(refreshBody); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, refreshBody, IdentityType.Email); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshToken refreshToken = decodeRefreshToken(encoder, refreshTokenStringNew); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -1371,18 +1371,18 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT assertNotNull(refreshBody); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, refreshBody, IdentityType.Email); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshToken refreshToken = decodeRefreshToken(encoder, refreshTokenStringNew); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -1549,13 +1549,13 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); testContext.completeNow(); }); @@ -1583,16 +1583,16 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2495,16 +2495,16 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Phone); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2534,16 +2534,16 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Phone); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshToken refreshToken = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2578,18 +2578,18 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertNotNull(refreshBody); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingToken.rawUidIdentity.rawUid); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshToken refreshToken = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); - assertEquals(clientSiteId, refreshToken.publisherIdentity.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshToken.firstLevelHashIdentity.firstLevelHash); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); + assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -4002,14 +4002,14 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver assertEquals("success", response.getString("status")); final JsonObject genBody = response.getJsonObject("body"); - final AdvertisingToken advertisingToken = validateAndGetToken(encoder, genBody, identityType); - final RefreshToken refreshToken = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); + final AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, genBody, identityType); + final RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); - assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); // When we refresh the token the user has opted out. when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) - .thenReturn(advertisingToken.rawUidIdentity.establishedAt.plusSeconds(1)); + .thenReturn(advertisingTokenInput.rawUidIdentity.establishedAt.plusSeconds(1)); sendTokenRefresh("v2", vertx, testContext, genBody.getString("refresh_token"), genBody.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("optout", refreshRespJson.getString("status")); @@ -4066,11 +4066,11 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id decodeV2RefreshToken(respJson); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, genBody, identityType); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, genBody, identityType); - RefreshToken refreshToken = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); - assertAreClientSideGeneratedTokens(advertisingToken, refreshToken, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_from")), 10); @@ -4091,13 +4091,13 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id EncryptedTokenEncoder encoder2 = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); //make sure the new advertising token from refresh looks right - AdvertisingToken adTokenFromRefresh = validateAndGetToken(encoder2, refreshBody, identityType); + AdvertisingTokenInput adTokenFromRefresh = validateAndGetToken(encoder2, refreshBody, identityType); String refreshTokenStringNew = refreshBody.getString("decrypted_refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshToken refreshTokenAfterRefresh = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); + RefreshTokenInput refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); - assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefresh, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_from")), 10); @@ -4191,18 +4191,18 @@ void cstgInvalidInput(String identityType, String rawUID, Vertx vertx, VertxTest }); } - private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity) { - assertAreClientSideGeneratedTokens(advertisingToken, - refreshToken, + private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, int siteId, IdentityType identityType, String identity) { + assertAreClientSideGeneratedTokens(advertisingTokenInput, + refreshTokenInput, siteId, identityType, identity, false); } - private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToken, RefreshToken refreshToken, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { - final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingToken.rawUidIdentity.privacyBits); - final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshToken.firstLevelHashIdentity.privacyBits); + private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { + final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits); + final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshTokenInput.firstLevelHashIdentity.privacyBits); final byte[] advertisingId = getAdvertisingIdFromIdentity(identityType, identity, @@ -4218,11 +4218,11 @@ private void assertAreClientSideGeneratedTokens(AdvertisingToken advertisingToke () -> assertTrue(refreshTokenPrivacyBits.isClientSideTokenGenerated(), "Refresh token privacy bits CSTG flag is incorrect"), () -> assertEquals(expectedOptOut, refreshTokenPrivacyBits.isClientSideTokenOptedOut(), "Refresh token privacy bits CSTG optout flag is incorrect"), - () -> assertEquals(siteId, advertisingToken.publisherIdentity.siteId, "Advertising token site ID is incorrect"), - () -> assertEquals(siteId, refreshToken.publisherIdentity.siteId, "Refresh token site ID is incorrect"), + () -> assertEquals(siteId, advertisingTokenInput.publisherIdentity.siteId, "Advertising token site ID is incorrect"), + () -> assertEquals(siteId, refreshTokenInput.publisherIdentity.siteId, "Refresh token site ID is incorrect"), - () -> assertArrayEquals(advertisingId, advertisingToken.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), - () -> assertArrayEquals(firstLevelHash, refreshToken.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") + () -> assertArrayEquals(advertisingId, advertisingTokenInput.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), + () -> assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") ); } @@ -4452,16 +4452,16 @@ void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTe assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingToken advertisingToken = validateAndGetToken(encoder, body, IdentityType.Email); - assertEquals(clientSiteId, advertisingToken.publisherIdentity.siteId); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); + assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); //Uses a key from default keyset int clientKeyId; - if (advertisingToken.version == TokenVersion.V3 || advertisingToken.version == TokenVersion.V4) { + if (advertisingTokenInput.version == TokenVersion.V3 || advertisingTokenInput.version == TokenVersion.V4) { String advertisingTokenString = body.getString("advertising_token"); byte[] bytes = null; - if (advertisingToken.version == TokenVersion.V3) { + if (advertisingTokenInput.version == TokenVersion.V3) { bytes = EncodingUtils.fromBase64(advertisingTokenString); - } else if (advertisingToken.version == TokenVersion.V4) { + } else if (advertisingTokenInput.version == TokenVersion.V4) { bytes = Uid2Base64UrlCoder.decode(advertisingTokenString); //same as V3 but use Base64URL encoding } final Buffer b = Buffer.buffer(bytes); @@ -4471,7 +4471,7 @@ void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTe final Buffer masterPayload = Buffer.buffer(masterPayloadBytes); clientKeyId = masterPayload.getInt(29); } else { - clientKeyId = advertisingToken.publisherIdentity.clientKeyId; + clientKeyId = advertisingTokenInput.publisherIdentity.clientKeyId; } switch (testRun) { case "MultiKeysets": From 5595a1592d0a3b15ed8d426bca452f03963191d6 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 18:35:22 +1100 Subject: [PATCH 09/61] Renamed ITokenEncoder.encode to ITokenEncoder.encodeIntoIdentityResponse --- .../java/com/uid2/operator/service/EncryptedTokenEncoder.java | 2 +- src/main/java/com/uid2/operator/service/ITokenEncoder.java | 2 +- src/main/java/com/uid2/operator/service/UIDOperatorService.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index d65977d74..c118134b9 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -340,7 +340,7 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi } @Override - public Identity encode(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { + public Identity encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { final byte[] advertisingTokenBytes = encode(advertisingTokenInput, asOf); final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); diff --git a/src/main/java/com/uid2/operator/service/ITokenEncoder.java b/src/main/java/com/uid2/operator/service/ITokenEncoder.java index 07811124a..c0c1594c4 100644 --- a/src/main/java/com/uid2/operator/service/ITokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/ITokenEncoder.java @@ -7,7 +7,7 @@ import java.time.Instant; public interface ITokenEncoder { - Identity encode(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf); + Identity encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf); AdvertisingTokenInput decodeAdvertisingToken(String base64String); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index b2bf55daf..dfd65ed14 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -254,7 +254,7 @@ private Identity generateIdentity(PublisherIdentity publisherIdentity, FirstLeve firstLevelHashIdentity.identityType, mappedIdentityResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); - return this.encoder.encode( + return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenInput(publisherIdentity, rawUidIdentity, nowUtc), this.createRefreshTokenInput(publisherIdentity, firstLevelHashIdentity, nowUtc), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), From c6bc08f2188ffd9b3a06d8c5ac0a0dcc96ac3bad Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 18:42:42 +1100 Subject: [PATCH 10/61] Renamed Identity.isEmptyToken method to Identity.isNotValid --- src/main/java/com/uid2/operator/model/Identity.java | 2 +- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 4 ++-- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/Identity.java b/src/main/java/com/uid2/operator/model/Identity.java index 62d1c8ea3..b5ebdb74d 100644 --- a/src/main/java/com/uid2/operator/model/Identity.java +++ b/src/main/java/com/uid2/operator/model/Identity.java @@ -48,7 +48,7 @@ public Instant getRefreshFrom() { return refreshFrom; } - public boolean isEmptyToken() { + public boolean isNotValid() { return advertisingToken == null || advertisingToken.isEmpty(); } } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index b4112ba2e..081be9d34 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -473,7 +473,7 @@ else if(emailHash != null) { JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; - if (identity.isEmptyToken()) { + if (identity.isNotValid()) { response = ResponseUtil.SuccessNoBodyV2(ResponseStatus.OptOut); responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } @@ -998,7 +998,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.respectOptOut())); - if (t.isEmptyToken()) { + if (t.isNotValid()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy final InputUtil.InputVal optOutTokenInput = input.getIdentityType() == IdentityType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 52068337b..4d342fdf9 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -211,7 +211,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); - assertFalse(identity.isEmptyToken()); + assertFalse(identity.isNotValid()); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenInput)); @@ -227,7 +227,7 @@ public void testTestOptOutKey_RespectOptout() { OptoutCheckPolicy.RespectOptOut ); final Identity identity = uid2Service.generateIdentity(identityRequest); - assertTrue(identity.isEmptyToken()); + assertTrue(identity.isNotValid()); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); } From 639b799c34f446c4a3d22da559e1001eacfc8329 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 19:12:20 +1100 Subject: [PATCH 11/61] Renamed PublisherIdentity to SourcePublisher --- .../operator/model/AdvertisingTokenInput.java | 6 +-- .../uid2/operator/model/IdentityRequest.java | 6 +-- .../operator/model/RefreshTokenInput.java | 6 +-- ...sherIdentity.java => SourcePublisher.java} | 5 +- .../service/EncryptedTokenEncoder.java | 54 +++++++++---------- .../operator/service/UIDOperatorService.java | 20 +++---- .../operator/vertx/UIDOperatorVerticle.java | 12 ++--- .../com/uid2/operator/TokenEncodingTest.java | 8 +-- .../uid2/operator/UIDOperatorServiceTest.java | 42 +++++++-------- .../operator/UIDOperatorVerticleTest.java | 44 +++++++-------- .../operator/benchmark/BenchmarkCommon.java | 4 +- .../benchmark/TokenEndecBenchmark.java | 4 +- 12 files changed, 106 insertions(+), 105 deletions(-) rename src/main/java/com/uid2/operator/model/{PublisherIdentity.java => SourcePublisher.java} (59%) diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java index e8bc12748..02571b2f3 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java @@ -5,14 +5,14 @@ public class AdvertisingTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; - public final PublisherIdentity publisherIdentity; + public final SourcePublisher sourcePublisher; public final RawUidIdentity rawUidIdentity; public AdvertisingTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity) { + SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; - this.publisherIdentity = publisherIdentity; + this.sourcePublisher = sourcePublisher; this.rawUidIdentity = rawUidIdentity; } } diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index 0a60bf0cd..26eaf916e 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -1,16 +1,16 @@ package com.uid2.operator.model; public final class IdentityRequest { - public final PublisherIdentity publisherIdentity; + public final SourcePublisher sourcePublisher; public final HashedDiiIdentity hashedDiiIdentity; public final OptoutCheckPolicy optoutCheckPolicy; public IdentityRequest( - PublisherIdentity publisherIdentity, + SourcePublisher sourcePublisher, HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy) { - this.publisherIdentity = publisherIdentity; + this.sourcePublisher = sourcePublisher; this.hashedDiiIdentity = hashedDiiIdentity; this.optoutCheckPolicy = tokenGeneratePolicy; } diff --git a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java index f734a954a..426fd3ce7 100644 --- a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java +++ b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java @@ -5,14 +5,14 @@ public class RefreshTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; - public final PublisherIdentity publisherIdentity; + public final SourcePublisher sourcePublisher; public final FirstLevelHashIdentity firstLevelHashIdentity; public RefreshTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity) { + SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; - this.publisherIdentity = publisherIdentity; + this.sourcePublisher = sourcePublisher; this.firstLevelHashIdentity = firstLevelHashIdentity; } } diff --git a/src/main/java/com/uid2/operator/model/PublisherIdentity.java b/src/main/java/com/uid2/operator/model/SourcePublisher.java similarity index 59% rename from src/main/java/com/uid2/operator/model/PublisherIdentity.java rename to src/main/java/com/uid2/operator/model/SourcePublisher.java index d7a0fae57..4f13fd53e 100644 --- a/src/main/java/com/uid2/operator/model/PublisherIdentity.java +++ b/src/main/java/com/uid2/operator/model/SourcePublisher.java @@ -1,11 +1,12 @@ package com.uid2.operator.model; -public class PublisherIdentity { +// The original publisher that requests to generate a UID token +public class SourcePublisher { public final int siteId; public final int clientKeyId; public final long publisherId; - public PublisherIdentity(int siteId, int clientKeyId, long publisherId) { + public SourcePublisher(int siteId, int clientKeyId, long publisherId) { this.siteId = siteId; this.clientKeyId = clientKeyId; this.publisherId = publisherId; diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index c118134b9..64d686b4d 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -24,7 +24,7 @@ public EncryptedTokenEncoder(KeyManager keyManager) { public byte[] encode(AdvertisingTokenInput t, Instant asOf) { final KeysetKey masterKey = this.keyManager.getMasterKey(asOf); - final KeysetKey siteEncryptionKey = this.keyManager.getActiveKeyBySiteIdWithFallback(t.publisherIdentity.siteId, Data.AdvertisingTokenSiteId, asOf); + final KeysetKey siteEncryptionKey = this.keyManager.getActiveKeyBySiteIdWithFallback(t.sourcePublisher.siteId, Data.AdvertisingTokenSiteId, asOf); return t.version == TokenVersion.V2 ? encodeV2(t, masterKey, siteEncryptionKey) @@ -39,7 +39,7 @@ private byte[] encodeV2(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey Buffer b2 = Buffer.buffer(); b2.appendLong(t.expiresAt.toEpochMilli()); - encodeSiteIdentityV2(b2, t.publisherIdentity, t.rawUidIdentity, siteKey); + encodeSiteIdentityV2(b2, t.sourcePublisher, t.rawUidIdentity, siteKey); final byte[] encryptedId = AesCbc.encrypt(b2.getBytes(), masterKey).getPayload(); @@ -50,7 +50,7 @@ private byte[] encodeV2(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey private byte[] encodeV3(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer sitePayload = Buffer.buffer(69); - encodePublisherIdentityV3(sitePayload, t.publisherIdentity); + encodePublisherRequesterV3(sitePayload, t.sourcePublisher); sitePayload.appendInt(t.rawUidIdentity.privacyBits); sitePayload.appendLong(t.rawUidIdentity.establishedAt.toEpochMilli()); sitePayload.appendLong(t.rawUidIdentity.refreshedAt.toEpochMilli()); @@ -123,7 +123,7 @@ private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { return new RefreshTokenInput( TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), - new PublisherIdentity(siteId, 0, 0), + new SourcePublisher(siteId, 0, 0), new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, identity, privacyBits, Instant.ofEpochMilli(establishedMillis), null)); } @@ -142,7 +142,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { final Instant expiresAt = Instant.ofEpochMilli(b2.getLong(0)); final Instant createdAt = Instant.ofEpochMilli(b2.getLong(8)); final OperatorIdentity operatorIdentity = decodeOperatorIdentityV3(b2, 16); - final PublisherIdentity publisherIdentity = decodePublisherIdentityV3(b2, 29); + final SourcePublisher sourcePublisher = decodeSourcePublisherV3(b2, 29); final int privacyBits = b2.getInt(45); final Instant establishedAt = Instant.ofEpochMilli(b2.getLong(49)); final IdentityScope identityScope = decodeIdentityScopeV3(b2.getByte(57)); @@ -157,7 +157,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { } return new RefreshTokenInput( - TokenVersion.V3, createdAt, expiresAt, operatorIdentity, publisherIdentity, + TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, new FirstLevelHashIdentity(identityScope, identityType, id, privacyBits, establishedAt, null)); } @@ -225,7 +225,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(establishedMillis), Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), - new PublisherIdentity(siteId, siteKeyId, 0), + new SourcePublisher(siteId, siteKeyId, 0), new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, advertisingId, privacyBits, Instant.ofEpochMilli(establishedMillis), null) ); @@ -247,7 +247,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes final int siteKeyId = masterPayload.getInt(29); final Buffer sitePayload = Buffer.buffer(AesGcm.decrypt(masterPayloadBytes, 33, this.keyManager.getKey(siteKeyId))); - final PublisherIdentity publisherIdentity = decodePublisherIdentityV3(sitePayload, 0); + final SourcePublisher sourcePublisher = decodeSourcePublisherV3(sitePayload, 0); final int privacyBits = sitePayload.getInt(16); final Instant establishedAt = Instant.ofEpochMilli(sitePayload.getLong(20)); final Instant refreshedAt = Instant.ofEpochMilli(sitePayload.getLong(28)); @@ -266,7 +266,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes } return new AdvertisingTokenInput( - tokenVersion, createdAt, expiresAt, operatorIdentity, publisherIdentity, + tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, new RawUidIdentity(identityScope, identityType, id, privacyBits, establishedAt, refreshedAt) ); } @@ -284,10 +284,10 @@ public byte[] encode(RefreshTokenInput t, Instant asOf) { switch (t.version) { case V2: - recordRefreshTokenVersionCount(String.valueOf(t.publisherIdentity.siteId), TokenVersion.V2); + recordRefreshTokenVersionCount(String.valueOf(t.sourcePublisher.siteId), TokenVersion.V2); return encodeV2(t, serviceKey); case V3: - recordRefreshTokenVersionCount(String.valueOf(t.publisherIdentity.siteId), TokenVersion.V3); + recordRefreshTokenVersionCount(String.valueOf(t.sourcePublisher.siteId), TokenVersion.V3); return encodeV3(t, serviceKey); default: throw new ClientInputValidationException("RefreshToken version " + t.version + " not supported"); @@ -302,7 +302,7 @@ public byte[] encodeV2(RefreshTokenInput t, KeysetKey serviceKey) { // give an extra minute for clients which are trying to refresh tokens close to or at the refresh expiry timestamp b.appendLong(t.expiresAt.plusSeconds(60).toEpochMilli()); b.appendInt(serviceKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(t.publisherIdentity, t.firstLevelHashIdentity, serviceKey); + final byte[] encryptedIdentity = encryptIdentityV2(t.sourcePublisher, t.firstLevelHashIdentity, serviceKey); b.appendBytes(encryptedIdentity); return b.getBytes(); } @@ -312,7 +312,7 @@ public byte[] encodeV3(RefreshTokenInput t, KeysetKey serviceKey) { refreshPayload.appendLong(t.expiresAt.toEpochMilli()); refreshPayload.appendLong(t.createdAt.toEpochMilli()); encodeOperatorIdentityV3(refreshPayload, t.operatorIdentity); - encodePublisherIdentityV3(refreshPayload, t.publisherIdentity); + encodePublisherRequesterV3(refreshPayload, t.sourcePublisher); refreshPayload.appendInt(t.firstLevelHashIdentity.privacyBits); refreshPayload.appendLong(t.firstLevelHashIdentity.establishedAt.toEpochMilli()); refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHashIdentity.identityScope, t.firstLevelHashIdentity.identityType)); @@ -327,10 +327,10 @@ public byte[] encodeV3(RefreshTokenInput t, KeysetKey serviceKey) { return b.getBytes(); } - private void encodeSiteIdentityV2(Buffer b, PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, + private void encodeSiteIdentityV2(Buffer b, SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, KeysetKey siteEncryptionKey) { b.appendInt(siteEncryptionKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(publisherIdentity, rawUidIdentity, siteEncryptionKey); + final byte[] encryptedIdentity = encryptIdentityV2(sourcePublisher, rawUidIdentity, siteEncryptionKey); b.appendBytes(encryptedIdentity); } @@ -355,24 +355,24 @@ public Identity encodeIntoIdentityResponse(AdvertisingTokenInput advertisingToke ); } - private byte[] encryptIdentityV2(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { - return encryptIdentityV2(publisherIdentity, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { + return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, key); } - private byte[] encryptIdentityV2(PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, KeysetKey key) { - return encryptIdentityV2(publisherIdentity, rawUidIdentity.rawUid, rawUidIdentity.privacyBits, + return encryptIdentityV2(sourcePublisher, rawUidIdentity.rawUid, rawUidIdentity.privacyBits, rawUidIdentity.establishedAt, key); } - private byte[] encryptIdentityV2(PublisherIdentity publisherIdentity, byte[] id, int privacyBits, + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, byte[] id, int privacyBits, Instant establishedAt, KeysetKey key) { Buffer b = Buffer.buffer(); try { - b.appendInt(publisherIdentity.siteId); + b.appendInt(sourcePublisher.siteId); final byte[] identityBytes = EncodingUtils.toBase64(id); b.appendInt(identityBytes.length); b.appendBytes(identityBytes); @@ -397,14 +397,14 @@ static private IdentityType decodeIdentityTypeV3(byte value) { return IdentityType.fromValue((value & 0xf) >> 2); } - static void encodePublisherIdentityV3(Buffer b, PublisherIdentity publisherIdentity) { - b.appendInt(publisherIdentity.siteId); - b.appendLong(publisherIdentity.publisherId); - b.appendInt(publisherIdentity.clientKeyId); + static void encodePublisherRequesterV3(Buffer b, SourcePublisher sourcePublisher) { + b.appendInt(sourcePublisher.siteId); + b.appendLong(sourcePublisher.publisherId); + b.appendInt(sourcePublisher.clientKeyId); } - static PublisherIdentity decodePublisherIdentityV3(Buffer b, int offset) { - return new PublisherIdentity(b.getInt(offset), b.getInt(offset + 12), b.getLong(offset + 4)); + static SourcePublisher decodeSourcePublisherV3(Buffer b, int offset) { + return new SourcePublisher(b.getInt(offset), b.getInt(offset + 12), b.getLong(offset + 4)); } static void encodeOperatorIdentityV3(Buffer b, OperatorIdentity operatorIdentity) { diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index dfd65ed14..444df6f8d 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -112,7 +112,7 @@ public Identity generateIdentity(IdentityRequest request) { if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { return Identity.InvalidIdentity; } else { - return generateIdentity(request.publisherIdentity, firstLevelHashIdentity); + return generateIdentity(request.sourcePublisher, firstLevelHashIdentity); } } @@ -143,7 +143,7 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { final Duration durationSinceLastRefresh = Duration.between(token.createdAt, now); if (!optedOut) { - Identity identity = this.generateIdentity(token.publisherIdentity, token.firstLevelHashIdentity); + Identity identity = this.generateIdentity(token.sourcePublisher, token.firstLevelHashIdentity); return RefreshResponse.createRefreshedResponse(identity, durationSinceLastRefresh, isCstg); } else { @@ -246,7 +246,7 @@ private MappedIdentityResult generateMappedIdentity(FirstLevelHashIdentity first rotatingSalt.getHashedId()); } - private Identity generateIdentity(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity) { + private Identity generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(firstLevelHashIdentity, nowUtc); @@ -255,28 +255,28 @@ private Identity generateIdentity(PublisherIdentity publisherIdentity, FirstLeve mappedIdentityResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encodeIntoIdentityResponse( - this.createAdvertisingTokenInput(publisherIdentity, rawUidIdentity, nowUtc), - this.createRefreshTokenInput(publisherIdentity, firstLevelHashIdentity, nowUtc), + this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc), + this.createRefreshTokenInput(sourcePublisher, firstLevelHashIdentity, nowUtc), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc ); } - private RefreshTokenInput createRefreshTokenInput(PublisherIdentity publisherIdentity, FirstLevelHashIdentity firstLevelHashIdentity, + private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, Instant now) { return new RefreshTokenInput( this.refreshTokenVersion, now, now.plusMillis(refreshExpiresAfter.toMillis()), this.operatorIdentity, - publisherIdentity, + sourcePublisher, firstLevelHashIdentity); } - private AdvertisingTokenInput createAdvertisingTokenInput(PublisherIdentity publisherIdentity, RawUidIdentity rawUidIdentity, + private AdvertisingTokenInput createAdvertisingTokenInput(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, Instant now) { TokenVersion tokenVersion; - if (siteIdsUsingV4Tokens.contains(publisherIdentity.siteId)) { + if (siteIdsUsingV4Tokens.contains(sourcePublisher.siteId)) { tokenVersion = TokenVersion.V4; } else { int pseudoRandomNumber = 1; @@ -288,7 +288,7 @@ private AdvertisingTokenInput createAdvertisingTokenInput(PublisherIdentity publ } tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } - return new AdvertisingTokenInput(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, publisherIdentity, rawUidIdentity); + return new AdvertisingTokenInput(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, sourcePublisher, rawUidIdentity); } static protected class GlobalOptoutResult { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 081be9d34..2a6be515a 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -463,7 +463,7 @@ else if(emailHash != null) { try { identity = this.idService.generateIdentity( new IdentityRequest( - new PublisherIdentity(clientSideKeypair.getSiteId(), 0, 0), + new SourcePublisher(clientSideKeypair.getSiteId(), 0, 0), input.toHashedDiiIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), OptoutCheckPolicy.RespectOptOut)); } catch (KeyManager.NoActiveKeyException e){ @@ -938,7 +938,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { } else { final Identity t = this.idService.generateIdentity( new IdentityRequest( - new PublisherIdentity(siteId, 0, 0), + new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.defaultPolicy())); @@ -994,7 +994,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { final Identity t = this.idService.generateIdentity( new IdentityRequest( - new PublisherIdentity(siteId, 0, 0), + new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.respectOptOut())); @@ -1010,7 +1010,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { final Identity optOutTokens = this.idService.generateIdentity( new IdentityRequest( - new PublisherIdentity(siteId, 0, 0), + new SourcePublisher(siteId, 0, 0), optOutTokenInput.toHashedDiiIdentity(this.identityScope, pb.getAsInt(), Instant.now()), OptoutCheckPolicy.DoNotRespect)); @@ -1050,7 +1050,7 @@ else if (!input.isValid()) { siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); final Identity t = this.idService.generateIdentity( new IdentityRequest( - new PublisherIdentity(siteId, 0, 0), + new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.defaultPolicy())); @@ -1788,7 +1788,7 @@ private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { return RefreshResponse.Invalid; } if (!AuthMiddleware.isAuthenticated(rc)) { - rc.put(Const.RoutingContextData.SiteId, refreshTokenInput.publisherIdentity.siteId); + rc.put(Const.RoutingContextData.SiteId, refreshTokenInput.sourcePublisher.siteId); } recordRefreshTokenVersionCount(String.valueOf(rc.data().get(Const.RoutingContextData.SiteId)), this.getRefreshTokenVersion(tokenStr)); diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index b7671149f..dcf67029d 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -56,7 +56,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { now, now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), - new PublisherIdentity(111, 112, 113), + new SourcePublisher(111, 112, 113), new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, 121, now, now.minusSeconds(122)) ); @@ -74,7 +74,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { assertTrue(token.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); assertEquals(token.firstLevelHashIdentity.privacyBits, decoded.firstLevelHashIdentity.privacyBits); assertEquals(token.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); - assertEquals(token.publisherIdentity.siteId, decoded.publisherIdentity.siteId); + assertEquals(token.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 25 : 2); @@ -98,7 +98,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { now, now.plusSeconds(60), new OperatorIdentity(101, OperatorType.Service, 102, 103), - new PublisherIdentity(111, 112, 113), + new SourcePublisher(111, 112, 113), new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, 121, now, now.minusSeconds(122)) ); @@ -111,7 +111,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { assertTrue(token.rawUidIdentity.matches(decoded.rawUidIdentity)); assertEquals(token.rawUidIdentity.privacyBits, decoded.rawUidIdentity.privacyBits); assertEquals(token.rawUidIdentity.establishedAt, decoded.rawUidIdentity.establishedAt); - assertEquals(token.publisherIdentity.siteId, decoded.publisherIdentity.siteId); + assertEquals(token.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 1 : 2); //TODO - extract master key from token should be a helper function diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 4d342fdf9..17a862b47 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -151,7 +151,7 @@ private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expcte @CsvSource({"123, V2","127, V4","128, V4"}) //site id 127 and 128 is for testing "site_ids_using_v4_tokens" public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(siteId, 124, 125), + new SourcePublisher(siteId, 124, 125), createHashedDiiIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), OptoutCheckPolicy.DoNotRespect ); @@ -162,13 +162,13 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { UIDOperatorVerticleTest.validateAdvertisingToken(identity.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identity.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); - assertEquals(identityRequest.publisherIdentity.siteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenInput.sourcePublisher.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); RefreshTokenInput refreshTokenInput = tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); assertEquals(this.now, refreshTokenInput.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput.expiresAt); - assertEquals(identityRequest.publisherIdentity.siteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(identityRequest.sourcePublisher.siteId, refreshTokenInput.sourcePublisher.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, refreshTokenInput.firstLevelHashIdentity); setNow(Instant.now().plusSeconds(200)); @@ -184,7 +184,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); AdvertisingTokenInput advertisingTokenInput2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput2.expiresAt); - assertEquals(advertisingTokenInput.publisherIdentity.siteId, advertisingTokenInput2.publisherIdentity.siteId); + assertEquals(advertisingTokenInput.sourcePublisher.siteId, advertisingTokenInput2.sourcePublisher.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingTokenInput.rawUidIdentity, advertisingTokenInput2.rawUidIdentity); assertArrayEquals(advertisingTokenInput.rawUidIdentity.rawUid, @@ -193,7 +193,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { RefreshTokenInput refreshTokenInput2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentity().getRefreshToken()); assertEquals(this.now, refreshTokenInput2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput2.expiresAt); - assertEquals(refreshTokenInput.publisherIdentity.siteId, refreshTokenInput2.publisherIdentity.siteId); + assertEquals(refreshTokenInput.sourcePublisher.siteId, refreshTokenInput2.sourcePublisher.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(refreshTokenInput.firstLevelHashIdentity, refreshTokenInput2.firstLevelHashIdentity); assertArrayEquals(refreshTokenInput.firstLevelHashIdentity.firstLevelHash, refreshTokenInput2.firstLevelHashIdentity.firstLevelHash); } @@ -203,7 +203,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { final InputUtil.InputVal inputVal = InputUtil.normalizeEmail(IdentityConst.OptOutIdentityForEmail); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.DoNotRespect ); @@ -222,7 +222,7 @@ public void testTestOptOutKey_RespectOptout() { final InputUtil.InputVal inputVal = InputUtil.normalizeEmail(IdentityConst.OptOutIdentityForEmail); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.RespectOptOut ); @@ -238,7 +238,7 @@ public void testTestOptOutKeyIdentityScopeMismatch() { final InputUtil.InputVal inputVal = InputUtil.normalizeEmail(email); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.EUID, 0, this.now), OptoutCheckPolicy.DoNotRespect ); @@ -262,12 +262,12 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(id, scope, type); final IdentityRequest identityRequestForceGenerate = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), hashedDiiIdentity, OptoutCheckPolicy.DoNotRespect); final IdentityRequest identityRequestRespectOptOut = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), hashedDiiIdentity, OptoutCheckPolicy.RespectOptOut); @@ -282,7 +282,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit identity = uid2Service.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); identityAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); @@ -290,7 +290,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit identity = euidService.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); identityAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } @@ -393,7 +393,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut ); @@ -459,7 +459,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.DoNotRespect ); @@ -498,7 +498,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut ); @@ -573,7 +573,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut ); @@ -589,7 +589,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, else { identity = uid2Service.generateIdentity(identityRequest); } - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identity); @@ -641,7 +641,7 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.DoNotRespect ); @@ -702,7 +702,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( - new PublisherIdentity(123, 124, 125), + new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut); @@ -711,11 +711,11 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String reset(shutdownHandler); if(scope == IdentityScope.EUID) { identity = euidService.generateIdentity(identityRequest); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); } else { identity = uid2Service.generateIdentity(identityRequest); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.publisherIdentity.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 74652f014..8fc85fe6e 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1230,11 +1230,11 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -1272,11 +1272,11 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -1316,13 +1316,13 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); @@ -1375,13 +1375,13 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); @@ -1550,11 +1550,11 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); testContext.completeNow(); @@ -1587,11 +1587,11 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -2499,11 +2499,11 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -2538,11 +2538,11 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -2582,13 +2582,13 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); - assertEquals(clientSiteId, refreshTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); @@ -4218,8 +4218,8 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisin () -> assertTrue(refreshTokenPrivacyBits.isClientSideTokenGenerated(), "Refresh token privacy bits CSTG flag is incorrect"), () -> assertEquals(expectedOptOut, refreshTokenPrivacyBits.isClientSideTokenOptedOut(), "Refresh token privacy bits CSTG optout flag is incorrect"), - () -> assertEquals(siteId, advertisingTokenInput.publisherIdentity.siteId, "Advertising token site ID is incorrect"), - () -> assertEquals(siteId, refreshTokenInput.publisherIdentity.siteId, "Refresh token site ID is incorrect"), + () -> assertEquals(siteId, advertisingTokenInput.sourcePublisher.siteId, "Advertising token site ID is incorrect"), + () -> assertEquals(siteId, refreshTokenInput.sourcePublisher.siteId, "Refresh token site ID is incorrect"), () -> assertArrayEquals(advertisingId, advertisingTokenInput.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), () -> assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") @@ -4453,7 +4453,7 @@ void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTe EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertEquals(clientSiteId, advertisingTokenInput.publisherIdentity.siteId); + assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); //Uses a key from default keyset int clientKeyId; if (advertisingTokenInput.version == TokenVersion.V3 || advertisingTokenInput.version == TokenVersion.V4) { @@ -4471,7 +4471,7 @@ void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTe final Buffer masterPayload = Buffer.buffer(masterPayloadBytes); clientKeyId = masterPayload.getInt(29); } else { - clientKeyId = advertisingTokenInput.publisherIdentity.clientKeyId; + clientKeyId = advertisingTokenInput.sourcePublisher.clientKeyId; } switch (testRun) { case "MultiKeysets": diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 1082d0bba..18756c9e2 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -159,7 +159,7 @@ static HashedDiiIdentity[] createUserIdentities() { return arr; } - static PublisherIdentity createPublisherIdentity() throws Exception { + static SourcePublisher createSourcePublisher() throws Exception { RotatingClientKeyProvider clients = new RotatingClientKeyProvider( new EmbeddedResourceStorage(Main.class), new GlobalScope(new CloudPath("/com.uid2.core/test/clients/metadata.json"))); @@ -167,7 +167,7 @@ static PublisherIdentity createPublisherIdentity() throws Exception { for (ClientKey client : clients.getAll()) { if (client.hasRole(Role.GENERATOR)) { - return new PublisherIdentity(client.getSiteId(), 0, 0); + return new SourcePublisher(client.getSiteId(), 0, 0); } } throw new IllegalStateException("embedded resource does not include any publisher key"); diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 08893ae91..609f9e48c 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -14,7 +14,7 @@ public class TokenEndecBenchmark { private static final IUIDOperatorService uidService; private static final HashedDiiIdentity[] userIdentities; - private static final PublisherIdentity publisher; + private static final SourcePublisher publisher; private static final EncryptedTokenEncoder encoder; private static final Identity[] generatedTokens; private static int idx = 0; @@ -23,7 +23,7 @@ public class TokenEndecBenchmark { try { uidService = BenchmarkCommon.createUidOperatorService(); userIdentities = BenchmarkCommon.createUserIdentities(); - publisher = BenchmarkCommon.createPublisherIdentity(); + publisher = BenchmarkCommon.createSourcePublisher(); encoder = BenchmarkCommon.createTokenEncoder(); generatedTokens = createAdvertisingTokens(); if (generatedTokens.length < 65536 || userIdentities.length < 65536) { From d9c730e7fc13c33e143a22c7f328148451fa274c Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 19:23:51 +1100 Subject: [PATCH 12/61] Refactored UserIdentity as a base class which is inherited by HashedDii/FirstLevelHash/RawUidIdentity sub-classes --- .../operator/model/AdvertisingTokenInput.java | 2 ++ .../operator/model/HashedDiiIdentity.java | 36 ------------------- .../uid2/operator/model/IdentityRequest.java | 2 ++ .../com/uid2/operator/model/MapRequest.java | 2 ++ .../operator/model/RefreshTokenInput.java | 2 ++ .../com/uid2/operator/model/UserIdentity.java | 11 ------ .../FirstLevelHashIdentity.java | 17 +++------ .../model/userIdentity/HashedDiiIdentity.java | 22 ++++++++++++ .../{ => userIdentity}/RawUidIdentity.java | 17 +++------ .../model/userIdentity/UserIdentity.java | 21 +++++++++++ .../service/EncryptedTokenEncoder.java | 2 ++ .../operator/service/IUIDOperatorService.java | 1 + .../com/uid2/operator/service/InputUtil.java | 2 +- .../operator/service/UIDOperatorService.java | 3 ++ .../operator/store/CloudSyncOptOutStore.java | 3 +- .../com/uid2/operator/store/IOptOutStore.java | 3 +- .../operator/vertx/UIDOperatorVerticle.java | 1 + .../com/uid2/operator/TokenEncodingTest.java | 2 ++ .../uid2/operator/UIDOperatorServiceTest.java | 3 ++ .../operator/UIDOperatorVerticleTest.java | 1 + .../operator/benchmark/BenchmarkCommon.java | 2 ++ .../benchmark/IdentityMapBenchmark.java | 1 + .../benchmark/TokenEndecBenchmark.java | 1 + 23 files changed, 81 insertions(+), 76 deletions(-) delete mode 100644 src/main/java/com/uid2/operator/model/HashedDiiIdentity.java delete mode 100644 src/main/java/com/uid2/operator/model/UserIdentity.java rename src/main/java/com/uid2/operator/model/{ => userIdentity}/FirstLevelHashIdentity.java (62%) create mode 100644 src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java rename src/main/java/com/uid2/operator/model/{ => userIdentity}/RawUidIdentity.java (58%) create mode 100644 src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java index 02571b2f3..b5ffcb89a 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java @@ -1,6 +1,8 @@ package com.uid2.operator.model; import java.time.Instant; + +import com.uid2.operator.model.userIdentity.RawUidIdentity; import com.uid2.shared.model.TokenVersion; public class AdvertisingTokenInput extends VersionedToken { diff --git a/src/main/java/com/uid2/operator/model/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/HashedDiiIdentity.java deleted file mode 100644 index 500540acd..000000000 --- a/src/main/java/com/uid2/operator/model/HashedDiiIdentity.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.uid2.operator.model; - -import java.time.Instant; -import java.util.Arrays; - -// Contains a hash computed from a raw email/phone number DII input or the hash is provided by the UID Participant -// directly -public class HashedDiiIdentity implements UserIdentity{ - public final IdentityScope identityScope; - public final IdentityType identityType; - public final byte[] hashedDii; - public final int privacyBits; - public final Instant establishedAt; - public final Instant refreshedAt; - - public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, - Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; - this.hashedDii = hashedDii; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; - } - - public boolean matches(HashedDiiIdentity that) { - return this.identityScope.equals(that.identityScope) && - this.identityType.equals(that.identityType) && - Arrays.equals(this.hashedDii, that.hashedDii); - } - - public IdentityScope GetIdentityScope() { return identityScope; } - public IdentityType GetIdentityType() { return identityType; } - public Instant GetEstablishedAt() { return establishedAt; }; - public Instant GetIRefreshedAt() { return refreshedAt; } -} diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index 26eaf916e..e9a0c96cb 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -1,5 +1,7 @@ package com.uid2.operator.model; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; + public final class IdentityRequest { public final SourcePublisher sourcePublisher; public final HashedDiiIdentity hashedDiiIdentity; diff --git a/src/main/java/com/uid2/operator/model/MapRequest.java b/src/main/java/com/uid2/operator/model/MapRequest.java index f627d0703..925296e44 100644 --- a/src/main/java/com/uid2/operator/model/MapRequest.java +++ b/src/main/java/com/uid2/operator/model/MapRequest.java @@ -1,5 +1,7 @@ package com.uid2.operator.model; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; + import java.time.Instant; public final class MapRequest { diff --git a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java index 426fd3ce7..15bef6a0c 100644 --- a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java +++ b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java @@ -1,6 +1,8 @@ package com.uid2.operator.model; import java.time.Instant; + +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; import com.uid2.shared.model.TokenVersion; public class RefreshTokenInput extends VersionedToken { diff --git a/src/main/java/com/uid2/operator/model/UserIdentity.java b/src/main/java/com/uid2/operator/model/UserIdentity.java deleted file mode 100644 index 7b01c0ed0..000000000 --- a/src/main/java/com/uid2/operator/model/UserIdentity.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.uid2.operator.model; - -import java.time.Instant; - -public interface UserIdentity { - - public IdentityScope GetIdentityScope(); - public IdentityType GetIdentityType(); - public Instant GetEstablishedAt(); - public Instant GetIRefreshedAt(); -} diff --git a/src/main/java/com/uid2/operator/model/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java similarity index 62% rename from src/main/java/com/uid2/operator/model/FirstLevelHashIdentity.java rename to src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index b74e51368..4286d2a0c 100644 --- a/src/main/java/com/uid2/operator/model/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -1,16 +1,14 @@ -package com.uid2.operator.model; +package com.uid2.operator.model.userIdentity; + +import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.IdentityType; import java.time.Instant; import java.util.Arrays; // Contains a first level salted computed from Hashed DII (email/phone number) and applying salt to it -public class FirstLevelHashIdentity implements UserIdentity { - public final IdentityScope identityScope; - public final IdentityType identityType; +public class FirstLevelHashIdentity extends UserIdentity { public final byte[] firstLevelHash; - public final int privacyBits; - public final Instant establishedAt; - public final Instant refreshedAt; public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, int privacyBits, Instant establishedAt, Instant refreshedAt) { @@ -27,9 +25,4 @@ public boolean matches(FirstLevelHashIdentity that) { this.identityType.equals(that.identityType) && Arrays.equals(this.firstLevelHash, that.firstLevelHash); } - - public IdentityScope GetIdentityScope() { return identityScope; } - public IdentityType GetIdentityType() { return identityType; } - public Instant GetEstablishedAt() { return establishedAt; }; - public Instant GetIRefreshedAt() { return refreshedAt; } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java new file mode 100644 index 000000000..c5b162315 --- /dev/null +++ b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java @@ -0,0 +1,22 @@ +package com.uid2.operator.model.userIdentity; + +import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.IdentityType; + +import java.time.Instant; + +// Contains a hash computed from a raw email/phone number DII input or the hash is provided by the UID Participant +// directly +public class HashedDiiIdentity extends UserIdentity{ + public final byte[] hashedDii; + + public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, + Instant establishedAt, Instant refreshedAt) { + this.identityScope = identityScope; + this.identityType = identityType; + this.hashedDii = hashedDii; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; + this.refreshedAt = refreshedAt; + } +} diff --git a/src/main/java/com/uid2/operator/model/RawUidIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java similarity index 58% rename from src/main/java/com/uid2/operator/model/RawUidIdentity.java rename to src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java index 4ae00f2cf..7af6edf5b 100644 --- a/src/main/java/com/uid2/operator/model/RawUidIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java @@ -1,16 +1,14 @@ -package com.uid2.operator.model; +package com.uid2.operator.model.userIdentity; + +import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.IdentityType; import java.time.Instant; import java.util.Arrays; // A raw UID is stored inside -public class RawUidIdentity implements UserIdentity { - public final IdentityScope identityScope; - public final IdentityType identityType; +public class RawUidIdentity extends UserIdentity { public final byte[] rawUid; - public final int privacyBits; - public final Instant establishedAt; - public final Instant refreshedAt; public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid, int privacyBits, Instant establishedAt, Instant refreshedAt) { @@ -27,9 +25,4 @@ public boolean matches(RawUidIdentity that) { this.identityType.equals(that.identityType) && Arrays.equals(this.rawUid, that.rawUid); } - - public IdentityScope GetIdentityScope() { return identityScope; } - public IdentityType GetIdentityType() { return identityType; } - public Instant GetEstablishedAt() { return establishedAt; }; - public Instant GetIRefreshedAt() { return refreshedAt; } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java new file mode 100644 index 000000000..0e16cc4ed --- /dev/null +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -0,0 +1,21 @@ +package com.uid2.operator.model.userIdentity; + +import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.IdentityType; + +import java.time.Instant; + +//base class for all other HshedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields +public class UserIdentity { + + public IdentityScope identityScope; + public IdentityType identityType; + public int privacyBits; + public Instant establishedAt; + public Instant refreshedAt; + + public IdentityScope GetIdentityScope() { return identityScope; } + public IdentityType GetIdentityType() { return identityType; } + public Instant GetEstablishedAt() { return establishedAt; }; + public Instant GetIRefreshedAt() { return refreshedAt; } +} diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 64d686b4d..92894ea65 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -1,6 +1,8 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.userIdentity.RawUidIdentity; import com.uid2.operator.vertx.ClientInputValidationException; import com.uid2.shared.Const.Data; import com.uid2.shared.encryption.AesCbc; diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 630d20423..a2105812c 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -1,6 +1,7 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.shared.model.SaltEntry; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; diff --git a/src/main/java/com/uid2/operator/service/InputUtil.java b/src/main/java/com/uid2/operator/service/InputUtil.java index 133d6641c..ff9b3647b 100644 --- a/src/main/java/com/uid2/operator/service/InputUtil.java +++ b/src/main/java/com/uid2/operator/service/InputUtil.java @@ -2,7 +2,7 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.IdentityType; -import com.uid2.operator.model.HashedDiiIdentity; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import java.time.Instant; diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 444df6f8d..1dbce899e 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -1,6 +1,9 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.userIdentity.RawUidIdentity; import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.SaltEntry; import com.uid2.operator.store.IOptOutStore; diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 29c8a53a5..1808175a0 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -4,8 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.uid2.operator.Const; -import com.uid2.operator.model.FirstLevelHashIdentity; -import com.uid2.operator.model.HashedDiiIdentity; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; import com.uid2.operator.service.EncodingUtils; import com.uid2.shared.Utils; import com.uid2.shared.cloud.CloudStorageException; diff --git a/src/main/java/com/uid2/operator/store/IOptOutStore.java b/src/main/java/com/uid2/operator/store/IOptOutStore.java index 20d30dda8..f767b316e 100644 --- a/src/main/java/com/uid2/operator/store/IOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/IOptOutStore.java @@ -1,7 +1,6 @@ package com.uid2.operator.store; -import com.uid2.operator.model.FirstLevelHashIdentity; -import com.uid2.operator.model.HashedDiiIdentity; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 2a6be515a..365b5d75e 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -4,6 +4,7 @@ import com.uid2.operator.model.*; import com.uid2.operator.model.Identity; import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.StatsCollectorHandler; import com.uid2.operator.monitoring.TokenResponseStatsCollector; diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index dcf67029d..9a483c866 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -1,6 +1,8 @@ package com.uid2.operator; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.userIdentity.RawUidIdentity; import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.TokenUtils; diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 17a862b47..0c4669fec 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -1,6 +1,9 @@ package com.uid2.operator; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.userIdentity.UserIdentity; import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.InputUtil; diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 8fc85fe6e..b9c64a843 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -5,6 +5,7 @@ import ch.qos.logback.core.read.ListAppender; import com.uid2.operator.model.*; import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.TokenResponseStatsCollector; import com.uid2.operator.service.*; diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 18756c9e2..00c2e2cac 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -3,6 +3,8 @@ import com.uid2.operator.Const; import com.uid2.operator.Main; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.IUIDOperatorService; import com.uid2.operator.service.UIDOperatorService; diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 401ea1b82..bbafba89a 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -1,6 +1,7 @@ package com.uid2.operator.benchmark; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.operator.service.IUIDOperatorService; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 609f9e48c..672d9763d 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -1,6 +1,7 @@ package com.uid2.operator.benchmark; import com.uid2.operator.model.*; +import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.IUIDOperatorService; import org.openjdk.jmh.annotations.Benchmark; From 42c58903549c8e1cd4ace42588631c3bb38d0a88 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Fri, 11 Oct 2024 19:29:14 +1100 Subject: [PATCH 13/61] Renamed Identity to IdentityResponse --- .../{Identity.java => IdentityResponse.java} | 11 +- .../uid2/operator/model/RefreshResponse.java | 28 ++-- .../service/EncryptedTokenEncoder.java | 4 +- .../uid2/operator/service/ITokenEncoder.java | 4 +- .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 10 +- .../operator/vertx/UIDOperatorVerticle.java | 24 ++-- .../uid2/operator/UIDOperatorServiceTest.java | 122 +++++++++--------- .../benchmark/TokenEndecBenchmark.java | 10 +- 9 files changed, 108 insertions(+), 107 deletions(-) rename src/main/java/com/uid2/operator/model/{Identity.java => IdentityResponse.java} (71%) diff --git a/src/main/java/com/uid2/operator/model/Identity.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java similarity index 71% rename from src/main/java/com/uid2/operator/model/Identity.java rename to src/main/java/com/uid2/operator/model/IdentityResponse.java index b5ebdb74d..5c3b004ae 100644 --- a/src/main/java/com/uid2/operator/model/Identity.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -4,9 +4,10 @@ import java.time.Instant; -// this is the response of the /token/generate and /client/generate endpoints -public class Identity { - public static Identity InvalidIdentity = new Identity("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); +// this defines all the fields for the response of the /token/generate and /client/generate endpoints before they are +// json-ised +public class IdentityResponse { + public static IdentityResponse invalidIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; private final TokenVersion advertisingTokenVersion; private final String refreshToken; @@ -14,8 +15,8 @@ public class Identity { private final Instant refreshExpires; private final Instant refreshFrom; - public Identity(String advertisingToken, TokenVersion advertisingTokenVersion, String refreshToken, - Instant identityExpires, Instant refreshExpires, Instant refreshFrom) { + public IdentityResponse(String advertisingToken, TokenVersion advertisingTokenVersion, String refreshToken, + Instant identityExpires, Instant refreshExpires, Instant refreshFrom) { this.advertisingToken = advertisingToken; this.advertisingTokenVersion = advertisingTokenVersion; this.refreshToken = refreshToken; diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index 0a62b4655..d4c8850b3 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -4,37 +4,37 @@ public class RefreshResponse { - public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, Identity.InvalidIdentity); - public static RefreshResponse Optout = new RefreshResponse(Status.Optout, Identity.InvalidIdentity); - public static RefreshResponse Expired = new RefreshResponse(Status.Expired, Identity.InvalidIdentity); - public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, Identity.InvalidIdentity); - public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, Identity.InvalidIdentity); + public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, IdentityResponse.invalidIdentityResponse); + public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.invalidIdentityResponse); + public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.invalidIdentityResponse); + public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.invalidIdentityResponse); + public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.invalidIdentityResponse); private final Status status; - private final Identity identity; + private final IdentityResponse identityResponse; private final Duration durationSinceLastRefresh; private final boolean isCstg; - private RefreshResponse(Status status, Identity identity, Duration durationSinceLastRefresh, boolean isCstg) { + private RefreshResponse(Status status, IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { this.status = status; - this.identity = identity; + this.identityResponse = identityResponse; this.durationSinceLastRefresh = durationSinceLastRefresh; this.isCstg = isCstg; } - private RefreshResponse(Status status, Identity identity) { - this(status, identity, null, false); + private RefreshResponse(Status status, IdentityResponse identityResponse) { + this(status, identityResponse, null, false); } - public static RefreshResponse createRefreshedResponse(Identity identity, Duration durationSinceLastRefresh, boolean isCstg) { - return new RefreshResponse(Status.Refreshed, identity, durationSinceLastRefresh, isCstg); + public static RefreshResponse createRefreshedResponse(IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { + return new RefreshResponse(Status.Refreshed, identityResponse, durationSinceLastRefresh, isCstg); } public Status getStatus() { return status; } - public Identity getIdentity() { - return identity; + public IdentityResponse getIdentity() { + return identityResponse; } public Duration getDurationSinceLastRefresh() { diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 92894ea65..ab70aeea3 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -342,12 +342,12 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi } @Override - public Identity encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { + public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { final byte[] advertisingTokenBytes = encode(advertisingTokenInput, asOf); final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); - return new Identity( + return new IdentityResponse( base64AdvertisingToken, advertisingTokenInput.version, EncodingUtils.toBase64String(encode(refreshTokenInput, asOf)), diff --git a/src/main/java/com/uid2/operator/service/ITokenEncoder.java b/src/main/java/com/uid2/operator/service/ITokenEncoder.java index c0c1594c4..9380dc8c2 100644 --- a/src/main/java/com/uid2/operator/service/ITokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/ITokenEncoder.java @@ -1,13 +1,13 @@ package com.uid2.operator.service; import com.uid2.operator.model.AdvertisingTokenInput; -import com.uid2.operator.model.Identity; +import com.uid2.operator.model.IdentityResponse; import com.uid2.operator.model.RefreshTokenInput; import java.time.Instant; public interface ITokenEncoder { - Identity encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf); + IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf); AdvertisingTokenInput decodeAdvertisingToken(String base64String); diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index a2105812c..9c3cd2d89 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -12,7 +12,7 @@ public interface IUIDOperatorService { - Identity generateIdentity(IdentityRequest request); + IdentityResponse generateIdentity(IdentityRequest request); RefreshResponse refreshIdentity(RefreshTokenInput refreshTokenInput); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 1dbce899e..7b5c88e8e 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -105,7 +105,7 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv } @Override - public Identity generateIdentity(IdentityRequest request) { + public IdentityResponse generateIdentity(IdentityRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); final byte[] firstLevelHash = getFirstLevelHash(request.hashedDiiIdentity.hashedDii, now); final FirstLevelHashIdentity firstLevelHashIdentity = new FirstLevelHashIdentity( @@ -113,7 +113,7 @@ public Identity generateIdentity(IdentityRequest request) { request.hashedDiiIdentity.establishedAt, request.hashedDiiIdentity.refreshedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return Identity.InvalidIdentity; + return IdentityResponse.invalidIdentityResponse; } else { return generateIdentity(request.sourcePublisher, firstLevelHashIdentity); } @@ -146,9 +146,9 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { final Duration durationSinceLastRefresh = Duration.between(token.createdAt, now); if (!optedOut) { - Identity identity = this.generateIdentity(token.sourcePublisher, token.firstLevelHashIdentity); + IdentityResponse identityResponse = this.generateIdentity(token.sourcePublisher, token.firstLevelHashIdentity); - return RefreshResponse.createRefreshedResponse(identity, durationSinceLastRefresh, isCstg); + return RefreshResponse.createRefreshedResponse(identityResponse, durationSinceLastRefresh, isCstg); } else { return RefreshResponse.Optout; } @@ -249,7 +249,7 @@ private MappedIdentityResult generateMappedIdentity(FirstLevelHashIdentity first rotatingSalt.getHashedId()); } - private Identity generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { + private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(firstLevelHashIdentity, nowUtc); diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 365b5d75e..9df97ba39 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -2,7 +2,7 @@ import com.uid2.operator.Const; import com.uid2.operator.model.*; -import com.uid2.operator.model.Identity; +import com.uid2.operator.model.IdentityResponse; import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.operator.monitoring.IStatsCollectorQueue; @@ -460,9 +460,9 @@ else if(emailHash != null) { privacyBits.setLegacyBit(); privacyBits.setClientSideTokenGenerate(); - Identity identity; + IdentityResponse identityResponse; try { - identity = this.idService.generateIdentity( + identityResponse = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(clientSideKeypair.getSiteId(), 0, 0), input.toHashedDiiIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), @@ -474,12 +474,12 @@ else if(emailHash != null) { JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; - if (identity.isNotValid()) { + if (identityResponse.isNotValid()) { response = ResponseUtil.SuccessNoBodyV2(ResponseStatus.OptOut); responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } else { //user not opted out and already generated valid identity token - response = ResponseUtil.SuccessV2(toJsonV1(identity)); + response = ResponseUtil.SuccessV2(toJsonV1(identityResponse)); } //if returning an optout token or a successful identity token created originally if (responseStatus == TokenResponseStatsCollector.ResponseStatus.Success) { @@ -487,7 +487,7 @@ else if(emailHash != null) { } final byte[] encryptedResponse = AesGcm.encrypt(response.toBuffer().getBytes(), sharedSecret); rc.response().setStatusCode(200).end(Buffer.buffer(Unpooled.wrappedBuffer(Base64.getEncoder().encode(encryptedResponse)))); - recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identity.getAdvertisingTokenVersion(), platformType); + recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identityResponse.getAdvertisingTokenVersion(), platformType); } private boolean hasValidOriginOrAppName(RoutingContext rc, CstgRequest request, ClientSideKeypair keypair, TokenResponseStatsCollector.PlatformType platformType) { @@ -937,7 +937,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { if (!checkForInvalidTokenInput(input, rc)) { return; } else { - final Identity t = this.idService.generateIdentity( + final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), @@ -993,7 +993,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { return; } - final Identity t = this.idService.generateIdentity( + final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), @@ -1009,7 +1009,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { pb.setLegacyBit(); pb.setClientSideTokenGenerateOptout(); - final Identity optOutTokens = this.idService.generateIdentity( + final IdentityResponse optOutTokens = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), optOutTokenInput.toHashedDiiIdentity(this.identityScope, pb.getAsInt(), Instant.now()), @@ -1049,7 +1049,7 @@ else if (!input.isValid()) { try { siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); - final Identity t = this.idService.generateIdentity( + final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), @@ -1986,7 +1986,7 @@ private TransparentConsentParseResult getUserConsentV2(JsonObject req) { } } - private JsonObject toJsonV1(Identity t) { + private JsonObject toJsonV1(IdentityResponse t) { final JsonObject json = new JsonObject(); json.put("advertising_token", t.getAdvertisingToken()); json.put("refresh_token", t.getRefreshToken()); @@ -2040,7 +2040,7 @@ private static JsonObject toJson(KeysetKey key) { return json; } - private JsonObject toJson(Identity t) { + private JsonObject toJson(IdentityResponse t) { final JsonObject json = new JsonObject(); json.put("advertisement_token", t.getAdvertisingToken()); json.put("advertising_token", t.getAdvertisingToken()); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 0c4669fec..e251fcd4f 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -158,17 +158,17 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { createHashedDiiIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), OptoutCheckPolicy.DoNotRespect ); - final Identity identity = uid2Service.generateIdentity(identityRequest); + final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identity); + assertNotNull(identityResponse); - UIDOperatorVerticleTest.validateAdvertisingToken(identity.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identity.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); + UIDOperatorVerticleTest.validateAdvertisingToken(identityResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identityResponse.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenInput.sourcePublisher.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); - RefreshTokenInput refreshTokenInput = tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + RefreshTokenInput refreshTokenInput = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); assertEquals(this.now, refreshTokenInput.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput.expiresAt); assertEquals(identityRequest.sourcePublisher.siteId, refreshTokenInput.sourcePublisher.siteId); @@ -210,13 +210,13 @@ public void testTestOptOutKey_DoNotRespectOptout() { inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.DoNotRespect ); - final Identity identity = uid2Service.generateIdentity(identityRequest); + final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identity); - assertFalse(identity.isNotValid()); + assertNotNull(identityResponse); + assertFalse(identityResponse.isNotValid()); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenInput)); } @@ -229,8 +229,8 @@ public void testTestOptOutKey_RespectOptout() { inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), OptoutCheckPolicy.RespectOptOut ); - final Identity identity = uid2Service.generateIdentity(identityRequest); - assertTrue(identity.isNotValid()); + final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); + assertTrue(identityResponse.isNotValid()); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); } @@ -245,12 +245,12 @@ public void testTestOptOutKeyIdentityScopeMismatch() { inputVal.toHashedDiiIdentity(IdentityScope.EUID, 0, this.now), OptoutCheckPolicy.DoNotRespect ); - final Identity identity = euidService.generateIdentity(identityRequest); + final IdentityResponse identityResponse = euidService.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identity); + assertNotNull(identityResponse); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshTokenInput)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -278,31 +278,31 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final Identity identity; + final IdentityResponse identityResponse; final AdvertisingTokenInput advertisingTokenInput; - final Identity identityAfterOptOut; + final IdentityResponse identityResponseAfterOptOut; if (scope == IdentityScope.UID2) { - identity = uid2Service.generateIdentity(identityRequestForceGenerate); + identityResponse = uid2Service.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); - identityAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); + identityResponseAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); } else { - identity = euidService.generateIdentity(identityRequestForceGenerate); + identityResponse = euidService.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); - identityAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); + identityResponseAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identity); + assertNotNull(identityResponse); assertNotNull(advertisingTokenInput.rawUidIdentity); - assertNotNull(identityAfterOptOut); - assertTrue(identityAfterOptOut.getAdvertisingToken() == null || identityAfterOptOut.getAdvertisingToken().isEmpty()); + assertNotNull(identityResponseAfterOptOut); + assertTrue(identityResponseAfterOptOut.getAdvertisingToken() == null || identityResponseAfterOptOut.getAdvertisingToken().isEmpty()); } @@ -404,16 +404,16 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i // identity has no optout record, ensure generate still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - Identity identity; + IdentityResponse identityResponse; if(scope == IdentityScope.EUID) { - identity = euidService.generateIdentity(identityRequest); + identityResponse = euidService.generateIdentity(identityRequest); } else { - identity = uid2Service.generateIdentity(identityRequest); + identityResponse = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertEquals(identity, Identity.InvalidIdentity); + assertEquals(identityResponse, IdentityResponse.invalidIdentityResponse); } @ParameterizedTest @@ -467,22 +467,22 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id OptoutCheckPolicy.DoNotRespect ); - Identity identity; + IdentityResponse identityResponse; if(scope == IdentityScope.EUID) { - identity = euidService.generateIdentity(identityRequest); + identityResponse = euidService.generateIdentity(identityRequest); } else { - identity = uid2Service.generateIdentity(identityRequest); + identityResponse = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identity); - assertNotEquals(Identity.InvalidIdentity, identity); + assertNotNull(identityResponse); + assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -509,22 +509,22 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String // identity has optout record, ensure still generates when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - Identity identity; + IdentityResponse identityResponse; if(scope == IdentityScope.EUID) { - identity = euidService.generateIdentity(identityRequest); + identityResponse = euidService.generateIdentity(identityRequest); } else { - identity = uid2Service.generateIdentity(identityRequest); + identityResponse = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identity); - assertNotEquals(Identity.InvalidIdentity, identity); + assertNotNull(identityResponse); + assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -584,19 +584,19 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, // all identities have optout records, ensure validate identities still get generated when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - Identity identity; + IdentityResponse identityResponse; AdvertisingTokenInput advertisingTokenInput; if (scope == IdentityScope.EUID) { - identity = euidService.generateIdentity(identityRequest); + identityResponse = euidService.generateIdentity(identityRequest); } else { - identity = uid2Service.generateIdentity(identityRequest); + identityResponse = uid2Service.generateIdentity(identityRequest); } - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identity); - assertNotEquals(Identity.InvalidIdentity, identity); + assertNotNull(identityResponse); + assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); assertNotNull(advertisingTokenInput.rawUidIdentity); } @@ -648,19 +648,19 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.DoNotRespect ); - Identity identity; + IdentityResponse identityResponse; if(scope == IdentityScope.EUID) { - identity = euidService.generateIdentity(identityRequest); + identityResponse = euidService.generateIdentity(identityRequest); } else { - identity = uid2Service.generateIdentity(identityRequest); + identityResponse = uid2Service.generateIdentity(identityRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotEquals(identity, Identity.InvalidIdentity); - assertNotNull(identity); + assertNotEquals(identityResponse, IdentityResponse.invalidIdentityResponse); + assertNotNull(identityResponse); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput); assertTrue(refreshResponse.isRefreshed()); assertNotNull(refreshResponse.getIdentity()); @@ -709,24 +709,24 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut); - Identity identity; + IdentityResponse identityResponse; AdvertisingTokenInput advertisingTokenInput; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - identity = euidService.generateIdentity(identityRequest); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + identityResponse = euidService.generateIdentity(identityRequest); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); } else { - identity = uid2Service.generateIdentity(identityRequest); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identity.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + identityResponse = uid2Service.generateIdentity(identityRequest); + advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(identity); - assertNotEquals(Identity.InvalidIdentity, identity); + assertNotNull(identityResponse); + assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); assertNotNull(advertisingTokenInput.rawUidIdentity); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identity.getRefreshToken()); + final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 672d9763d..0e5f62b89 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -17,7 +17,7 @@ public class TokenEndecBenchmark { private static final HashedDiiIdentity[] userIdentities; private static final SourcePublisher publisher; private static final EncryptedTokenEncoder encoder; - private static final Identity[] generatedTokens; + private static final IdentityResponse[] generatedTokens; private static int idx = 0; static { @@ -35,8 +35,8 @@ public class TokenEndecBenchmark { } } - static Identity[] createAdvertisingTokens() { - List tokens = new ArrayList<>(); + static IdentityResponse[] createAdvertisingTokens() { + List tokens = new ArrayList<>(); for (int i = 0; i < userIdentities.length; i++) { tokens.add( uidService.generateIdentity(new IdentityRequest( @@ -44,12 +44,12 @@ static Identity[] createAdvertisingTokens() { userIdentities[i], OptoutCheckPolicy.DoNotRespect))); } - return tokens.toArray(new Identity[tokens.size()]); + return tokens.toArray(new IdentityResponse[tokens.size()]); } @Benchmark @BenchmarkMode(Mode.Throughput) - public Identity TokenGenerationBenchmark() { + public IdentityResponse TokenGenerationBenchmark() { return uidService.generateIdentity(new IdentityRequest( publisher, userIdentities[(idx++) & 65535], From b62aa54fe7df09232005dd08d5fb88cb5bd09aad Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 12:22:25 +1100 Subject: [PATCH 14/61] Fixed using raw identity in testGenerateTokenForOptOutUser --- .../java/com/uid2/operator/UIDOperatorServiceTest.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index e251fcd4f..d516012ff 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -4,10 +4,7 @@ import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.operator.model.userIdentity.UserIdentity; -import com.uid2.operator.service.EncodingUtils; -import com.uid2.operator.service.EncryptedTokenEncoder; -import com.uid2.operator.service.InputUtil; -import com.uid2.operator.service.UIDOperatorService; +import com.uid2.operator.service.*; import com.uid2.operator.store.IOptOutStore; import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.shared.store.CloudPath; @@ -262,7 +259,8 @@ public void testTestOptOutKeyIdentityScopeMismatch() { "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) public void testGenerateTokenForOptOutUser(IdentityType type, String id, IdentityScope scope) { - final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(id, scope, type); + final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(TokenUtils.getIdentityHashString(id), + scope, type); final IdentityRequest identityRequestForceGenerate = new IdentityRequest( new SourcePublisher(123, 124, 125), From b272d40c0dd10a06312873dd52fb898c0e3371b5 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 12:51:56 +1100 Subject: [PATCH 15/61] Renamed RefreshResponse#getIdentity to RefreshResponse#getIdentityResponse --- .../com/uid2/operator/model/RefreshResponse.java | 2 +- .../monitoring/TokenResponseStatsCollector.java | 8 ++++---- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 6 +++--- .../com/uid2/operator/UIDOperatorServiceTest.java | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index d4c8850b3..252acece3 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -33,7 +33,7 @@ public Status getStatus() { return status; } - public IdentityResponse getIdentity() { + public IdentityResponse getIdentityResponse() { return identityResponse; } diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index b2e7e56ec..fc28bba70 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -72,14 +72,14 @@ private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoin public static void recordRefresh(ISiteStore siteStore, Integer siteId, Endpoint endpoint, RefreshResponse refreshResponse, PlatformType platformType) { if (!refreshResponse.isRefreshed()) { if (refreshResponse.isOptOut() || refreshResponse.isDeprecated()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getIdentityResponse().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } else if (refreshResponse.isInvalidToken()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.InvalidToken, refreshResponse.getIdentityResponse().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } else if (refreshResponse.isExpired()) { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.ExpiredToken, refreshResponse.getIdentityResponse().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } } else { - recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getIdentity().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); + recordInternal(siteStore, siteId, endpoint, ResponseStatus.Success, refreshResponse.getIdentityResponse().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); } } } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 9df97ba39..43585c664 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -825,7 +825,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } } else { - ResponseUtil.Success(rc, toJsonV1(r.getIdentity())); + ResponseUtil.Success(rc, toJsonV1(r.getIdentityResponse())); this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } @@ -859,7 +859,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } } else { - ResponseUtil.SuccessV2(rc, toJsonV1(r.getIdentity())); + ResponseUtil.SuccessV2(rc, toJsonV1(r.getIdentityResponse())); this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, r, platformType); @@ -1076,7 +1076,7 @@ private void handleTokenRefresh(RoutingContext rc) { try { final RefreshResponse r = this.refreshIdentity(rc, tokenList.get(0)); - sendJsonResponse(rc, toJson(r.getIdentity())); + sendJsonResponse(rc, toJson(r.getIdentityResponse())); siteId = rc.get(Const.RoutingContextData.SiteId); if (r.isRefreshed()) { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index d516012ff..07f072ac7 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -179,10 +179,10 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(refreshResponse); assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); - assertNotNull(refreshResponse.getIdentity()); + assertNotNull(refreshResponse.getIdentityResponse()); - UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingTokenInput advertisingTokenInput2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentity().getAdvertisingToken()); + UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + AdvertisingTokenInput advertisingTokenInput2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput2.expiresAt); assertEquals(advertisingTokenInput.sourcePublisher.siteId, advertisingTokenInput2.sourcePublisher.siteId); assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingTokenInput.rawUidIdentity, @@ -190,7 +190,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertArrayEquals(advertisingTokenInput.rawUidIdentity.rawUid, advertisingTokenInput2.rawUidIdentity.rawUid); - RefreshTokenInput refreshTokenInput2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentity().getRefreshToken()); + RefreshTokenInput refreshTokenInput2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); assertEquals(this.now, refreshTokenInput2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput2.expiresAt); assertEquals(refreshTokenInput.sourcePublisher.siteId, refreshTokenInput2.sourcePublisher.siteId); @@ -661,7 +661,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput); assertTrue(refreshResponse.isRefreshed()); - assertNotNull(refreshResponse.getIdentity()); + assertNotNull(refreshResponse.getIdentityResponse()); assertNotEquals(RefreshResponse.Optout, refreshResponse); } @@ -730,7 +730,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertTrue(refreshResponse.isRefreshed()); - assertNotNull(refreshResponse.getIdentity()); + assertNotNull(refreshResponse.getIdentityResponse()); assertNotEquals(RefreshResponse.Optout, refreshResponse); final MapRequest mapRequest = new MapRequest( From 7e5ad5dc5a50c7a9a01bf1b7d751ba8b0250455c Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 13:44:57 +1100 Subject: [PATCH 16/61] 1. Refactor EncryptedTokenEncoder#encodeIntoIdentityResponse 2. Moved toJson methods into IdentityResponse from UIDOperatorVerticle class --- .../uid2/operator/model/IdentityResponse.java | 22 ++++++++++++ .../service/EncryptedTokenEncoder.java | 19 +++++++--- .../operator/vertx/UIDOperatorVerticle.java | 35 +++++-------------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 5c3b004ae..3b82d30e0 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -1,6 +1,7 @@ package com.uid2.operator.model; import com.uid2.shared.model.TokenVersion; +import io.vertx.core.json.JsonObject; import java.time.Instant; @@ -52,4 +53,25 @@ public Instant getRefreshFrom() { public boolean isNotValid() { return advertisingToken == null || advertisingToken.isEmpty(); } + + // for v1/v2 token/generate and token/refresh and client/generate (CSTG) endpoints + public JsonObject toJsonV1() { + final JsonObject json = new JsonObject(); + json.put("advertising_token", getAdvertisingToken()); + json.put("refresh_token", getRefreshToken()); + json.put("identity_expires", getIdentityExpires().toEpochMilli()); + json.put("refresh_expires", getRefreshExpires().toEpochMilli()); + json.put("refresh_from", getRefreshFrom().toEpochMilli()); + return json; + } + + // for the original/legacy token/generate and token/refresh endpoint + public JsonObject toJsonV0() { + final JsonObject json = new JsonObject(); + json.put("advertisement_token", getAdvertisingToken()); + json.put("advertising_token", getAdvertisingToken()); + json.put("refresh_token", getRefreshToken()); + + return json; + } } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index ab70aeea3..1dc01777e 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -344,19 +344,30 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi @Override public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { - final byte[] advertisingTokenBytes = encode(advertisingTokenInput, asOf); - final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); - + final String base64AdvertisingToken = generateBase64AdvertisingToken(advertisingTokenInput, asOf); + final String base64RefreshToken = generateBase64RefreshToken(refreshTokenInput, asOf); return new IdentityResponse( base64AdvertisingToken, advertisingTokenInput.version, - EncodingUtils.toBase64String(encode(refreshTokenInput, asOf)), + base64RefreshToken, advertisingTokenInput.expiresAt, refreshTokenInput.expiresAt, refreshFrom ); } + private String generateBase64RefreshToken(RefreshTokenInput refreshTokenInput, Instant asOf) { + return EncodingUtils.toBase64String(encode(refreshTokenInput, asOf)); + } + + private String generateBase64AdvertisingToken(AdvertisingTokenInput advertisingTokenInput, Instant asOf) { + final byte[] advertisingTokenBytes = encode(advertisingTokenInput, asOf); + final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); + return base64AdvertisingToken; + } + + + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, key); diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 43585c664..65db2e4b8 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -479,7 +479,7 @@ else if(emailHash != null) { responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } else { //user not opted out and already generated valid identity token - response = ResponseUtil.SuccessV2(toJsonV1(identityResponse)); + response = ResponseUtil.SuccessV2(identityResponse.toJsonV1()); } //if returning an optout token or a successful identity token created originally if (responseStatus == TokenResponseStatsCollector.ResponseStatus.Success) { @@ -825,7 +825,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } } else { - ResponseUtil.Success(rc, toJsonV1(r.getIdentityResponse())); + ResponseUtil.Success(rc, r.getIdentityResponse().toJsonV1()); this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } @@ -859,7 +859,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State"); } } else { - ResponseUtil.SuccessV2(rc, toJsonV1(r.getIdentityResponse())); + ResponseUtil.SuccessV2(rc, r.getIdentityResponse().toJsonV1()); this.recordRefreshDurationStats(siteId, getApiContact(rc), r.getDurationSinceLastRefresh(), rc.request().headers().contains(ORIGIN_HEADER)); } TokenResponseStatsCollector.recordRefresh(siteProvider, siteId, TokenResponseStatsCollector.Endpoint.RefreshV2, r, platformType); @@ -945,7 +945,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); - ResponseUtil.Success(rc, toJsonV1(t)); + ResponseUtil.Success(rc, t.toJsonV1()); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), platformType); } } catch (Exception e) { @@ -1015,14 +1015,14 @@ private void handleTokenGenerateV2(RoutingContext rc) { optOutTokenInput.toHashedDiiIdentity(this.identityScope, pb.getAsInt(), Instant.now()), OptoutCheckPolicy.DoNotRespect)); - ResponseUtil.SuccessV2(rc, toJsonV1(optOutTokens)); + ResponseUtil.SuccessV2(rc, optOutTokens.toJsonV1()); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, optOutTokens.getAdvertisingTokenVersion(), platformType); } else { // new participant, or legacy specified policy/optout_check=1 ResponseUtil.SuccessNoBodyV2("optout", rc); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, siteProvider, null, platformType); } } else { - ResponseUtil.SuccessV2(rc, toJsonV1(t)); + ResponseUtil.SuccessV2(rc, t.toJsonV1()); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), platformType); } } @@ -1058,7 +1058,7 @@ else if (!input.isValid()) { //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Other); - sendJsonResponse(rc, toJson(t)); + sendJsonResponse(rc, t.toJsonV0()); } catch (Exception e) { SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Other); @@ -1076,7 +1076,7 @@ private void handleTokenRefresh(RoutingContext rc) { try { final RefreshResponse r = this.refreshIdentity(rc, tokenList.get(0)); - sendJsonResponse(rc, toJson(r.getIdentityResponse())); + sendJsonResponse(rc, r.getIdentityResponse().toJsonV0()); siteId = rc.get(Const.RoutingContextData.SiteId); if (r.isRefreshed()) { @@ -1986,16 +1986,6 @@ private TransparentConsentParseResult getUserConsentV2(JsonObject req) { } } - private JsonObject toJsonV1(IdentityResponse t) { - final JsonObject json = new JsonObject(); - json.put("advertising_token", t.getAdvertisingToken()); - json.put("refresh_token", t.getRefreshToken()); - json.put("identity_expires", t.getIdentityExpires().toEpochMilli()); - json.put("refresh_expires", t.getRefreshExpires().toEpochMilli()); - json.put("refresh_from", t.getRefreshFrom().toEpochMilli()); - return json; - } - private static MissingAclMode getMissingAclMode(ClientKey clientKey) { return clientKey.hasRole(Role.ID_READER) ? MissingAclMode.ALLOW_ALL : MissingAclMode.DENY_ALL; } @@ -2040,15 +2030,6 @@ private static JsonObject toJson(KeysetKey key) { return json; } - private JsonObject toJson(IdentityResponse t) { - final JsonObject json = new JsonObject(); - json.put("advertisement_token", t.getAdvertisingToken()); - json.put("advertising_token", t.getAdvertisingToken()); - json.put("refresh_token", t.getRefreshToken()); - - return json; - } - private void sendJsonResponse(RoutingContext rc, JsonObject json) { rc.response().putHeader(HttpHeaders.CONTENT_TYPE, "application/json") .end(json.encode()); From 131d203972adf6948380fb1c559de812eb5bc028 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 13:59:47 +1100 Subject: [PATCH 17/61] Use EncryptedTokenEncoder directly inside UIDOperatorService class instead of ITokenEncoder interfact so it's easier to jump to references and we haven't really created any other ITokenEncoder variants --- .../java/com/uid2/operator/service/UIDOperatorService.java | 4 ++-- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 7b5c88e8e..b678d7f67 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -36,7 +36,7 @@ public class UIDOperatorService implements IUIDOperatorService { private static final Instant RefreshCutoff = LocalDateTime.parse("2021-03-08T17:00:00", DateTimeFormatter.ISO_LOCAL_DATE_TIME).toInstant(ZoneOffset.UTC); private final ISaltProvider saltProvider; private final IOptOutStore optOutStore; - private final ITokenEncoder encoder; + private final EncryptedTokenEncoder encoder; private final Clock clock; private final IdentityScope identityScope; private final FirstLevelHashIdentity testOptOutIdentityForEmail; @@ -58,7 +58,7 @@ public class UIDOperatorService implements IUIDOperatorService { private final Handler saltRetrievalResponseHandler; - public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProvider saltProvider, ITokenEncoder encoder, Clock clock, + public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProvider saltProvider, EncryptedTokenEncoder encoder, Clock clock, IdentityScope identityScope, Handler saltRetrievalResponseHandler) { this.saltProvider = saltProvider; this.encoder = encoder; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 65db2e4b8..32fe035f9 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -91,7 +91,7 @@ public class UIDOperatorVerticle extends AbstractVerticle { private final AuthMiddleware auth; private final ISiteStore siteProvider; private final IClientSideKeypairStore clientSideKeypairProvider; - private final ITokenEncoder encoder; + private final EncryptedTokenEncoder encoder; private final ISaltProvider saltProvider; private final IOptOutStore optOutStore; private final IClientKeyProvider clientKeyProvider; From 8dc0a41034970b499c6547333ee9075cded4ca20 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 15:24:35 +1100 Subject: [PATCH 18/61] Renamed MappedIdentity to RawUid2Result and UIDOperatorService.getAdvertisingId to generateRawUid --- .../uid2/operator/model/IdentityResponse.java | 2 +- ...IdentityResult.java => RawUid2Result.java} | 8 +-- .../uid2/operator/model/RefreshResponse.java | 10 +-- .../operator/service/IUIDOperatorService.java | 4 +- .../operator/service/UIDOperatorService.java | 28 ++++---- .../operator/vertx/UIDOperatorVerticle.java | 18 ++--- .../uid2/operator/UIDOperatorServiceTest.java | 72 +++++++++---------- .../benchmark/IdentityMapBenchmark.java | 4 +- 8 files changed, 73 insertions(+), 73 deletions(-) rename src/main/java/com/uid2/operator/model/{MappedIdentityResult.java => RawUid2Result.java} (67%) diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 5c3b004ae..8b840de0e 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -7,7 +7,7 @@ // this defines all the fields for the response of the /token/generate and /client/generate endpoints before they are // json-ised public class IdentityResponse { - public static IdentityResponse invalidIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); + public static IdentityResponse optOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; private final TokenVersion advertisingTokenVersion; private final String refreshToken; diff --git a/src/main/java/com/uid2/operator/model/MappedIdentityResult.java b/src/main/java/com/uid2/operator/model/RawUid2Result.java similarity index 67% rename from src/main/java/com/uid2/operator/model/MappedIdentityResult.java rename to src/main/java/com/uid2/operator/model/RawUid2Result.java index 08752115e..7bc93a451 100644 --- a/src/main/java/com/uid2/operator/model/MappedIdentityResult.java +++ b/src/main/java/com/uid2/operator/model/RawUid2Result.java @@ -1,13 +1,13 @@ package com.uid2.operator.model; -// Contains the computed raw UID and its bucket ID from identity/map logic -public class MappedIdentityResult { - public static MappedIdentityResult OptoutIdentity = new MappedIdentityResult(new byte[33], ""); +// Contains the computed raw UID and its bucket ID from identity/map request +public class RawUid2Result { + public static RawUid2Result OptoutIdentity = new RawUid2Result(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) public final byte[] rawUid; public final String bucketId; - public MappedIdentityResult(byte[] rawUid, String bucketId) { + public RawUid2Result(byte[] rawUid, String bucketId) { this.rawUid = rawUid; this.bucketId = bucketId; } diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index 252acece3..31022953b 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -4,11 +4,11 @@ public class RefreshResponse { - public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, IdentityResponse.invalidIdentityResponse); - public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.invalidIdentityResponse); - public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.invalidIdentityResponse); - public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.invalidIdentityResponse); - public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.invalidIdentityResponse); + public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, IdentityResponse.optOutIdentityResponse); + public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.optOutIdentityResponse); + public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.optOutIdentityResponse); + public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.optOutIdentityResponse); + public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.optOutIdentityResponse); private final Status status; private final IdentityResponse identityResponse; private final Duration durationSinceLastRefresh; diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 9c3cd2d89..c61f27aa4 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -16,10 +16,10 @@ public interface IUIDOperatorService { RefreshResponse refreshIdentity(RefreshTokenInput refreshTokenInput); - MappedIdentityResult mapIdentity(MapRequest request); + RawUid2Result mapIdentity(MapRequest request); @Deprecated - MappedIdentityResult map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + RawUid2Result map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 7b5c88e8e..1931a1434 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -113,7 +113,7 @@ public IdentityResponse generateIdentity(IdentityRequest request) { request.hashedDiiIdentity.establishedAt, request.hashedDiiIdentity.refreshedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return IdentityResponse.invalidIdentityResponse; + return IdentityResponse.optOutIdentityResponse; } else { return generateIdentity(request.sourcePublisher, firstLevelHashIdentity); } @@ -160,20 +160,20 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { } @Override - public MappedIdentityResult mapIdentity(MapRequest request) { + public RawUid2Result mapIdentity(MapRequest request) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return MappedIdentityResult.OptoutIdentity; + return RawUid2Result.OptoutIdentity; } else { - return generateMappedIdentity(firstLevelHashIdentity, request.asOf); + return generateRawUid(firstLevelHashIdentity, request.asOf); } } @Override - public MappedIdentityResult map(HashedDiiIdentity diiIdentity, Instant asOf) { + public RawUid2Result map(HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - return generateMappedIdentity(firstLevelHashIdentity, asOf); + return generateRawUid(firstLevelHashIdentity, asOf); } @Override @@ -194,9 +194,9 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(hashedDiiIdentity, asOf); + final RawUid2Result rawUid2Result = generateRawUid(hashedDiiIdentity, asOf); - this.optOutStore.addEntry(hashedDiiIdentity, mappedIdentityResult.rawUid, r -> { + this.optOutStore.addEntry(hashedDiiIdentity, rawUid2Result.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -208,10 +208,10 @@ public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, H @Override public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(firstLevelHashIdentity, asOf); + final RawUid2Result rawUid2Result = generateRawUid(firstLevelHashIdentity, asOf); final AdvertisingTokenInput token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(mappedIdentityResult.rawUid, token.rawUidIdentity.rawUid); + return Arrays.equals(rawUid2Result.rawUid, token.rawUidIdentity.rawUid); } @Override @@ -238,10 +238,10 @@ private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private MappedIdentityResult generateMappedIdentity(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { + private RawUid2Result generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); - return new MappedIdentityResult( + return new RawUid2Result( this.identityV3Enabled ? TokenUtils.getAdvertisingIdV3(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) @@ -252,10 +252,10 @@ private MappedIdentityResult generateMappedIdentity(FirstLevelHashIdentity first private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final MappedIdentityResult mappedIdentityResult = generateMappedIdentity(firstLevelHashIdentity, nowUtc); + final RawUid2Result rawUid2Result = generateRawUid(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - mappedIdentityResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); + rawUid2Result.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc), diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 43585c664..7f32b2afc 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1241,11 +1241,11 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final MappedIdentityResult mappedIdentityResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + final RawUid2Result rawUid2Result = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); - jsonObject.put("advertising_id", EncodingUtils.toBase64String(mappedIdentityResult.rawUid)); - jsonObject.put("bucket_id", mappedIdentityResult.bucketId); + jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUid2Result.rawUid)); + jsonObject.put("bucket_id", rawUid2Result.bucketId); ResponseUtil.Success(rc, jsonObject); } catch (Exception e) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State", e); @@ -1264,8 +1264,8 @@ else if (!input.isValid()) { } else { final Instant now = Instant.now(); - final MappedIdentityResult mappedIdentityResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); - rc.response().end(EncodingUtils.toBase64String(mappedIdentityResult.rawUid)); + final RawUid2Result rawUid2Result = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + rc.response().end(EncodingUtils.toBase64String(rawUid2Result.rawUid)); } } catch (Exception ex) { LOGGER.error("Unexpected error while mapping identity", ex); @@ -1460,13 +1460,13 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal for (int i = 0; i < count; ++i) { final InputUtil.InputVal input = inputList[i]; if (input != null && input.isValid()) { - final MappedIdentityResult mappedIdentityResult = idService.mapIdentity( + final RawUid2Result rawUid2Result = idService.mapIdentity( new MapRequest( input.toHashedDiiIdentity(this.identityScope, 0, now), OptoutCheckPolicy.respectOptOut(), now)); - if (mappedIdentityResult.isOptedOut()) { + if (rawUid2Result.isOptedOut()) { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); resp.put("reason", "optout"); @@ -1475,8 +1475,8 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal } else { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); - resp.put("advertising_id", EncodingUtils.toBase64String(mappedIdentityResult.rawUid)); - resp.put("bucket_id", mappedIdentityResult.bucketId); + resp.put("advertising_id", EncodingUtils.toBase64String(rawUid2Result.rawUid)); + resp.put("bucket_id", rawUid2Result.bucketId); mapped.add(resp); } } else { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 07f072ac7..7e114caa8 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -327,27 +327,27 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final MappedIdentityResult mappedIdentityResult; - final MappedIdentityResult mappedIdentityResultShouldBeOptOut; + final RawUid2Result rawUid2Result; + final RawUid2Result rawUid2ResultShouldBeOptOut; if (scope == IdentityScope.UID2) { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - mappedIdentityResult = uid2Service.mapIdentity(mapRequestForceMap); + rawUid2Result = uid2Service.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - mappedIdentityResultShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUid2ResultShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); } else { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - mappedIdentityResult = euidService.mapIdentity(mapRequestForceMap); + rawUid2Result = euidService.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - mappedIdentityResultShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); + rawUid2ResultShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentityResult); - assertFalse(mappedIdentityResult.isOptedOut()); - assertNotNull(mappedIdentityResultShouldBeOptOut); - assertTrue(mappedIdentityResultShouldBeOptOut.isOptedOut()); + assertNotNull(rawUid2Result); + assertFalse(rawUid2Result.isOptedOut()); + assertNotNull(rawUid2ResultShouldBeOptOut); + assertTrue(rawUid2ResultShouldBeOptOut.isOptedOut()); } private enum TestIdentityInputType { @@ -411,7 +411,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertEquals(identityResponse, IdentityResponse.invalidIdentityResponse); + assertEquals(identityResponse, IdentityResponse.optOutIdentityResponse); } @ParameterizedTest @@ -434,17 +434,17 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, // identity has no optout record, ensure map still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final MappedIdentityResult mappedIdentityResult; + final RawUid2Result rawUid2Result; if(scope == IdentityScope.EUID) { - mappedIdentityResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUid2Result = euidService.mapIdentity(mapRequestRespectOptOut); } else { - mappedIdentityResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUid2Result = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentityResult); - assertTrue(mappedIdentityResult.isOptedOut()); + assertNotNull(rawUid2Result); + assertTrue(rawUid2Result.isOptedOut()); } @ParameterizedTest @@ -475,7 +475,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -517,7 +517,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -548,17 +548,17 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str // all identities have optout records, ensure refresh-optout identities still map when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final MappedIdentityResult mappedIdentityResult; + final RawUid2Result rawUid2Result; if(scope == IdentityScope.EUID) { - mappedIdentityResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUid2Result = euidService.mapIdentity(mapRequestRespectOptOut); } else { - mappedIdentityResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUid2Result = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentityResult); - assertFalse(mappedIdentityResult.isOptedOut()); + assertNotNull(rawUid2Result); + assertFalse(rawUid2Result.isOptedOut()); } @ParameterizedTest @@ -594,7 +594,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); assertNotNull(advertisingTokenInput.rawUidIdentity); } @@ -619,17 +619,17 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i // all identities have optout records, ensure validate identities still get mapped when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final MappedIdentityResult mappedIdentityResult; + final RawUid2Result rawUid2Result; if(scope == IdentityScope.EUID) { - mappedIdentityResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUid2Result = euidService.mapIdentity(mapRequestRespectOptOut); } else { - mappedIdentityResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUid2Result = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(mappedIdentityResult); - assertFalse(mappedIdentityResult.isOptedOut()); + assertNotNull(rawUid2Result); + assertFalse(rawUid2Result.isOptedOut()); } @ParameterizedTest @@ -655,7 +655,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotEquals(identityResponse, IdentityResponse.invalidIdentityResponse); + assertNotEquals(identityResponse, IdentityResponse.optOutIdentityResponse); assertNotNull(identityResponse); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); @@ -721,7 +721,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.invalidIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); assertNotNull(advertisingTokenInput.rawUidIdentity); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); @@ -737,18 +737,18 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); - final MappedIdentityResult mappedIdentityResult; + final RawUid2Result rawUid2Result; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - mappedIdentityResult = euidService.mapIdentity(mapRequest); + rawUid2Result = euidService.mapIdentity(mapRequest); } else { - mappedIdentityResult = uid2Service.mapIdentity(mapRequest); + rawUid2Result = uid2Service.mapIdentity(mapRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(mappedIdentityResult); - assertFalse(mappedIdentityResult.isOptedOut()); + assertNotNull(rawUid2Result); + assertFalse(rawUid2Result.isOptedOut()); } } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index bbafba89a..0de1126a5 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -25,13 +25,13 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) - public MappedIdentityResult IdentityMapRawThroughput() { + public RawUid2Result IdentityMapRawThroughput() { return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) - public MappedIdentityResult IdentityMapWithOptOutThroughput() { + public RawUid2Result IdentityMapWithOptOutThroughput() { return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } From 91ffa125a98e373bc644d7e6379d3ab6bd56ea70 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 15:43:19 +1100 Subject: [PATCH 19/61] 1. Fixed RawUid2Result to RawUidResult 2. Renamed AdvertisingId to RawUid in most operator codes (except optout store related) --- .../{RawUid2Result.java => RawUidResult.java} | 6 +- .../service/EncryptedTokenEncoder.java | 4 +- .../operator/service/IUIDOperatorService.java | 4 +- .../com/uid2/operator/service/TokenUtils.java | 20 +++---- .../operator/service/UIDOperatorService.java | 26 ++++---- .../operator/vertx/UIDOperatorVerticle.java | 18 +++--- .../uid2/operator/UIDOperatorServiceTest.java | 60 +++++++++---------- .../operator/UIDOperatorVerticleTest.java | 48 +++++++-------- .../benchmark/IdentityMapBenchmark.java | 4 +- 9 files changed, 95 insertions(+), 95 deletions(-) rename src/main/java/com/uid2/operator/model/{RawUid2Result.java => RawUidResult.java} (72%) diff --git a/src/main/java/com/uid2/operator/model/RawUid2Result.java b/src/main/java/com/uid2/operator/model/RawUidResult.java similarity index 72% rename from src/main/java/com/uid2/operator/model/RawUid2Result.java rename to src/main/java/com/uid2/operator/model/RawUidResult.java index 7bc93a451..5348700e0 100644 --- a/src/main/java/com/uid2/operator/model/RawUid2Result.java +++ b/src/main/java/com/uid2/operator/model/RawUidResult.java @@ -1,13 +1,13 @@ package com.uid2.operator.model; // Contains the computed raw UID and its bucket ID from identity/map request -public class RawUid2Result { - public static RawUid2Result OptoutIdentity = new RawUid2Result(new byte[33], ""); +public class RawUidResult { + public static RawUidResult OptoutIdentity = new RawUidResult(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) public final byte[] rawUid; public final String bucketId; - public RawUid2Result(byte[] rawUid, String bucketId) { + public RawUidResult(byte[] rawUid, String bucketId) { this.rawUid = rawUid; this.bucketId = bucketId; } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index ab70aeea3..77a545c62 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -217,7 +217,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { final int siteId = b3.getInt(0); final int length = b3.getInt(4); - final byte[] advertisingId = EncodingUtils.fromBase64(b3.slice(8, 8 + length).getBytes()); + final byte[] getRawUid = EncodingUtils.fromBase64(b3.slice(8, 8 + length).getBytes()); final int privacyBits = b3.getInt(8 + length); final long establishedMillis = b3.getLong(8 + length + 4); @@ -228,7 +228,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new SourcePublisher(siteId, siteKeyId, 0), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, advertisingId, privacyBits, + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, getRawUid, privacyBits, Instant.ofEpochMilli(establishedMillis), null) ); diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index c61f27aa4..c2bf091d2 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -16,10 +16,10 @@ public interface IUIDOperatorService { RefreshResponse refreshIdentity(RefreshTokenInput refreshTokenInput); - RawUid2Result mapIdentity(MapRequest request); + RawUidResult mapIdentity(MapRequest request); @Deprecated - RawUid2Result map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + RawUidResult map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); diff --git a/src/main/java/com/uid2/operator/service/TokenUtils.java b/src/main/java/com/uid2/operator/service/TokenUtils.java index 4a13145c6..b42ac3c5f 100644 --- a/src/main/java/com/uid2/operator/service/TokenUtils.java +++ b/src/main/java/com/uid2/operator/service/TokenUtils.java @@ -27,19 +27,19 @@ public static byte[] getFirstLevelHashFromIdentityHash(String identityHash, Stri return EncodingUtils.getSha256Bytes(identityHash, firstLevelSalt); } - public static byte[] getAdvertisingIdV2(byte[] firstLevelHash, String rotatingSalt) { + public static byte[] getRawUidV2(byte[] firstLevelHash, String rotatingSalt) { return EncodingUtils.getSha256Bytes(EncodingUtils.toBase64String(firstLevelHash), rotatingSalt); } - public static byte[] getAdvertisingIdV2FromIdentity(String identityString, String firstLevelSalt, String rotatingSalt) { - return getAdvertisingIdV2(getFirstLevelHashFromIdentity(identityString, firstLevelSalt), rotatingSalt); + public static byte[] getRawUidV2FromIdentity(String identityString, String firstLevelSalt, String rotatingSalt) { + return getRawUidV2(getFirstLevelHashFromIdentity(identityString, firstLevelSalt), rotatingSalt); } - public static byte[] getAdvertisingIdV2FromIdentityHash(String identityString, String firstLevelSalt, String rotatingSalt) { - return getAdvertisingIdV2(getFirstLevelHashFromIdentityHash(identityString, firstLevelSalt), rotatingSalt); + public static byte[] getRawUidV2FromIdentityHash(String identityString, String firstLevelSalt, String rotatingSalt) { + return getRawUidV2(getFirstLevelHashFromIdentityHash(identityString, firstLevelSalt), rotatingSalt); } - public static byte[] getAdvertisingIdV3(IdentityScope scope, IdentityType type, byte[] firstLevelHash, String rotatingSalt) { + public static byte[] getRawUidV3(IdentityScope scope, IdentityType type, byte[] firstLevelHash, String rotatingSalt) { final byte[] sha = EncodingUtils.getSha256Bytes(EncodingUtils.toBase64String(firstLevelHash), rotatingSalt); final byte[] id = new byte[33]; id[0] = (byte)(encodeIdentityScope(scope) | encodeIdentityType(type)); @@ -47,12 +47,12 @@ public static byte[] getAdvertisingIdV3(IdentityScope scope, IdentityType type, return id; } - public static byte[] getAdvertisingIdV3FromIdentity(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { - return getAdvertisingIdV3(scope, type, getFirstLevelHashFromIdentity(identityString, firstLevelSalt), rotatingSalt); + public static byte[] getRawUidV3FromIdentity(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { + return getRawUidV3(scope, type, getFirstLevelHashFromIdentity(identityString, firstLevelSalt), rotatingSalt); } - public static byte[] getAdvertisingIdV3FromIdentityHash(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { - return getAdvertisingIdV3(scope, type, getFirstLevelHashFromIdentityHash(identityString, firstLevelSalt), rotatingSalt); + public static byte[] getRawUidV3FromIdentityHash(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { + return getRawUidV3(scope, type, getFirstLevelHashFromIdentityHash(identityString, firstLevelSalt), rotatingSalt); } public static byte encodeIdentityScope(IdentityScope identityScope) { diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 1931a1434..5d7b229d2 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -160,18 +160,18 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { } @Override - public RawUid2Result mapIdentity(MapRequest request) { + public RawUidResult mapIdentity(MapRequest request) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return RawUid2Result.OptoutIdentity; + return RawUidResult.OptoutIdentity; } else { return generateRawUid(firstLevelHashIdentity, request.asOf); } } @Override - public RawUid2Result map(HashedDiiIdentity diiIdentity, Instant asOf) { + public RawUidResult map(HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); return generateRawUid(firstLevelHashIdentity, asOf); } @@ -194,9 +194,9 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUid2Result rawUid2Result = generateRawUid(hashedDiiIdentity, asOf); + final RawUidResult rawUidResult = generateRawUid(hashedDiiIdentity, asOf); - this.optOutStore.addEntry(hashedDiiIdentity, rawUid2Result.rawUid, r -> { + this.optOutStore.addEntry(hashedDiiIdentity, rawUidResult.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -208,10 +208,10 @@ public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, H @Override public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUid2Result rawUid2Result = generateRawUid(firstLevelHashIdentity, asOf); + final RawUidResult rawUidResult = generateRawUid(firstLevelHashIdentity, asOf); final AdvertisingTokenInput token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(rawUid2Result.rawUid, token.rawUidIdentity.rawUid); + return Arrays.equals(rawUidResult.rawUid, token.rawUidIdentity.rawUid); } @Override @@ -238,24 +238,24 @@ private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private RawUid2Result generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { + private RawUidResult generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); - return new RawUid2Result( + return new RawUidResult( this.identityV3Enabled - ? TokenUtils.getAdvertisingIdV3(firstLevelHashIdentity.identityScope, + ? TokenUtils.getRawUidV3(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) - : TokenUtils.getAdvertisingIdV2(firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()), + : TokenUtils.getRawUidV2(firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()), rotatingSalt.getHashedId()); } private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final RawUid2Result rawUid2Result = generateRawUid(firstLevelHashIdentity, nowUtc); + final RawUidResult rawUidResult = generateRawUid(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - rawUid2Result.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); + rawUidResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc), diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 7f32b2afc..69e002988 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1241,11 +1241,11 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final RawUid2Result rawUid2Result = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + final RawUidResult rawUidResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); - jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUid2Result.rawUid)); - jsonObject.put("bucket_id", rawUid2Result.bucketId); + jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUidResult.rawUid)); + jsonObject.put("bucket_id", rawUidResult.bucketId); ResponseUtil.Success(rc, jsonObject); } catch (Exception e) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State", e); @@ -1264,8 +1264,8 @@ else if (!input.isValid()) { } else { final Instant now = Instant.now(); - final RawUid2Result rawUid2Result = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); - rc.response().end(EncodingUtils.toBase64String(rawUid2Result.rawUid)); + final RawUidResult rawUidResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + rc.response().end(EncodingUtils.toBase64String(rawUidResult.rawUid)); } } catch (Exception ex) { LOGGER.error("Unexpected error while mapping identity", ex); @@ -1460,13 +1460,13 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal for (int i = 0; i < count; ++i) { final InputUtil.InputVal input = inputList[i]; if (input != null && input.isValid()) { - final RawUid2Result rawUid2Result = idService.mapIdentity( + final RawUidResult rawUidResult = idService.mapIdentity( new MapRequest( input.toHashedDiiIdentity(this.identityScope, 0, now), OptoutCheckPolicy.respectOptOut(), now)); - if (rawUid2Result.isOptedOut()) { + if (rawUidResult.isOptedOut()) { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); resp.put("reason", "optout"); @@ -1475,8 +1475,8 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal } else { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); - resp.put("advertising_id", EncodingUtils.toBase64String(rawUid2Result.rawUid)); - resp.put("bucket_id", rawUid2Result.bucketId); + resp.put("advertising_id", EncodingUtils.toBase64String(rawUidResult.rawUid)); + resp.put("bucket_id", rawUidResult.bucketId); mapped.add(resp); } } else { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 7e114caa8..32c32ebbd 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -327,27 +327,27 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final RawUid2Result rawUid2Result; - final RawUid2Result rawUid2ResultShouldBeOptOut; + final RawUidResult rawUidResult; + final RawUidResult rawUidResultShouldBeOptOut; if (scope == IdentityScope.UID2) { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUid2Result = uid2Service.mapIdentity(mapRequestForceMap); + rawUidResult = uid2Service.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUid2ResultShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResultShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); } else { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUid2Result = euidService.mapIdentity(mapRequestForceMap); + rawUidResult = euidService.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUid2ResultShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResultShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUid2Result); - assertFalse(rawUid2Result.isOptedOut()); - assertNotNull(rawUid2ResultShouldBeOptOut); - assertTrue(rawUid2ResultShouldBeOptOut.isOptedOut()); + assertNotNull(rawUidResult); + assertFalse(rawUidResult.isOptedOut()); + assertNotNull(rawUidResultShouldBeOptOut); + assertTrue(rawUidResultShouldBeOptOut.isOptedOut()); } private enum TestIdentityInputType { @@ -434,17 +434,17 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, // identity has no optout record, ensure map still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RawUid2Result rawUid2Result; + final RawUidResult rawUidResult; if(scope == IdentityScope.EUID) { - rawUid2Result = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUid2Result = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUid2Result); - assertTrue(rawUid2Result.isOptedOut()); + assertNotNull(rawUidResult); + assertTrue(rawUidResult.isOptedOut()); } @ParameterizedTest @@ -548,17 +548,17 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str // all identities have optout records, ensure refresh-optout identities still map when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUid2Result rawUid2Result; + final RawUidResult rawUidResult; if(scope == IdentityScope.EUID) { - rawUid2Result = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUid2Result = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUid2Result); - assertFalse(rawUid2Result.isOptedOut()); + assertNotNull(rawUidResult); + assertFalse(rawUidResult.isOptedOut()); } @ParameterizedTest @@ -619,17 +619,17 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i // all identities have optout records, ensure validate identities still get mapped when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUid2Result rawUid2Result; + final RawUidResult rawUidResult; if(scope == IdentityScope.EUID) { - rawUid2Result = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUid2Result = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUid2Result); - assertFalse(rawUid2Result.isOptedOut()); + assertNotNull(rawUidResult); + assertFalse(rawUidResult.isOptedOut()); } @ParameterizedTest @@ -737,18 +737,18 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); - final RawUid2Result rawUid2Result; + final RawUidResult rawUidResult; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - rawUid2Result = euidService.mapIdentity(mapRequest); + rawUidResult = euidService.mapIdentity(mapRequest); } else { - rawUid2Result = uid2Service.mapIdentity(mapRequest); + rawUidResult = uid2Service.mapIdentity(mapRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(rawUid2Result); - assertFalse(rawUid2Result.isOptedOut()); + assertNotNull(rawUidResult); + assertFalse(rawUidResult.isOptedOut()); } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index b9c64a843..ea8385779 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -622,26 +622,26 @@ private void assertTokenStatusMetrics(Integer siteId, TokenResponseStatsCollecto assertEquals(1, actual); } - private byte[] getAdvertisingIdFromIdentity(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt) { + private byte[] getRawUidFromIdentity(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt) { return getRawUid(identityType, identityString, firstLevelSalt, rotatingSalt, getIdentityScope(), useIdentityV3()); } private static byte[] getRawUid(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt, IdentityScope identityScope, boolean useIdentityV3) { return !useIdentityV3 - ? TokenUtils.getAdvertisingIdV2FromIdentity(identityString, firstLevelSalt, rotatingSalt) - : TokenUtils.getAdvertisingIdV3FromIdentity(identityScope, identityType, identityString, firstLevelSalt, rotatingSalt); + ? TokenUtils.getRawUidV2FromIdentity(identityString, firstLevelSalt, rotatingSalt) + : TokenUtils.getRawUidV3FromIdentity(identityScope, identityType, identityString, firstLevelSalt, rotatingSalt); } public static byte[] getRawUid(IdentityType identityType, String identityString, IdentityScope identityScope, boolean useIdentityV3) { return !useIdentityV3 - ? TokenUtils.getAdvertisingIdV2FromIdentity(identityString, firstLevelSalt, rotatingSalt123.getSalt()) - : TokenUtils.getAdvertisingIdV3FromIdentity(identityScope, identityType, identityString, firstLevelSalt, rotatingSalt123.getSalt()); + ? TokenUtils.getRawUidV2FromIdentity(identityString, firstLevelSalt, rotatingSalt123.getSalt()) + : TokenUtils.getRawUidV3FromIdentity(identityScope, identityType, identityString, firstLevelSalt, rotatingSalt123.getSalt()); } - private byte[] getAdvertisingIdFromIdentityHash(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt) { + private byte[] getRawUidFromIdentityHash(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt) { return !useIdentityV3() - ? TokenUtils.getAdvertisingIdV2FromIdentityHash(identityString, firstLevelSalt, rotatingSalt) - : TokenUtils.getAdvertisingIdV3FromIdentityHash(getIdentityScope(), identityType, identityString, firstLevelSalt, rotatingSalt); + ? TokenUtils.getRawUidV2FromIdentityHash(identityString, firstLevelSalt, rotatingSalt) + : TokenUtils.getRawUidV3FromIdentityHash(getIdentityScope(), identityType, identityString, firstLevelSalt, rotatingSalt); } private JsonObject createBatchEmailsRequestPayload() { @@ -1169,12 +1169,12 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, identityType); RefreshTokenInput refreshTokenInput = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); - final byte[] advertisingId = getAdvertisingIdFromIdentity(identityType, + final byte[] rawUid = getRawUidFromIdentity(identityType, optOutTokenInput.getNormalized(), firstLevelSalt, rotatingSalt123.getSalt()); final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity(optOutTokenInput.getNormalized(), firstLevelSalt); - assertArrayEquals(advertisingId, advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(rawUid, advertisingTokenInput.rawUidIdentity.rawUid); assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); String advertisingTokenString = body.getString("advertising_token"); @@ -1232,7 +1232,7 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); @@ -1274,7 +1274,7 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); @@ -1318,7 +1318,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); @@ -1377,7 +1377,7 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); @@ -1552,7 +1552,7 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); @@ -1589,7 +1589,7 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); @@ -2301,9 +2301,9 @@ void optOutStatusRequest(Map optedOutIds, int optedOutCount, Role assertEquals(optedOutCount, optOutJsonArray.size()); for (int i = 0; i < optOutJsonArray.size(); ++i) { JsonObject optOutObject = optOutJsonArray.getJsonObject(i); - String advertisingId = optOutObject.getString("advertising_id"); - assertTrue(optedOutIds.containsKey(advertisingId)); - long expectedTimestamp = Instant.ofEpochSecond(optedOutIds.get(advertisingId)).toEpochMilli(); + String rawUid = optOutObject.getString("advertising_id"); + assertTrue(optedOutIds.containsKey(rawUid)); + long expectedTimestamp = Instant.ofEpochSecond(optedOutIds.get(rawUid)).toEpochMilli(); assertEquals(expectedTimestamp, optOutObject.getLong("opted_out_since")); } testContext.completeNow(); @@ -2501,7 +2501,7 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); @@ -2540,7 +2540,7 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); @@ -2584,7 +2584,7 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getAdvertisingIdFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); @@ -4205,7 +4205,7 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisin final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits); final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshTokenInput.firstLevelHashIdentity.privacyBits); - final byte[] advertisingId = getAdvertisingIdFromIdentity(identityType, + final byte[] rawUid = getRawUidFromIdentity(identityType, identity, firstLevelSalt, rotatingSalt123.getSalt()); @@ -4222,7 +4222,7 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisin () -> assertEquals(siteId, advertisingTokenInput.sourcePublisher.siteId, "Advertising token site ID is incorrect"), () -> assertEquals(siteId, refreshTokenInput.sourcePublisher.siteId, "Refresh token site ID is incorrect"), - () -> assertArrayEquals(advertisingId, advertisingTokenInput.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), + () -> assertArrayEquals(rawUid, advertisingTokenInput.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), () -> assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") ); } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 0de1126a5..acf5b8e2e 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -25,13 +25,13 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUid2Result IdentityMapRawThroughput() { + public RawUidResult IdentityMapRawThroughput() { return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUid2Result IdentityMapWithOptOutThroughput() { + public RawUidResult IdentityMapWithOptOutThroughput() { return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } From 4bb4ccb8c962f19950846f29c3763023a03ecac3 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 16:17:32 +1100 Subject: [PATCH 20/61] Renamed IdentityResponse.optOutIdentityResponse to OptOutIdentityResponse --- .../com/uid2/operator/model/IdentityResponse.java | 2 +- .../com/uid2/operator/model/RefreshResponse.java | 10 +++++----- .../uid2/operator/service/UIDOperatorService.java | 2 +- .../com/uid2/operator/UIDOperatorServiceTest.java | 12 ++++++------ 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 8b840de0e..d8686d8d1 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -7,7 +7,7 @@ // this defines all the fields for the response of the /token/generate and /client/generate endpoints before they are // json-ised public class IdentityResponse { - public static IdentityResponse optOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); + public static IdentityResponse OptOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; private final TokenVersion advertisingTokenVersion; private final String refreshToken; diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index 31022953b..2a520fcc4 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -4,11 +4,11 @@ public class RefreshResponse { - public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, IdentityResponse.optOutIdentityResponse); - public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.optOutIdentityResponse); - public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.optOutIdentityResponse); - public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.optOutIdentityResponse); - public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.optOutIdentityResponse); + public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, IdentityResponse.OptOutIdentityResponse); + public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.OptOutIdentityResponse); + public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.OptOutIdentityResponse); + public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.OptOutIdentityResponse); + public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.OptOutIdentityResponse); private final Status status; private final IdentityResponse identityResponse; private final Duration durationSinceLastRefresh; diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 5d7b229d2..6abc1439c 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -113,7 +113,7 @@ public IdentityResponse generateIdentity(IdentityRequest request) { request.hashedDiiIdentity.establishedAt, request.hashedDiiIdentity.refreshedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return IdentityResponse.optOutIdentityResponse; + return IdentityResponse.OptOutIdentityResponse; } else { return generateIdentity(request.sourcePublisher, firstLevelHashIdentity); } diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 32c32ebbd..6a57f1e40 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -411,7 +411,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertEquals(identityResponse, IdentityResponse.optOutIdentityResponse); + assertEquals(identityResponse, IdentityResponse.OptOutIdentityResponse); } @ParameterizedTest @@ -475,7 +475,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -517,7 +517,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -594,7 +594,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); assertNotNull(advertisingTokenInput.rawUidIdentity); } @@ -655,7 +655,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotEquals(identityResponse, IdentityResponse.optOutIdentityResponse); + assertNotEquals(identityResponse, IdentityResponse.OptOutIdentityResponse); assertNotNull(identityResponse); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); @@ -721,7 +721,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.optOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); assertNotNull(advertisingTokenInput.rawUidIdentity); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); From 8ae5e0804298a3d0d1cd9f8a2fd5077af45adfd4 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 14 Oct 2024 16:59:37 +1100 Subject: [PATCH 21/61] Renamed IdentityResponse.optoutIdentityResponse to OptOutIdentityResponse --- src/main/java/com/uid2/operator/model/IdentityResponse.java | 2 +- .../java/com/uid2/operator/vertx/UIDOperatorVerticle.java | 4 ++-- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index d8686d8d1..6f802821b 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -49,7 +49,7 @@ public Instant getRefreshFrom() { return refreshFrom; } - public boolean isNotValid() { + public boolean isOptedout() { return advertisingToken == null || advertisingToken.isEmpty(); } } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 69e002988..de9cb3c8a 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -474,7 +474,7 @@ else if(emailHash != null) { JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; - if (identityResponse.isNotValid()) { + if (identityResponse.isOptedout()) { response = ResponseUtil.SuccessNoBodyV2(ResponseStatus.OptOut); responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } @@ -999,7 +999,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.respectOptOut())); - if (t.isNotValid()) { + if (t.isOptedout()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy final InputUtil.InputVal optOutTokenInput = input.getIdentityType() == IdentityType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 6a57f1e40..7b01b7180 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -211,7 +211,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertFalse(identityResponse.isNotValid()); + assertFalse(identityResponse.isOptedout()); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenInput)); @@ -227,7 +227,7 @@ public void testTestOptOutKey_RespectOptout() { OptoutCheckPolicy.RespectOptOut ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); - assertTrue(identityResponse.isNotValid()); + assertTrue(identityResponse.isOptedout()); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); } From b507d8e8ae55c493c8ddf5391428fe66eb1d192d Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 16:57:13 +1100 Subject: [PATCH 22/61] Fixed UserIdentity member variables as final and added constructor --- .../userIdentity/FirstLevelHashIdentity.java | 6 +----- .../model/userIdentity/HashedDiiIdentity.java | 6 +----- .../model/userIdentity/RawUidIdentity.java | 6 +----- .../model/userIdentity/UserIdentity.java | 21 +++++++++++-------- .../uid2/operator/UIDOperatorServiceTest.java | 6 +++--- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index 4286d2a0c..cac4f970e 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -12,12 +12,8 @@ public class FirstLevelHashIdentity extends UserIdentity { public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, int privacyBits, Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; + super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); this.firstLevelHash = firstLevelHash; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; } public boolean matches(FirstLevelHashIdentity that) { diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java index c5b162315..25baaf308 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java @@ -12,11 +12,7 @@ public class HashedDiiIdentity extends UserIdentity{ public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; + super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); this.hashedDii = hashedDii; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java index 7af6edf5b..4e15c6ff0 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java @@ -12,12 +12,8 @@ public class RawUidIdentity extends UserIdentity { public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid, int privacyBits, Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; + super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); this.rawUid = rawUid; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; } public boolean matches(RawUidIdentity that) { diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java index 0e16cc4ed..362b89fbe 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -8,14 +8,17 @@ //base class for all other HshedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields public class UserIdentity { - public IdentityScope identityScope; - public IdentityType identityType; - public int privacyBits; - public Instant establishedAt; - public Instant refreshedAt; + public final IdentityScope identityScope; + public final IdentityType identityType; + public final int privacyBits; + public final Instant establishedAt; + public final Instant refreshedAt; - public IdentityScope GetIdentityScope() { return identityScope; } - public IdentityType GetIdentityType() { return identityType; } - public Instant GetEstablishedAt() { return establishedAt; }; - public Instant GetIRefreshedAt() { return refreshedAt; } + public UserIdentity(IdentityScope identityScope, IdentityType identityType, int privacyBits, Instant establishedAt, Instant refreshedAt) { + this.identityScope = identityScope; + this.identityType = identityType; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; + this.refreshedAt = refreshedAt; + } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 7b01b7180..6b2459eca 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -142,9 +142,9 @@ private AdvertisingTokenInput validateAndGetToken(EncryptedTokenEncoder tokenEnc private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expctedValues, UserIdentity actualValues) { - assertEquals(expctedValues.GetIdentityScope(), actualValues.GetIdentityScope()); - assertEquals(expctedValues.GetIdentityType(), actualValues.GetIdentityType()); - assertEquals(expctedValues.GetEstablishedAt(), actualValues.GetEstablishedAt()); + assertEquals(expctedValues.identityScope, actualValues.identityScope); + assertEquals(expctedValues.identityType, actualValues.identityType); + assertEquals(expctedValues.establishedAt, actualValues.establishedAt); } @ParameterizedTest From f5877b76a9c651b37a680cd3db31d7f9270c7ee9 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 17:45:46 +1100 Subject: [PATCH 23/61] 1. Addressed code review feedbacks 2. Renamed RawUidResult to RawUidResponse 3. rename some id variable to rawUid to make it clearer 4. more comments --- .../java/com/uid2/operator/IdentityConst.java | 7 +- .../uid2/operator/model/IdentityResponse.java | 4 +- ...{RawUidResult.java => RawUidResponse.java} | 7 +- .../userIdentity/FirstLevelHashIdentity.java | 2 +- .../model/userIdentity/HashedDiiIdentity.java | 6 +- .../service/EncryptedTokenEncoder.java | 15 ++--- .../operator/service/IUIDOperatorService.java | 4 +- .../operator/service/UIDOperatorService.java | 22 +++---- .../operator/store/CloudSyncOptOutStore.java | 2 +- .../com/uid2/operator/store/IOptOutStore.java | 5 +- .../operator/vertx/UIDOperatorVerticle.java | 22 +++---- .../uid2/operator/UIDOperatorServiceTest.java | 64 +++++++++---------- .../benchmark/IdentityMapBenchmark.java | 4 +- 13 files changed, 83 insertions(+), 81 deletions(-) rename src/main/java/com/uid2/operator/model/{RawUidResult.java => RawUidResponse.java} (66%) diff --git a/src/main/java/com/uid2/operator/IdentityConst.java b/src/main/java/com/uid2/operator/IdentityConst.java index 0263d4e76..9362ade6e 100644 --- a/src/main/java/com/uid2/operator/IdentityConst.java +++ b/src/main/java/com/uid2/operator/IdentityConst.java @@ -3,9 +3,11 @@ import com.uid2.operator.service.EncodingUtils; public class IdentityConst { + // DIIs for generating optout tokens for legacy participants - to be deprecated public static final String OptOutTokenIdentityForEmail = "optout@unifiedid.com"; public static final String OptOutTokenIdentityForPhone = "+00000000001"; + // DIIs for for testing with token/validate endpoint, see https://unifiedid.com/docs/endpoints/post-token-validate public static final String ValidateIdentityForEmail = "validate@example.com"; public static final String ValidateIdentityForPhone = "+12345678901"; public static final byte[] ValidateIdentityForEmailHash = EncodingUtils.getSha256Bytes(IdentityConst.ValidateIdentityForEmail); @@ -15,9 +17,8 @@ public class IdentityConst { public static final String OptOutIdentityForEmail = "optout@example.com"; public static final String OptOutIdentityForPhone = "+00000000000"; + // DIIs to use when you want to generate a UID token but when doing refresh token, you want to always get an optout response + // to test the optout handling workflow public static final String RefreshOptOutIdentityForEmail = "refresh-optout@example.com"; public static final String RefreshOptOutIdentityForPhone = "+00000000002"; - - - } diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 78dee24ed..8b3ad4a43 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -6,7 +6,7 @@ import java.time.Instant; // this defines all the fields for the response of the /token/generate and /client/generate endpoints before they are -// json-ised +// jsonified public class IdentityResponse { public static IdentityResponse OptOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; @@ -50,7 +50,7 @@ public Instant getRefreshFrom() { return refreshFrom; } - public boolean isOptedout() { + public boolean isOptedOut() { return advertisingToken == null || advertisingToken.isEmpty(); } diff --git a/src/main/java/com/uid2/operator/model/RawUidResult.java b/src/main/java/com/uid2/operator/model/RawUidResponse.java similarity index 66% rename from src/main/java/com/uid2/operator/model/RawUidResult.java rename to src/main/java/com/uid2/operator/model/RawUidResponse.java index 5348700e0..249bef4c5 100644 --- a/src/main/java/com/uid2/operator/model/RawUidResult.java +++ b/src/main/java/com/uid2/operator/model/RawUidResponse.java @@ -1,17 +1,18 @@ package com.uid2.operator.model; // Contains the computed raw UID and its bucket ID from identity/map request -public class RawUidResult { - public static RawUidResult OptoutIdentity = new RawUidResult(new byte[33], ""); +public class RawUidResponse { + public static RawUidResponse OptoutIdentity = new RawUidResponse(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) public final byte[] rawUid; public final String bucketId; - public RawUidResult(byte[] rawUid, String bucketId) { + public RawUidResponse(byte[] rawUid, String bucketId) { this.rawUid = rawUid; this.bucketId = bucketId; } + // historically Optout is known as Logout public boolean isOptedOut() { return this.equals(OptoutIdentity) || this.bucketId == null || this.bucketId.isEmpty(); } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index cac4f970e..64b8bcedd 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -6,7 +6,7 @@ import java.time.Instant; import java.util.Arrays; -// Contains a first level salted computed from Hashed DII (email/phone number) and applying salt to it +// Contains a first level salted hash computed from Hashed DII (email/phone number) public class FirstLevelHashIdentity extends UserIdentity { public final byte[] firstLevelHash; diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java index 25baaf308..dad862f21 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java @@ -5,9 +5,9 @@ import java.time.Instant; -// Contains a hash computed from a raw email/phone number DII input or the hash is provided by the UID Participant -// directly -public class HashedDiiIdentity extends UserIdentity{ +// Contains a hash DII, +// This hash can either be computed from a raw email/phone number DII input or provided by the UID Participant directly +public class HashedDiiIdentity extends UserIdentity { public final byte[] hashedDii; public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 89ac7cc1e..7accc0ac5 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -217,7 +217,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { final int siteId = b3.getInt(0); final int length = b3.getInt(4); - final byte[] getRawUid = EncodingUtils.fromBase64(b3.slice(8, 8 + length).getBytes()); + final byte[] rawUid = EncodingUtils.fromBase64(b3.slice(8, 8 + length).getBytes()); final int privacyBits = b3.getInt(8 + length); final long establishedMillis = b3.getLong(8 + length + 4); @@ -228,7 +228,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new SourcePublisher(siteId, siteKeyId, 0), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, getRawUid, privacyBits, + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, privacyBits, Instant.ofEpochMilli(establishedMillis), null) ); @@ -253,11 +253,11 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes final int privacyBits = sitePayload.getInt(16); final Instant establishedAt = Instant.ofEpochMilli(sitePayload.getLong(20)); final Instant refreshedAt = Instant.ofEpochMilli(sitePayload.getLong(28)); - final byte[] id = sitePayload.slice(36, sitePayload.length()).getBytes(); - final IdentityScope identityScope = id.length == 32 ? IdentityScope.UID2 : decodeIdentityScopeV3(id[0]); - final IdentityType identityType = id.length == 32 ? IdentityType.Email : decodeIdentityTypeV3(id[0]); + final byte[] rawUid = sitePayload.slice(36, sitePayload.length()).getBytes(); + final IdentityScope identityScope = rawUid.length == 32 ? IdentityScope.UID2 : decodeIdentityScopeV3(rawUid[0]); + final IdentityType identityType = rawUid.length == 32 ? IdentityType.Email : decodeIdentityTypeV3(rawUid[0]); - if (id.length > 32) + if (rawUid.length > 32) { if (identityScope != decodeIdentityScopeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed decoding advertisingTokenV3: Identity scope mismatch"); @@ -269,7 +269,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes return new AdvertisingTokenInput( tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new RawUidIdentity(identityScope, identityType, id, privacyBits, establishedAt, refreshedAt) + new RawUidIdentity(identityScope, identityType, rawUid, privacyBits, establishedAt, refreshedAt) ); } @@ -371,7 +371,6 @@ private String generateBase64AdvertisingToken(AdvertisingTokenInput advertisingT private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, key); - } private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index c2bf091d2..38624848d 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -16,10 +16,10 @@ public interface IUIDOperatorService { RefreshResponse refreshIdentity(RefreshTokenInput refreshTokenInput); - RawUidResult mapIdentity(MapRequest request); + RawUidResponse mapIdentity(MapRequest request); @Deprecated - RawUidResult map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + RawUidResponse map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index c11b36710..4c397885c 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -160,18 +160,18 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { } @Override - public RawUidResult mapIdentity(MapRequest request) { + public RawUidResponse mapIdentity(MapRequest request) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return RawUidResult.OptoutIdentity; + return RawUidResponse.OptoutIdentity; } else { return generateRawUid(firstLevelHashIdentity, request.asOf); } } @Override - public RawUidResult map(HashedDiiIdentity diiIdentity, Instant asOf) { + public RawUidResponse map(HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); return generateRawUid(firstLevelHashIdentity, asOf); } @@ -194,9 +194,9 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResult rawUidResult = generateRawUid(hashedDiiIdentity, asOf); + final RawUidResponse rawUidResponse = generateRawUid(hashedDiiIdentity, asOf); - this.optOutStore.addEntry(hashedDiiIdentity, rawUidResult.rawUid, r -> { + this.optOutStore.addEntry(hashedDiiIdentity, rawUidResponse.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -208,10 +208,10 @@ public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, H @Override public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResult rawUidResult = generateRawUid(firstLevelHashIdentity, asOf); + final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, asOf); final AdvertisingTokenInput token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(rawUidResult.rawUid, token.rawUidIdentity.rawUid); + return Arrays.equals(rawUidResponse.rawUid, token.rawUidIdentity.rawUid); } @Override @@ -238,10 +238,10 @@ private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private RawUidResult generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { + private RawUidResponse generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); - return new RawUidResult( + return new RawUidResponse( this.identityV3Enabled ? TokenUtils.getRawUidV3(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) @@ -252,10 +252,10 @@ private RawUidResult generateRawUid(FirstLevelHashIdentity firstLevelHashIdentit private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final RawUidResult rawUidResult = generateRawUid(firstLevelHashIdentity, nowUtc); + final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - rawUidResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); + rawUidResponse.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc), diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 1808175a0..e33106949 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -94,7 +94,7 @@ public void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] adver this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath). addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.firstLevelHash)) - .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) + .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) // advertising id aka raw UID .putHeader("Authorization", remoteApiBearerToken) .as(BodyCodec.string()) .send(ar -> { diff --git a/src/main/java/com/uid2/operator/store/IOptOutStore.java b/src/main/java/com/uid2/operator/store/IOptOutStore.java index f767b316e..995939c70 100644 --- a/src/main/java/com/uid2/operator/store/IOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/IOptOutStore.java @@ -9,9 +9,10 @@ public interface IOptOutStore { /** - * Get latest Opt-out record with respect to the UID (hashed identity) + * Get latest opt-out record * - * @param firstLevelHashIdentity@return The timestamp of latest opt-out record. NULL if no record. + * @param firstLevelHashIdentity The first level hash of a DII Hash + * @return The timestamp of latest opt-out record. NULL if no record. */ Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity); diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 404cd92de..58c6703a1 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -474,7 +474,7 @@ else if(emailHash != null) { JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; - if (identityResponse.isOptedout()) { + if (identityResponse.isOptedOut()) { response = ResponseUtil.SuccessNoBodyV2(ResponseStatus.OptOut); responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } @@ -999,7 +999,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.respectOptOut())); - if (t.isOptedout()) { + if (t.isOptedOut()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy final InputUtil.InputVal optOutTokenInput = input.getIdentityType() == IdentityType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) @@ -1241,11 +1241,11 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final RawUidResult rawUidResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); - jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUidResult.rawUid)); - jsonObject.put("bucket_id", rawUidResult.bucketId); + jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUidResponse.rawUid)); + jsonObject.put("bucket_id", rawUidResponse.bucketId); ResponseUtil.Success(rc, jsonObject); } catch (Exception e) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State", e); @@ -1264,8 +1264,8 @@ else if (!input.isValid()) { } else { final Instant now = Instant.now(); - final RawUidResult rawUidResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); - rc.response().end(EncodingUtils.toBase64String(rawUidResult.rawUid)); + final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + rc.response().end(EncodingUtils.toBase64String(rawUidResponse.rawUid)); } } catch (Exception ex) { LOGGER.error("Unexpected error while mapping identity", ex); @@ -1460,13 +1460,13 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal for (int i = 0; i < count; ++i) { final InputUtil.InputVal input = inputList[i]; if (input != null && input.isValid()) { - final RawUidResult rawUidResult = idService.mapIdentity( + final RawUidResponse rawUidResponse = idService.mapIdentity( new MapRequest( input.toHashedDiiIdentity(this.identityScope, 0, now), OptoutCheckPolicy.respectOptOut(), now)); - if (rawUidResult.isOptedOut()) { + if (rawUidResponse.isOptedOut()) { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); resp.put("reason", "optout"); @@ -1475,8 +1475,8 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal } else { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); - resp.put("advertising_id", EncodingUtils.toBase64String(rawUidResult.rawUid)); - resp.put("bucket_id", rawUidResult.bucketId); + resp.put("advertising_id", EncodingUtils.toBase64String(rawUidResponse.rawUid)); + resp.put("bucket_id", rawUidResponse.bucketId); mapped.add(resp); } } else { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 6b2459eca..5196dfaf2 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -211,7 +211,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertFalse(identityResponse.isOptedout()); + assertFalse(identityResponse.isOptedOut()); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenInput)); @@ -227,7 +227,7 @@ public void testTestOptOutKey_RespectOptout() { OptoutCheckPolicy.RespectOptOut ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); - assertTrue(identityResponse.isOptedout()); + assertTrue(identityResponse.isOptedOut()); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); } @@ -327,27 +327,27 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final RawUidResult rawUidResult; - final RawUidResult rawUidResultShouldBeOptOut; + final RawUidResponse rawUidResponse; + final RawUidResponse rawUidResponseShouldBeOptOut; if (scope == IdentityScope.UID2) { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResult = uid2Service.mapIdentity(mapRequestForceMap); + rawUidResponse = uid2Service.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUidResultShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponseShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); } else { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResult = euidService.mapIdentity(mapRequestForceMap); + rawUidResponse = euidService.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUidResultShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponseShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); - assertNotNull(rawUidResultShouldBeOptOut); - assertTrue(rawUidResultShouldBeOptOut.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); + assertNotNull(rawUidResponseShouldBeOptOut); + assertTrue(rawUidResponseShouldBeOptOut.isOptedOut()); } private enum TestIdentityInputType { @@ -434,17 +434,17 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, // identity has no optout record, ensure map still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertTrue(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertTrue(rawUidResponse.isOptedOut()); } @ParameterizedTest @@ -548,17 +548,17 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str // all identities have optout records, ensure refresh-optout identities still map when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); } @ParameterizedTest @@ -619,17 +619,17 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i // all identities have optout records, ensure validate identities still get mapped when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); } @ParameterizedTest @@ -737,18 +737,18 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequest); + rawUidResponse = euidService.mapIdentity(mapRequest); } else { - rawUidResult = uid2Service.mapIdentity(mapRequest); + rawUidResponse = uid2Service.mapIdentity(mapRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); } } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index acf5b8e2e..011b80a2e 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -25,13 +25,13 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUidResult IdentityMapRawThroughput() { + public RawUidResponse IdentityMapRawThroughput() { return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUidResult IdentityMapWithOptOutThroughput() { + public RawUidResponse IdentityMapWithOptOutThroughput() { return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } From ccc639f00502eff02183a0e4271ffca101a97bd4 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 18:00:33 +1100 Subject: [PATCH 24/61] Made UserIdentity abstract first --- .../java/com/uid2/operator/model/userIdentity/UserIdentity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java index 362b89fbe..1391b7d75 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -6,7 +6,7 @@ import java.time.Instant; //base class for all other HshedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields -public class UserIdentity { +public abstract class UserIdentity { public final IdentityScope identityScope; public final IdentityType identityType; From dabff48084f78fc22c9f641ac696ab137ba81e6f Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 18:16:01 +1100 Subject: [PATCH 25/61] Fixed a few id variable to rawUid/firstLevelHash to make it clear. Fixed the UserIdentity/FirstLevelHashIdentity class uses to HashedDiiIdentity instead in IdentityMapBenchmark and TokenEndecBenchmark --- .../uid2/operator/service/EncryptedTokenEncoder.java | 4 ++-- .../java/com/uid2/operator/service/TokenUtils.java | 8 ++++---- .../com/uid2/operator/benchmark/BenchmarkCommon.java | 8 ++++---- .../operator/benchmark/IdentityMapBenchmark.java | 8 ++++---- .../uid2/operator/benchmark/TokenEndecBenchmark.java | 12 ++++++------ 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 7accc0ac5..c5a405f69 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -149,7 +149,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { final Instant establishedAt = Instant.ofEpochMilli(b2.getLong(49)); final IdentityScope identityScope = decodeIdentityScopeV3(b2.getByte(57)); final IdentityType identityType = decodeIdentityTypeV3(b2.getByte(57)); - final byte[] id = b2.getBytes(58, 90); + final byte[] firstLevelHash = b2.getBytes(58, 90); if (identityScope != decodeIdentityScopeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed to decode refreshTokenV3: Identity scope mismatch"); @@ -160,7 +160,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { return new RefreshTokenInput( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new FirstLevelHashIdentity(identityScope, identityType, id, privacyBits, establishedAt, null)); + new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, privacyBits, establishedAt, null)); } @Override diff --git a/src/main/java/com/uid2/operator/service/TokenUtils.java b/src/main/java/com/uid2/operator/service/TokenUtils.java index b42ac3c5f..ef532e578 100644 --- a/src/main/java/com/uid2/operator/service/TokenUtils.java +++ b/src/main/java/com/uid2/operator/service/TokenUtils.java @@ -41,10 +41,10 @@ public static byte[] getRawUidV2FromIdentityHash(String identityString, String f public static byte[] getRawUidV3(IdentityScope scope, IdentityType type, byte[] firstLevelHash, String rotatingSalt) { final byte[] sha = EncodingUtils.getSha256Bytes(EncodingUtils.toBase64String(firstLevelHash), rotatingSalt); - final byte[] id = new byte[33]; - id[0] = (byte)(encodeIdentityScope(scope) | encodeIdentityType(type)); - System.arraycopy(sha, 0, id, 1, 32); - return id; + final byte[] rawUid = new byte[33]; + rawUid[0] = (byte)(encodeIdentityScope(scope) | encodeIdentityType(type)); + System.arraycopy(sha, 0, rawUid, 1, 32); + return rawUid; } public static byte[] getRawUidV3FromIdentity(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 00c2e2cac..1c25faecd 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -150,12 +150,12 @@ static ICloudStorage make1mOptOutEntryStorage(String salt, List out_gene return storage; } - static HashedDiiIdentity[] createUserIdentities() { + static HashedDiiIdentity[] createHashedDiiIdentities() { HashedDiiIdentity[] arr = new HashedDiiIdentity[65536]; for (int i = 0; i < 65536; i++) { - final byte[] id = new byte[33]; - new Random().nextBytes(id); - arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, id, 0, + final byte[] diiHash = new byte[33]; + new Random().nextBytes(diiHash); + arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, diiHash, 0, Instant.now().minusSeconds(120), Instant.now().minusSeconds(60)); } return arr; diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 011b80a2e..880875fc0 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -11,13 +11,13 @@ public class IdentityMapBenchmark { private static final IUIDOperatorService uidService; - private static final HashedDiiIdentity[] firstLevelHashIdentities; + private static final HashedDiiIdentity[] hashedDiiIdentities; private static int idx = 0; static { try { uidService = BenchmarkCommon.createUidOperatorService(); - firstLevelHashIdentities = BenchmarkCommon.createUserIdentities(); + hashedDiiIdentities = BenchmarkCommon.createHashedDiiIdentities(); } catch (Exception e) { throw new RuntimeException(e); } @@ -26,12 +26,12 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) public RawUidResponse IdentityMapRawThroughput() { - return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); + return uidService.map(hashedDiiIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) public RawUidResponse IdentityMapWithOptOutThroughput() { - return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); + return uidService.mapIdentity(new MapRequest(hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 0e5f62b89..e907f638c 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -14,7 +14,7 @@ public class TokenEndecBenchmark { private static final IUIDOperatorService uidService; - private static final HashedDiiIdentity[] userIdentities; + private static final HashedDiiIdentity[] hashedDiiIdentities; private static final SourcePublisher publisher; private static final EncryptedTokenEncoder encoder; private static final IdentityResponse[] generatedTokens; @@ -23,11 +23,11 @@ public class TokenEndecBenchmark { static { try { uidService = BenchmarkCommon.createUidOperatorService(); - userIdentities = BenchmarkCommon.createUserIdentities(); + hashedDiiIdentities = BenchmarkCommon.createHashedDiiIdentities(); publisher = BenchmarkCommon.createSourcePublisher(); encoder = BenchmarkCommon.createTokenEncoder(); generatedTokens = createAdvertisingTokens(); - if (generatedTokens.length < 65536 || userIdentities.length < 65536) { + if (generatedTokens.length < 65536 || hashedDiiIdentities.length < 65536) { throw new IllegalStateException("must create more than 65535 test candidates."); } } catch (Exception e) { @@ -37,11 +37,11 @@ public class TokenEndecBenchmark { static IdentityResponse[] createAdvertisingTokens() { List tokens = new ArrayList<>(); - for (int i = 0; i < userIdentities.length; i++) { + for (int i = 0; i < hashedDiiIdentities.length; i++) { tokens.add( uidService.generateIdentity(new IdentityRequest( publisher, - userIdentities[i], + hashedDiiIdentities[i], OptoutCheckPolicy.DoNotRespect))); } return tokens.toArray(new IdentityResponse[tokens.size()]); @@ -52,7 +52,7 @@ static IdentityResponse[] createAdvertisingTokens() { public IdentityResponse TokenGenerationBenchmark() { return uidService.generateIdentity(new IdentityRequest( publisher, - userIdentities[(idx++) & 65535], + hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.DoNotRespect)); } From d8eda031be75c0bc7fbe98a29a7cddfbcc74cd71 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 16:57:13 +1100 Subject: [PATCH 26/61] Fixed UserIdentity member variables as final and added constructor --- .../userIdentity/FirstLevelHashIdentity.java | 6 +----- .../model/userIdentity/HashedDiiIdentity.java | 6 +----- .../model/userIdentity/RawUidIdentity.java | 6 +----- .../model/userIdentity/UserIdentity.java | 21 +++++++++++-------- .../uid2/operator/UIDOperatorServiceTest.java | 6 +++--- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index 4286d2a0c..cac4f970e 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -12,12 +12,8 @@ public class FirstLevelHashIdentity extends UserIdentity { public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, int privacyBits, Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; + super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); this.firstLevelHash = firstLevelHash; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; } public boolean matches(FirstLevelHashIdentity that) { diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java index c5b162315..25baaf308 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java @@ -12,11 +12,7 @@ public class HashedDiiIdentity extends UserIdentity{ public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; + super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); this.hashedDii = hashedDii; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java index 7af6edf5b..4e15c6ff0 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java @@ -12,12 +12,8 @@ public class RawUidIdentity extends UserIdentity { public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid, int privacyBits, Instant establishedAt, Instant refreshedAt) { - this.identityScope = identityScope; - this.identityType = identityType; + super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); this.rawUid = rawUid; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; } public boolean matches(RawUidIdentity that) { diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java index 0e16cc4ed..362b89fbe 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -8,14 +8,17 @@ //base class for all other HshedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields public class UserIdentity { - public IdentityScope identityScope; - public IdentityType identityType; - public int privacyBits; - public Instant establishedAt; - public Instant refreshedAt; + public final IdentityScope identityScope; + public final IdentityType identityType; + public final int privacyBits; + public final Instant establishedAt; + public final Instant refreshedAt; - public IdentityScope GetIdentityScope() { return identityScope; } - public IdentityType GetIdentityType() { return identityType; } - public Instant GetEstablishedAt() { return establishedAt; }; - public Instant GetIRefreshedAt() { return refreshedAt; } + public UserIdentity(IdentityScope identityScope, IdentityType identityType, int privacyBits, Instant establishedAt, Instant refreshedAt) { + this.identityScope = identityScope; + this.identityType = identityType; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; + this.refreshedAt = refreshedAt; + } } diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 7b01b7180..6b2459eca 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -142,9 +142,9 @@ private AdvertisingTokenInput validateAndGetToken(EncryptedTokenEncoder tokenEnc private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expctedValues, UserIdentity actualValues) { - assertEquals(expctedValues.GetIdentityScope(), actualValues.GetIdentityScope()); - assertEquals(expctedValues.GetIdentityType(), actualValues.GetIdentityType()); - assertEquals(expctedValues.GetEstablishedAt(), actualValues.GetEstablishedAt()); + assertEquals(expctedValues.identityScope, actualValues.identityScope); + assertEquals(expctedValues.identityType, actualValues.identityType); + assertEquals(expctedValues.establishedAt, actualValues.establishedAt); } @ParameterizedTest From e74e8da0cacec02af2ecb1a340af23ffbecb6221 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 17:45:46 +1100 Subject: [PATCH 27/61] 1. Addressed code review feedbacks 2. Renamed RawUidResult to RawUidResponse 3. rename some id variable to rawUid to make it clearer 4. more comments --- .../java/com/uid2/operator/IdentityConst.java | 7 +- .../uid2/operator/model/IdentityResponse.java | 4 +- ...{RawUidResult.java => RawUidResponse.java} | 7 +- .../userIdentity/FirstLevelHashIdentity.java | 2 +- .../model/userIdentity/HashedDiiIdentity.java | 6 +- .../service/EncryptedTokenEncoder.java | 15 ++--- .../operator/service/IUIDOperatorService.java | 4 +- .../operator/service/UIDOperatorService.java | 22 +++---- .../operator/store/CloudSyncOptOutStore.java | 2 +- .../com/uid2/operator/store/IOptOutStore.java | 5 +- .../operator/vertx/UIDOperatorVerticle.java | 22 +++---- .../uid2/operator/UIDOperatorServiceTest.java | 64 +++++++++---------- .../benchmark/IdentityMapBenchmark.java | 4 +- 13 files changed, 83 insertions(+), 81 deletions(-) rename src/main/java/com/uid2/operator/model/{RawUidResult.java => RawUidResponse.java} (66%) diff --git a/src/main/java/com/uid2/operator/IdentityConst.java b/src/main/java/com/uid2/operator/IdentityConst.java index 0263d4e76..9362ade6e 100644 --- a/src/main/java/com/uid2/operator/IdentityConst.java +++ b/src/main/java/com/uid2/operator/IdentityConst.java @@ -3,9 +3,11 @@ import com.uid2.operator.service.EncodingUtils; public class IdentityConst { + // DIIs for generating optout tokens for legacy participants - to be deprecated public static final String OptOutTokenIdentityForEmail = "optout@unifiedid.com"; public static final String OptOutTokenIdentityForPhone = "+00000000001"; + // DIIs for for testing with token/validate endpoint, see https://unifiedid.com/docs/endpoints/post-token-validate public static final String ValidateIdentityForEmail = "validate@example.com"; public static final String ValidateIdentityForPhone = "+12345678901"; public static final byte[] ValidateIdentityForEmailHash = EncodingUtils.getSha256Bytes(IdentityConst.ValidateIdentityForEmail); @@ -15,9 +17,8 @@ public class IdentityConst { public static final String OptOutIdentityForEmail = "optout@example.com"; public static final String OptOutIdentityForPhone = "+00000000000"; + // DIIs to use when you want to generate a UID token but when doing refresh token, you want to always get an optout response + // to test the optout handling workflow public static final String RefreshOptOutIdentityForEmail = "refresh-optout@example.com"; public static final String RefreshOptOutIdentityForPhone = "+00000000002"; - - - } diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 6f802821b..fc9182650 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -5,7 +5,7 @@ import java.time.Instant; // this defines all the fields for the response of the /token/generate and /client/generate endpoints before they are -// json-ised +// jsonified public class IdentityResponse { public static IdentityResponse OptOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); private final String advertisingToken; @@ -49,7 +49,7 @@ public Instant getRefreshFrom() { return refreshFrom; } - public boolean isOptedout() { + public boolean isOptedOut() { return advertisingToken == null || advertisingToken.isEmpty(); } } diff --git a/src/main/java/com/uid2/operator/model/RawUidResult.java b/src/main/java/com/uid2/operator/model/RawUidResponse.java similarity index 66% rename from src/main/java/com/uid2/operator/model/RawUidResult.java rename to src/main/java/com/uid2/operator/model/RawUidResponse.java index 5348700e0..249bef4c5 100644 --- a/src/main/java/com/uid2/operator/model/RawUidResult.java +++ b/src/main/java/com/uid2/operator/model/RawUidResponse.java @@ -1,17 +1,18 @@ package com.uid2.operator.model; // Contains the computed raw UID and its bucket ID from identity/map request -public class RawUidResult { - public static RawUidResult OptoutIdentity = new RawUidResult(new byte[33], ""); +public class RawUidResponse { + public static RawUidResponse OptoutIdentity = new RawUidResponse(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) public final byte[] rawUid; public final String bucketId; - public RawUidResult(byte[] rawUid, String bucketId) { + public RawUidResponse(byte[] rawUid, String bucketId) { this.rawUid = rawUid; this.bucketId = bucketId; } + // historically Optout is known as Logout public boolean isOptedOut() { return this.equals(OptoutIdentity) || this.bucketId == null || this.bucketId.isEmpty(); } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index cac4f970e..64b8bcedd 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -6,7 +6,7 @@ import java.time.Instant; import java.util.Arrays; -// Contains a first level salted computed from Hashed DII (email/phone number) and applying salt to it +// Contains a first level salted hash computed from Hashed DII (email/phone number) public class FirstLevelHashIdentity extends UserIdentity { public final byte[] firstLevelHash; diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java index 25baaf308..dad862f21 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java @@ -5,9 +5,9 @@ import java.time.Instant; -// Contains a hash computed from a raw email/phone number DII input or the hash is provided by the UID Participant -// directly -public class HashedDiiIdentity extends UserIdentity{ +// Contains a hash DII, +// This hash can either be computed from a raw email/phone number DII input or provided by the UID Participant directly +public class HashedDiiIdentity extends UserIdentity { public final byte[] hashedDii; public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 77a545c62..4985bb1cd 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -217,7 +217,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { final int siteId = b3.getInt(0); final int length = b3.getInt(4); - final byte[] getRawUid = EncodingUtils.fromBase64(b3.slice(8, 8 + length).getBytes()); + final byte[] rawUid = EncodingUtils.fromBase64(b3.slice(8, 8 + length).getBytes()); final int privacyBits = b3.getInt(8 + length); final long establishedMillis = b3.getLong(8 + length + 4); @@ -228,7 +228,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new SourcePublisher(siteId, siteKeyId, 0), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, getRawUid, privacyBits, + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, privacyBits, Instant.ofEpochMilli(establishedMillis), null) ); @@ -253,11 +253,11 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes final int privacyBits = sitePayload.getInt(16); final Instant establishedAt = Instant.ofEpochMilli(sitePayload.getLong(20)); final Instant refreshedAt = Instant.ofEpochMilli(sitePayload.getLong(28)); - final byte[] id = sitePayload.slice(36, sitePayload.length()).getBytes(); - final IdentityScope identityScope = id.length == 32 ? IdentityScope.UID2 : decodeIdentityScopeV3(id[0]); - final IdentityType identityType = id.length == 32 ? IdentityType.Email : decodeIdentityTypeV3(id[0]); + final byte[] rawUid = sitePayload.slice(36, sitePayload.length()).getBytes(); + final IdentityScope identityScope = rawUid.length == 32 ? IdentityScope.UID2 : decodeIdentityScopeV3(rawUid[0]); + final IdentityType identityType = rawUid.length == 32 ? IdentityType.Email : decodeIdentityTypeV3(rawUid[0]); - if (id.length > 32) + if (rawUid.length > 32) { if (identityScope != decodeIdentityScopeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed decoding advertisingTokenV3: Identity scope mismatch"); @@ -269,7 +269,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes return new AdvertisingTokenInput( tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new RawUidIdentity(identityScope, identityType, id, privacyBits, establishedAt, refreshedAt) + new RawUidIdentity(identityScope, identityType, rawUid, privacyBits, establishedAt, refreshedAt) ); } @@ -360,7 +360,6 @@ public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenInput adverti private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, key); - } private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index c2bf091d2..38624848d 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -16,10 +16,10 @@ public interface IUIDOperatorService { RefreshResponse refreshIdentity(RefreshTokenInput refreshTokenInput); - RawUidResult mapIdentity(MapRequest request); + RawUidResponse mapIdentity(MapRequest request); @Deprecated - RawUidResult map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + RawUidResponse map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 6abc1439c..c460ba8c1 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -160,18 +160,18 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { } @Override - public RawUidResult mapIdentity(MapRequest request) { + public RawUidResponse mapIdentity(MapRequest request) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return RawUidResult.OptoutIdentity; + return RawUidResponse.OptoutIdentity; } else { return generateRawUid(firstLevelHashIdentity, request.asOf); } } @Override - public RawUidResult map(HashedDiiIdentity diiIdentity, Instant asOf) { + public RawUidResponse map(HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); return generateRawUid(firstLevelHashIdentity, asOf); } @@ -194,9 +194,9 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResult rawUidResult = generateRawUid(hashedDiiIdentity, asOf); + final RawUidResponse rawUidResponse = generateRawUid(hashedDiiIdentity, asOf); - this.optOutStore.addEntry(hashedDiiIdentity, rawUidResult.rawUid, r -> { + this.optOutStore.addEntry(hashedDiiIdentity, rawUidResponse.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -208,10 +208,10 @@ public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, H @Override public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResult rawUidResult = generateRawUid(firstLevelHashIdentity, asOf); + final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, asOf); final AdvertisingTokenInput token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(rawUidResult.rawUid, token.rawUidIdentity.rawUid); + return Arrays.equals(rawUidResponse.rawUid, token.rawUidIdentity.rawUid); } @Override @@ -238,10 +238,10 @@ private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private RawUidResult generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { + private RawUidResponse generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); - return new RawUidResult( + return new RawUidResponse( this.identityV3Enabled ? TokenUtils.getRawUidV3(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) @@ -252,10 +252,10 @@ private RawUidResult generateRawUid(FirstLevelHashIdentity firstLevelHashIdentit private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final RawUidResult rawUidResult = generateRawUid(firstLevelHashIdentity, nowUtc); + final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - rawUidResult.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); + rawUidResponse.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc), diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 1808175a0..e33106949 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -94,7 +94,7 @@ public void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] adver this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath). addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.firstLevelHash)) - .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) + .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) // advertising id aka raw UID .putHeader("Authorization", remoteApiBearerToken) .as(BodyCodec.string()) .send(ar -> { diff --git a/src/main/java/com/uid2/operator/store/IOptOutStore.java b/src/main/java/com/uid2/operator/store/IOptOutStore.java index f767b316e..995939c70 100644 --- a/src/main/java/com/uid2/operator/store/IOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/IOptOutStore.java @@ -9,9 +9,10 @@ public interface IOptOutStore { /** - * Get latest Opt-out record with respect to the UID (hashed identity) + * Get latest opt-out record * - * @param firstLevelHashIdentity@return The timestamp of latest opt-out record. NULL if no record. + * @param firstLevelHashIdentity The first level hash of a DII Hash + * @return The timestamp of latest opt-out record. NULL if no record. */ Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity); diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index de9cb3c8a..6a012222f 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -474,7 +474,7 @@ else if(emailHash != null) { JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; - if (identityResponse.isOptedout()) { + if (identityResponse.isOptedOut()) { response = ResponseUtil.SuccessNoBodyV2(ResponseStatus.OptOut); responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } @@ -999,7 +999,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), OptoutCheckPolicy.respectOptOut())); - if (t.isOptedout()) { + if (t.isOptedOut()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy final InputUtil.InputVal optOutTokenInput = input.getIdentityType() == IdentityType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) @@ -1241,11 +1241,11 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final RawUidResult rawUidResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); - jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUidResult.rawUid)); - jsonObject.put("bucket_id", rawUidResult.bucketId); + jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUidResponse.rawUid)); + jsonObject.put("bucket_id", rawUidResponse.bucketId); ResponseUtil.Success(rc, jsonObject); } catch (Exception e) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State", e); @@ -1264,8 +1264,8 @@ else if (!input.isValid()) { } else { final Instant now = Instant.now(); - final RawUidResult rawUidResult = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); - rc.response().end(EncodingUtils.toBase64String(rawUidResult.rawUid)); + final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + rc.response().end(EncodingUtils.toBase64String(rawUidResponse.rawUid)); } } catch (Exception ex) { LOGGER.error("Unexpected error while mapping identity", ex); @@ -1460,13 +1460,13 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal for (int i = 0; i < count; ++i) { final InputUtil.InputVal input = inputList[i]; if (input != null && input.isValid()) { - final RawUidResult rawUidResult = idService.mapIdentity( + final RawUidResponse rawUidResponse = idService.mapIdentity( new MapRequest( input.toHashedDiiIdentity(this.identityScope, 0, now), OptoutCheckPolicy.respectOptOut(), now)); - if (rawUidResult.isOptedOut()) { + if (rawUidResponse.isOptedOut()) { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); resp.put("reason", "optout"); @@ -1475,8 +1475,8 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal } else { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); - resp.put("advertising_id", EncodingUtils.toBase64String(rawUidResult.rawUid)); - resp.put("bucket_id", rawUidResult.bucketId); + resp.put("advertising_id", EncodingUtils.toBase64String(rawUidResponse.rawUid)); + resp.put("bucket_id", rawUidResponse.bucketId); mapped.add(resp); } } else { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 6b2459eca..5196dfaf2 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -211,7 +211,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertFalse(identityResponse.isOptedout()); + assertFalse(identityResponse.isOptedOut()); final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenInput)); @@ -227,7 +227,7 @@ public void testTestOptOutKey_RespectOptout() { OptoutCheckPolicy.RespectOptOut ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); - assertTrue(identityResponse.isOptedout()); + assertTrue(identityResponse.isOptedOut()); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); } @@ -327,27 +327,27 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final RawUidResult rawUidResult; - final RawUidResult rawUidResultShouldBeOptOut; + final RawUidResponse rawUidResponse; + final RawUidResponse rawUidResponseShouldBeOptOut; if (scope == IdentityScope.UID2) { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResult = uid2Service.mapIdentity(mapRequestForceMap); + rawUidResponse = uid2Service.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUidResultShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponseShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); } else { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResult = euidService.mapIdentity(mapRequestForceMap); + rawUidResponse = euidService.mapIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUidResultShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponseShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); - assertNotNull(rawUidResultShouldBeOptOut); - assertTrue(rawUidResultShouldBeOptOut.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); + assertNotNull(rawUidResponseShouldBeOptOut); + assertTrue(rawUidResponseShouldBeOptOut.isOptedOut()); } private enum TestIdentityInputType { @@ -434,17 +434,17 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, // identity has no optout record, ensure map still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertTrue(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertTrue(rawUidResponse.isOptedOut()); } @ParameterizedTest @@ -548,17 +548,17 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str // all identities have optout records, ensure refresh-optout identities still map when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); } @ParameterizedTest @@ -619,17 +619,17 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i // all identities have optout records, ensure validate identities still get mapped when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); } else { - rawUidResult = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); } @ParameterizedTest @@ -737,18 +737,18 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); - final RawUidResult rawUidResult; + final RawUidResponse rawUidResponse; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - rawUidResult = euidService.mapIdentity(mapRequest); + rawUidResponse = euidService.mapIdentity(mapRequest); } else { - rawUidResult = uid2Service.mapIdentity(mapRequest); + rawUidResponse = uid2Service.mapIdentity(mapRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(rawUidResult); - assertFalse(rawUidResult.isOptedOut()); + assertNotNull(rawUidResponse); + assertFalse(rawUidResponse.isOptedOut()); } } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index acf5b8e2e..011b80a2e 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -25,13 +25,13 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUidResult IdentityMapRawThroughput() { + public RawUidResponse IdentityMapRawThroughput() { return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUidResult IdentityMapWithOptOutThroughput() { + public RawUidResponse IdentityMapWithOptOutThroughput() { return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } From 7f4ebf5ee422d1ba6e338c6f3e870f1b9886be1f Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 18:00:33 +1100 Subject: [PATCH 28/61] Made UserIdentity abstract first --- .../java/com/uid2/operator/model/userIdentity/UserIdentity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java index 362b89fbe..1391b7d75 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -6,7 +6,7 @@ import java.time.Instant; //base class for all other HshedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields -public class UserIdentity { +public abstract class UserIdentity { public final IdentityScope identityScope; public final IdentityType identityType; From 72f7be4c39a3b313162f2cb04f8fdcb426cfc9df Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Tue, 15 Oct 2024 18:16:01 +1100 Subject: [PATCH 29/61] Fixed a few id variable to rawUid/firstLevelHash to make it clear. Fixed the UserIdentity/FirstLevelHashIdentity class uses to HashedDiiIdentity instead in IdentityMapBenchmark and TokenEndecBenchmark --- .../uid2/operator/service/EncryptedTokenEncoder.java | 4 ++-- .../java/com/uid2/operator/service/TokenUtils.java | 8 ++++---- .../com/uid2/operator/benchmark/BenchmarkCommon.java | 8 ++++---- .../operator/benchmark/IdentityMapBenchmark.java | 8 ++++---- .../uid2/operator/benchmark/TokenEndecBenchmark.java | 12 ++++++------ 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 4985bb1cd..e60240a66 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -149,7 +149,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { final Instant establishedAt = Instant.ofEpochMilli(b2.getLong(49)); final IdentityScope identityScope = decodeIdentityScopeV3(b2.getByte(57)); final IdentityType identityType = decodeIdentityTypeV3(b2.getByte(57)); - final byte[] id = b2.getBytes(58, 90); + final byte[] firstLevelHash = b2.getBytes(58, 90); if (identityScope != decodeIdentityScopeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed to decode refreshTokenV3: Identity scope mismatch"); @@ -160,7 +160,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { return new RefreshTokenInput( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new FirstLevelHashIdentity(identityScope, identityType, id, privacyBits, establishedAt, null)); + new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, privacyBits, establishedAt, null)); } @Override diff --git a/src/main/java/com/uid2/operator/service/TokenUtils.java b/src/main/java/com/uid2/operator/service/TokenUtils.java index b42ac3c5f..ef532e578 100644 --- a/src/main/java/com/uid2/operator/service/TokenUtils.java +++ b/src/main/java/com/uid2/operator/service/TokenUtils.java @@ -41,10 +41,10 @@ public static byte[] getRawUidV2FromIdentityHash(String identityString, String f public static byte[] getRawUidV3(IdentityScope scope, IdentityType type, byte[] firstLevelHash, String rotatingSalt) { final byte[] sha = EncodingUtils.getSha256Bytes(EncodingUtils.toBase64String(firstLevelHash), rotatingSalt); - final byte[] id = new byte[33]; - id[0] = (byte)(encodeIdentityScope(scope) | encodeIdentityType(type)); - System.arraycopy(sha, 0, id, 1, 32); - return id; + final byte[] rawUid = new byte[33]; + rawUid[0] = (byte)(encodeIdentityScope(scope) | encodeIdentityType(type)); + System.arraycopy(sha, 0, rawUid, 1, 32); + return rawUid; } public static byte[] getRawUidV3FromIdentity(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 00c2e2cac..1c25faecd 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -150,12 +150,12 @@ static ICloudStorage make1mOptOutEntryStorage(String salt, List out_gene return storage; } - static HashedDiiIdentity[] createUserIdentities() { + static HashedDiiIdentity[] createHashedDiiIdentities() { HashedDiiIdentity[] arr = new HashedDiiIdentity[65536]; for (int i = 0; i < 65536; i++) { - final byte[] id = new byte[33]; - new Random().nextBytes(id); - arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, id, 0, + final byte[] diiHash = new byte[33]; + new Random().nextBytes(diiHash); + arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, diiHash, 0, Instant.now().minusSeconds(120), Instant.now().minusSeconds(60)); } return arr; diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 011b80a2e..880875fc0 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -11,13 +11,13 @@ public class IdentityMapBenchmark { private static final IUIDOperatorService uidService; - private static final HashedDiiIdentity[] firstLevelHashIdentities; + private static final HashedDiiIdentity[] hashedDiiIdentities; private static int idx = 0; static { try { uidService = BenchmarkCommon.createUidOperatorService(); - firstLevelHashIdentities = BenchmarkCommon.createUserIdentities(); + hashedDiiIdentities = BenchmarkCommon.createHashedDiiIdentities(); } catch (Exception e) { throw new RuntimeException(e); } @@ -26,12 +26,12 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) public RawUidResponse IdentityMapRawThroughput() { - return uidService.map(firstLevelHashIdentities[(idx++) & 65535], Instant.now()); + return uidService.map(hashedDiiIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) public RawUidResponse IdentityMapWithOptOutThroughput() { - return uidService.mapIdentity(new MapRequest(firstLevelHashIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); + return uidService.mapIdentity(new MapRequest(hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 0e5f62b89..e907f638c 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -14,7 +14,7 @@ public class TokenEndecBenchmark { private static final IUIDOperatorService uidService; - private static final HashedDiiIdentity[] userIdentities; + private static final HashedDiiIdentity[] hashedDiiIdentities; private static final SourcePublisher publisher; private static final EncryptedTokenEncoder encoder; private static final IdentityResponse[] generatedTokens; @@ -23,11 +23,11 @@ public class TokenEndecBenchmark { static { try { uidService = BenchmarkCommon.createUidOperatorService(); - userIdentities = BenchmarkCommon.createUserIdentities(); + hashedDiiIdentities = BenchmarkCommon.createHashedDiiIdentities(); publisher = BenchmarkCommon.createSourcePublisher(); encoder = BenchmarkCommon.createTokenEncoder(); generatedTokens = createAdvertisingTokens(); - if (generatedTokens.length < 65536 || userIdentities.length < 65536) { + if (generatedTokens.length < 65536 || hashedDiiIdentities.length < 65536) { throw new IllegalStateException("must create more than 65535 test candidates."); } } catch (Exception e) { @@ -37,11 +37,11 @@ public class TokenEndecBenchmark { static IdentityResponse[] createAdvertisingTokens() { List tokens = new ArrayList<>(); - for (int i = 0; i < userIdentities.length; i++) { + for (int i = 0; i < hashedDiiIdentities.length; i++) { tokens.add( uidService.generateIdentity(new IdentityRequest( publisher, - userIdentities[i], + hashedDiiIdentities[i], OptoutCheckPolicy.DoNotRespect))); } return tokens.toArray(new IdentityResponse[tokens.size()]); @@ -52,7 +52,7 @@ static IdentityResponse[] createAdvertisingTokens() { public IdentityResponse TokenGenerationBenchmark() { return uidService.generateIdentity(new IdentityRequest( publisher, - userIdentities[(idx++) & 65535], + hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.DoNotRespect)); } From 21f0c6035109772ac2197bcb4453eabb4f8e22c6 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 16 Oct 2024 13:57:07 +1100 Subject: [PATCH 30/61] 1. Refactored EncryptedTokenEncoder to rename encode/encodev2/encodev3 methods to encodeIntoAdvertisingToken or encodeIntoRefreshToken to make it clear what we are encoding into --- .../service/EncryptedTokenEncoder.java | 39 +++++++++++-------- .../com/uid2/operator/TokenEncodingTest.java | 6 +-- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index e60240a66..1a74a794a 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -24,16 +24,16 @@ public EncryptedTokenEncoder(KeyManager keyManager) { this.keyManager = keyManager; } - public byte[] encode(AdvertisingTokenInput t, Instant asOf) { + public byte[] encodeIntoAdvertisingToken(AdvertisingTokenInput t, Instant asOf) { final KeysetKey masterKey = this.keyManager.getMasterKey(asOf); final KeysetKey siteEncryptionKey = this.keyManager.getActiveKeyBySiteIdWithFallback(t.sourcePublisher.siteId, Data.AdvertisingTokenSiteId, asOf); return t.version == TokenVersion.V2 - ? encodeV2(t, masterKey, siteEncryptionKey) - : encodeV3(t, masterKey, siteEncryptionKey); //TokenVersion.V4 also calls encodeV3() since the byte array is identical between V3 and V4 + ? encodeIntoAdvertisingTokenV2(t, masterKey, siteEncryptionKey) + : encodeIntoAdvertisingTokenV3(t, masterKey, siteEncryptionKey); //TokenVersion.V4 also calls encodeV3() since the byte array is identical between V3 and V4 } - private byte[] encodeV2(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { + private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer b = Buffer.buffer(); b.appendByte((byte) t.version.rawVersion); @@ -50,7 +50,7 @@ private byte[] encodeV2(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey return b.getBytes(); } - private byte[] encodeV3(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { + private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer sitePayload = Buffer.buffer(69); encodePublisherRequesterV3(sitePayload, t.sourcePublisher); sitePayload.appendInt(t.rawUidIdentity.privacyBits); @@ -281,22 +281,22 @@ private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVer .register(Metrics.globalRegistry).increment(); } - public byte[] encode(RefreshTokenInput t, Instant asOf) { + public byte[] encodeIntoRefreshToken(RefreshTokenInput t, Instant asOf) { final KeysetKey serviceKey = this.keyManager.getRefreshKey(asOf); switch (t.version) { case V2: recordRefreshTokenVersionCount(String.valueOf(t.sourcePublisher.siteId), TokenVersion.V2); - return encodeV2(t, serviceKey); + return encodeIntoRefreshTokenV2(t, serviceKey); case V3: recordRefreshTokenVersionCount(String.valueOf(t.sourcePublisher.siteId), TokenVersion.V3); - return encodeV3(t, serviceKey); + return encodeIntoRefreshTokenV3(t, serviceKey); default: throw new ClientInputValidationException("RefreshToken version " + t.version + " not supported"); } } - public byte[] encodeV2(RefreshTokenInput t, KeysetKey serviceKey) { + public byte[] encodeIntoRefreshTokenV2(RefreshTokenInput t, KeysetKey serviceKey) { final Buffer b = Buffer.buffer(); b.appendByte((byte) t.version.rawVersion); b.appendLong(t.createdAt.toEpochMilli()); @@ -309,7 +309,7 @@ public byte[] encodeV2(RefreshTokenInput t, KeysetKey serviceKey) { return b.getBytes(); } - public byte[] encodeV3(RefreshTokenInput t, KeysetKey serviceKey) { + public byte[] encodeIntoRefreshTokenV3(RefreshTokenInput t, KeysetKey serviceKey) { final Buffer refreshPayload = Buffer.buffer(90); refreshPayload.appendLong(t.expiresAt.toEpochMilli()); refreshPayload.appendLong(t.createdAt.toEpochMilli()); @@ -343,20 +343,27 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi @Override public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { - - final byte[] advertisingTokenBytes = encode(advertisingTokenInput, asOf); - final String base64AdvertisingToken = bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); - + final String advertisingToken = generateAdvertisingTokenString(advertisingTokenInput, asOf); + final String refreshToken = generateRefreshTokenString(refreshTokenInput, asOf); return new IdentityResponse( - base64AdvertisingToken, + advertisingToken, advertisingTokenInput.version, - EncodingUtils.toBase64String(encode(refreshTokenInput, asOf)), + refreshToken, advertisingTokenInput.expiresAt, refreshTokenInput.expiresAt, refreshFrom ); } + private String generateRefreshTokenString(RefreshTokenInput refreshTokenInput, Instant asOf) { + return EncodingUtils.toBase64String(encodeIntoRefreshToken(refreshTokenInput, asOf)); + } + + private String generateAdvertisingTokenString(AdvertisingTokenInput advertisingTokenInput, Instant asOf) { + final byte[] advertisingTokenBytes = encodeIntoAdvertisingToken(advertisingTokenInput, asOf); + return bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); + } + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, key); diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 9a483c866..b53f79b4f 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -63,10 +63,10 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { ); if (tokenVersion == TokenVersion.V4) { - Assert.assertThrows(Exception.class, () -> encoder.encode(token, now)); + Assert.assertThrows(Exception.class, () -> encoder.encodeIntoRefreshToken(token, now)); return; //V4 not supported for RefreshTokens } - final byte[] encodedBytes = encoder.encode(token, now); + final byte[] encodedBytes = encoder.encodeIntoRefreshToken(token, now); final RefreshTokenInput decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); assertEquals(tokenVersion, decoded.version); @@ -104,7 +104,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, 121, now, now.minusSeconds(122)) ); - final byte[] encodedBytes = encoder.encode(token, now); + final byte[] encodedBytes = encoder.encodeIntoAdvertisingToken(token, now); final AdvertisingTokenInput decoded = encoder.decodeAdvertisingToken(EncryptedTokenEncoder.bytesToBase64Token(encodedBytes, tokenVersion)); assertEquals(tokenVersion, decoded.version); From 3b1718ca7c9ec7efb1cd08e1639d1c7f2f9fcfd6 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 16 Oct 2024 17:04:07 +1100 Subject: [PATCH 31/61] 1. Removed the UserIdentity's refreshedAt field as that's redundant and currently set to the same value as the AdvertisingTokenInput/RefreshTokenInput#createdAt timestamp. 2. Renamed some `token` variable names to adTokenInput and refreshTokenInput to make it clearer --- .../userIdentity/FirstLevelHashIdentity.java | 4 +- .../model/userIdentity/HashedDiiIdentity.java | 4 +- .../model/userIdentity/RawUidIdentity.java | 4 +- .../model/userIdentity/UserIdentity.java | 4 +- .../service/EncryptedTokenEncoder.java | 10 ++--- .../com/uid2/operator/service/InputUtil.java | 1 - .../operator/service/UIDOperatorService.java | 6 +-- .../com/uid2/operator/TokenEncodingTest.java | 38 +++++++++---------- .../uid2/operator/UIDOperatorServiceTest.java | 3 +- .../operator/benchmark/BenchmarkCommon.java | 2 +- 10 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index 64b8bcedd..d48607a4c 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -11,8 +11,8 @@ public class FirstLevelHashIdentity extends UserIdentity { public final byte[] firstLevelHash; public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, int privacyBits, - Instant establishedAt, Instant refreshedAt) { - super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); + Instant establishedAt) { + super(identityScope, identityType, privacyBits, establishedAt); this.firstLevelHash = firstLevelHash; } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java index dad862f21..6f7ced3c5 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java @@ -11,8 +11,8 @@ public class HashedDiiIdentity extends UserIdentity { public final byte[] hashedDii; public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, - Instant establishedAt, Instant refreshedAt) { - super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); + Instant establishedAt) { + super(identityScope, identityType, privacyBits, establishedAt); this.hashedDii = hashedDii; } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java index 4e15c6ff0..80bbbd182 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java @@ -11,8 +11,8 @@ public class RawUidIdentity extends UserIdentity { public final byte[] rawUid; public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid, int privacyBits, - Instant establishedAt, Instant refreshedAt) { - super(identityScope, identityType, privacyBits, establishedAt, refreshedAt); + Instant establishedAt) { + super(identityScope, identityType, privacyBits, establishedAt); this.rawUid = rawUid; } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java index 1391b7d75..b32da6385 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -12,13 +12,11 @@ public abstract class UserIdentity { public final IdentityType identityType; public final int privacyBits; public final Instant establishedAt; - public final Instant refreshedAt; - public UserIdentity(IdentityScope identityScope, IdentityType identityType, int privacyBits, Instant establishedAt, Instant refreshedAt) { + public UserIdentity(IdentityScope identityScope, IdentityType identityType, int privacyBits, Instant establishedAt) { this.identityScope = identityScope; this.identityType = identityType; this.privacyBits = privacyBits; this.establishedAt = establishedAt; - this.refreshedAt = refreshedAt; } } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 1a74a794a..fe2af06b3 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -55,7 +55,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey m encodePublisherRequesterV3(sitePayload, t.sourcePublisher); sitePayload.appendInt(t.rawUidIdentity.privacyBits); sitePayload.appendLong(t.rawUidIdentity.establishedAt.toEpochMilli()); - sitePayload.appendLong(t.rawUidIdentity.refreshedAt.toEpochMilli()); + sitePayload.appendLong(t.createdAt.toEpochMilli()); sitePayload.appendBytes(t.rawUidIdentity.rawUid); // 32 or 33 bytes final Buffer masterPayload = Buffer.buffer(130); @@ -127,7 +127,7 @@ private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { new OperatorIdentity(0, OperatorType.Service, 0, 0), new SourcePublisher(siteId, 0, 0), new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, identity, privacyBits, - Instant.ofEpochMilli(establishedMillis), null)); + Instant.ofEpochMilli(establishedMillis))); } private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { @@ -160,7 +160,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { return new RefreshTokenInput( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, privacyBits, establishedAt, null)); + new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, privacyBits, establishedAt)); } @Override @@ -229,7 +229,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new SourcePublisher(siteId, siteKeyId, 0), new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, privacyBits, - Instant.ofEpochMilli(establishedMillis), null) + Instant.ofEpochMilli(establishedMillis)) ); } catch (Exception e) { @@ -269,7 +269,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes return new AdvertisingTokenInput( tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new RawUidIdentity(identityScope, identityType, rawUid, privacyBits, establishedAt, refreshedAt) + new RawUidIdentity(identityScope, identityType, rawUid, privacyBits, establishedAt) ); } diff --git a/src/main/java/com/uid2/operator/service/InputUtil.java b/src/main/java/com/uid2/operator/service/InputUtil.java index ff9b3647b..fe63146f6 100644 --- a/src/main/java/com/uid2/operator/service/InputUtil.java +++ b/src/main/java/com/uid2/operator/service/InputUtil.java @@ -267,7 +267,6 @@ public HashedDiiIdentity toHashedDiiIdentity(IdentityScope identityScope, int pr this.identityType, getIdentityInput(), privacyBits, - establishedAt, establishedAt); } } diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 4c397885c..d8d1f8957 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -110,7 +110,7 @@ public IdentityResponse generateIdentity(IdentityRequest request) { final byte[] firstLevelHash = getFirstLevelHash(request.hashedDiiIdentity.hashedDii, now); final FirstLevelHashIdentity firstLevelHashIdentity = new FirstLevelHashIdentity( request.hashedDiiIdentity.identityScope, request.hashedDiiIdentity.identityType, firstLevelHash, request.hashedDiiIdentity.privacyBits, - request.hashedDiiIdentity.establishedAt, request.hashedDiiIdentity.refreshedAt); + request.hashedDiiIdentity.establishedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { return IdentityResponse.OptOutIdentityResponse; @@ -231,7 +231,7 @@ private FirstLevelHashIdentity getFirstLevelHashIdentity(HashedDiiIdentity hashe private FirstLevelHashIdentity getFirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] identityHash, Instant asOf) { final byte[] firstLevelHash = getFirstLevelHash(identityHash, asOf); - return new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, 0, null, null); + return new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, 0, null); } private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { @@ -255,7 +255,7 @@ private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, First final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - rawUidResponse.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt, nowUtc); + rawUidResponse.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt); return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc), diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index b53f79b4f..656d50f98 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -54,29 +54,29 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity("test@example.com", "some-salt"); - final RefreshTokenInput token = new RefreshTokenInput(tokenVersion, + final RefreshTokenInput refreshTokenInput = new RefreshTokenInput(tokenVersion, now, now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, 121, now, now.minusSeconds(122)) + new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, 121, now) ); if (tokenVersion == TokenVersion.V4) { - Assert.assertThrows(Exception.class, () -> encoder.encodeIntoRefreshToken(token, now)); + Assert.assertThrows(Exception.class, () -> encoder.encodeIntoRefreshToken(refreshTokenInput, now)); return; //V4 not supported for RefreshTokens } - final byte[] encodedBytes = encoder.encodeIntoRefreshToken(token, now); + final byte[] encodedBytes = encoder.encodeIntoRefreshToken(refreshTokenInput, now); final RefreshTokenInput decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); assertEquals(tokenVersion, decoded.version); - assertEquals(token.createdAt, decoded.createdAt); + assertEquals(refreshTokenInput.createdAt, decoded.createdAt); int addSeconds = (tokenVersion == TokenVersion.V2) ? 60 : 0; //todo: why is there a 60 second buffer in encodeV2() but not in encodeV3()? - assertEquals(token.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); - assertTrue(token.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); - assertEquals(token.firstLevelHashIdentity.privacyBits, decoded.firstLevelHashIdentity.privacyBits); - assertEquals(token.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); - assertEquals(token.sourcePublisher.siteId, decoded.sourcePublisher.siteId); + assertEquals(refreshTokenInput.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); + assertTrue(refreshTokenInput.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); + assertEquals(refreshTokenInput.firstLevelHashIdentity.privacyBits, decoded.firstLevelHashIdentity.privacyBits); + assertEquals(refreshTokenInput.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); + assertEquals(refreshTokenInput.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 25 : 2); @@ -95,25 +95,25 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { final byte[] rawUid = UIDOperatorVerticleTest.getRawUid(IdentityType.Email, "test@example.com", IdentityScope.UID2, tokenVersion != TokenVersion.V2); - final AdvertisingTokenInput token = new AdvertisingTokenInput( + final AdvertisingTokenInput adTokenInput = new AdvertisingTokenInput( tokenVersion, now, now.plusSeconds(60), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, 121, now, now.minusSeconds(122)) + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, 121, now) ); - final byte[] encodedBytes = encoder.encodeIntoAdvertisingToken(token, now); + final byte[] encodedBytes = encoder.encodeIntoAdvertisingToken(adTokenInput, now); final AdvertisingTokenInput decoded = encoder.decodeAdvertisingToken(EncryptedTokenEncoder.bytesToBase64Token(encodedBytes, tokenVersion)); assertEquals(tokenVersion, decoded.version); - assertEquals(token.createdAt, decoded.createdAt); - assertEquals(token.expiresAt, decoded.expiresAt); - assertTrue(token.rawUidIdentity.matches(decoded.rawUidIdentity)); - assertEquals(token.rawUidIdentity.privacyBits, decoded.rawUidIdentity.privacyBits); - assertEquals(token.rawUidIdentity.establishedAt, decoded.rawUidIdentity.establishedAt); - assertEquals(token.sourcePublisher.siteId, decoded.sourcePublisher.siteId); + assertEquals(adTokenInput.createdAt, decoded.createdAt); + assertEquals(adTokenInput.expiresAt, decoded.expiresAt); + assertTrue(adTokenInput.rawUidIdentity.matches(decoded.rawUidIdentity)); + assertEquals(adTokenInput.rawUidIdentity.privacyBits, decoded.rawUidIdentity.privacyBits); + assertEquals(adTokenInput.rawUidIdentity.establishedAt, decoded.rawUidIdentity.establishedAt); + assertEquals(adTokenInput.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 1 : 2); //TODO - extract master key from token should be a helper function diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 5196dfaf2..efc7c0578 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -129,8 +129,7 @@ private HashedDiiIdentity createHashedDiiIdentity(String rawIdentityHash, Identi type, rawIdentityHash.getBytes(StandardCharsets.UTF_8), 0, - this.now.minusSeconds(234), - this.now.plusSeconds(12345) + this.now.minusSeconds(234) ); } diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 1c25faecd..58f555818 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -156,7 +156,7 @@ static HashedDiiIdentity[] createHashedDiiIdentities() { final byte[] diiHash = new byte[33]; new Random().nextBytes(diiHash); arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, diiHash, 0, - Instant.now().minusSeconds(120), Instant.now().minusSeconds(60)); + Instant.now().minusSeconds(120)); } return arr; } From 0ab0a79f29a0ca294e9a0587bfed2cf16002790a Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 16 Oct 2024 18:42:22 +1100 Subject: [PATCH 32/61] 1. Removed privacyBits and establishedAt from UserIdentity/HashedDiiIdentity/RawUidIdentity but only kept inside FirstLevelHashIdentity - these fields are only relevant when a first level hash is generated for token generation and then passed along into ad token generation logic. 2. As a result, privacyBits and establishedAt are generated from either a. in a brand new token generation call (by default should be 1 and the timestamp at the time of the call) b. or, during token refresh logic, these fields will be inherited from previous refresh token. 3. Updated a lot of codes as a result (more refinement required such as not hardcoding the "1, Instant.now()" in a lot of places) --- .../operator/model/AdvertisingTokenInput.java | 8 +- .../uid2/operator/model/IdentityRequest.java | 11 ++- .../userIdentity/FirstLevelHashIdentity.java | 12 ++- .../model/userIdentity/HashedDiiIdentity.java | 5 +- .../model/userIdentity/RawUidIdentity.java | 5 +- .../model/userIdentity/UserIdentity.java | 6 +- .../service/EncryptedTokenEncoder.java | 24 +++--- .../com/uid2/operator/service/InputUtil.java | 6 +- .../operator/service/UIDOperatorService.java | 13 ++-- .../operator/vertx/UIDOperatorVerticle.java | 38 +++++----- .../com/uid2/operator/TokenEncodingTest.java | 8 +- .../uid2/operator/UIDOperatorServiceTest.java | 75 ++++++++++--------- .../operator/UIDOperatorVerticleTest.java | 42 +++++------ .../operator/benchmark/BenchmarkCommon.java | 3 +- .../benchmark/TokenEndecBenchmark.java | 5 +- 15 files changed, 144 insertions(+), 117 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java index b5ffcb89a..2d32dc4f4 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java @@ -10,12 +10,18 @@ public class AdvertisingTokenInput extends VersionedToken { public final SourcePublisher sourcePublisher; public final RawUidIdentity rawUidIdentity; + public final int privacyBits; + public final Instant establishedAt; + public AdvertisingTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity) { + SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, int privacyBits, + Instant establishedAt) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.sourcePublisher = sourcePublisher; this.rawUidIdentity = rawUidIdentity; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; } } diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index e9a0c96cb..a4f7c9b1d 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -2,19 +2,28 @@ import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import java.time.Instant; + public final class IdentityRequest { public final SourcePublisher sourcePublisher; public final HashedDiiIdentity hashedDiiIdentity; public final OptoutCheckPolicy optoutCheckPolicy; + public final int privacyBits; + public final Instant establishedAt; + public IdentityRequest( SourcePublisher sourcePublisher, HashedDiiIdentity hashedDiiIdentity, - OptoutCheckPolicy tokenGeneratePolicy) + OptoutCheckPolicy tokenGeneratePolicy, + int privacyBits, + Instant establishedAt) { this.sourcePublisher = sourcePublisher; this.hashedDiiIdentity = hashedDiiIdentity; this.optoutCheckPolicy = tokenGeneratePolicy; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; } public boolean shouldCheckOptOut() { diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index d48607a4c..5eb13526a 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -10,10 +10,20 @@ public class FirstLevelHashIdentity extends UserIdentity { public final byte[] firstLevelHash; + // for brand new token generation, it should contain 1 + // if the first level hash is from token/refresh call, it will inherit from the refresh token + public final int privacyBits; + + // for brand new token generation, it should be the time it is generated + // if the first level hash is from token/refresh call, it will be when the raw UID was originally created in the earliest token generation + public final Instant establishedAt; + public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, int privacyBits, Instant establishedAt) { - super(identityScope, identityType, privacyBits, establishedAt); + super(identityScope, identityType); this.firstLevelHash = firstLevelHash; + this.privacyBits = privacyBits; + this.establishedAt = establishedAt; } public boolean matches(FirstLevelHashIdentity that) { diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java index 6f7ced3c5..a9a6efe0a 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java @@ -10,9 +10,8 @@ public class HashedDiiIdentity extends UserIdentity { public final byte[] hashedDii; - public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii, int privacyBits, - Instant establishedAt) { - super(identityScope, identityType, privacyBits, establishedAt); + public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii) { + super(identityScope, identityType); this.hashedDii = hashedDii; } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java index 80bbbd182..b86740a05 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java @@ -10,9 +10,8 @@ public class RawUidIdentity extends UserIdentity { public final byte[] rawUid; - public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid, int privacyBits, - Instant establishedAt) { - super(identityScope, identityType, privacyBits, establishedAt); + public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid) { + super(identityScope, identityType); this.rawUid = rawUid; } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java index b32da6385..8221a8c61 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -10,13 +10,9 @@ public abstract class UserIdentity { public final IdentityScope identityScope; public final IdentityType identityType; - public final int privacyBits; - public final Instant establishedAt; - public UserIdentity(IdentityScope identityScope, IdentityType identityType, int privacyBits, Instant establishedAt) { + public UserIdentity(IdentityScope identityScope, IdentityType identityType) { this.identityScope = identityScope; this.identityType = identityType; - this.privacyBits = privacyBits; - this.establishedAt = establishedAt; } } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index fe2af06b3..67fac4d1d 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -41,7 +41,7 @@ private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenInput t, KeysetKey m Buffer b2 = Buffer.buffer(); b2.appendLong(t.expiresAt.toEpochMilli()); - encodeSiteIdentityV2(b2, t.sourcePublisher, t.rawUidIdentity, siteKey); + encodeSiteIdentityV2(b2, t.sourcePublisher, t.rawUidIdentity, siteKey, t.privacyBits, t.establishedAt); final byte[] encryptedId = AesCbc.encrypt(b2.getBytes(), masterKey).getPayload(); @@ -53,8 +53,8 @@ private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenInput t, KeysetKey m private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer sitePayload = Buffer.buffer(69); encodePublisherRequesterV3(sitePayload, t.sourcePublisher); - sitePayload.appendInt(t.rawUidIdentity.privacyBits); - sitePayload.appendLong(t.rawUidIdentity.establishedAt.toEpochMilli()); + sitePayload.appendInt(t.privacyBits); + sitePayload.appendLong(t.establishedAt.toEpochMilli()); sitePayload.appendLong(t.createdAt.toEpochMilli()); sitePayload.appendBytes(t.rawUidIdentity.rawUid); // 32 or 33 bytes @@ -228,8 +228,9 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new SourcePublisher(siteId, siteKeyId, 0), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, privacyBits, - Instant.ofEpochMilli(establishedMillis)) + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid), + privacyBits, + Instant.ofEpochMilli(establishedMillis) ); } catch (Exception e) { @@ -269,7 +270,8 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes return new AdvertisingTokenInput( tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new RawUidIdentity(identityScope, identityType, rawUid, privacyBits, establishedAt) + new RawUidIdentity(identityScope, identityType, rawUid), + privacyBits, establishedAt ); } @@ -330,9 +332,9 @@ public byte[] encodeIntoRefreshTokenV3(RefreshTokenInput t, KeysetKey serviceKey } private void encodeSiteIdentityV2(Buffer b, SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, - KeysetKey siteEncryptionKey) { + KeysetKey siteEncryptionKey, int privacyBits, Instant establishedAt) { b.appendInt(siteEncryptionKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(sourcePublisher, rawUidIdentity, siteEncryptionKey); + final byte[] encryptedIdentity = encryptIdentityV2(sourcePublisher, rawUidIdentity, siteEncryptionKey, privacyBits, establishedAt); b.appendBytes(encryptedIdentity); } @@ -370,9 +372,9 @@ private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHash } private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, - KeysetKey key) { - return encryptIdentityV2(sourcePublisher, rawUidIdentity.rawUid, rawUidIdentity.privacyBits, - rawUidIdentity.establishedAt, key); + KeysetKey key, int privacyBits, Instant establishedAt) { + return encryptIdentityV2(sourcePublisher, rawUidIdentity.rawUid, privacyBits, + establishedAt, key); } diff --git a/src/main/java/com/uid2/operator/service/InputUtil.java b/src/main/java/com/uid2/operator/service/InputUtil.java index fe63146f6..8e44e5717 100644 --- a/src/main/java/com/uid2/operator/service/InputUtil.java +++ b/src/main/java/com/uid2/operator/service/InputUtil.java @@ -261,13 +261,11 @@ public boolean isValid() { return valid; } - public HashedDiiIdentity toHashedDiiIdentity(IdentityScope identityScope, int privacyBits, Instant establishedAt) { + public HashedDiiIdentity toHashedDiiIdentity(IdentityScope identityScope) { return new HashedDiiIdentity( identityScope, this.identityType, - getIdentityInput(), - privacyBits, - establishedAt); + getIdentityInput()); } } diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index d8d1f8957..eed0c0bb8 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -109,8 +109,8 @@ public IdentityResponse generateIdentity(IdentityRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); final byte[] firstLevelHash = getFirstLevelHash(request.hashedDiiIdentity.hashedDii, now); final FirstLevelHashIdentity firstLevelHashIdentity = new FirstLevelHashIdentity( - request.hashedDiiIdentity.identityScope, request.hashedDiiIdentity.identityType, firstLevelHash, request.hashedDiiIdentity.privacyBits, - request.hashedDiiIdentity.establishedAt); + request.hashedDiiIdentity.identityScope, request.hashedDiiIdentity.identityType, firstLevelHash, request.privacyBits, + request.establishedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { return IdentityResponse.OptOutIdentityResponse; @@ -255,10 +255,10 @@ private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, First final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - rawUidResponse.rawUid, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt); + rawUidResponse.rawUid); return this.encoder.encodeIntoIdentityResponse( - this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc), + this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt), this.createRefreshTokenInput(sourcePublisher, firstLevelHashIdentity, nowUtc), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc @@ -277,7 +277,7 @@ private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublishe } private AdvertisingTokenInput createAdvertisingTokenInput(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, - Instant now) { + Instant now, int privacyBits, Instant establishedAt) { TokenVersion tokenVersion; if (siteIdsUsingV4Tokens.contains(sourcePublisher.siteId)) { tokenVersion = TokenVersion.V4; @@ -291,7 +291,8 @@ private AdvertisingTokenInput createAdvertisingTokenInput(SourcePublisher source } tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } - return new AdvertisingTokenInput(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, sourcePublisher, rawUidIdentity); + return new AdvertisingTokenInput(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, sourcePublisher, rawUidIdentity, + privacyBits, establishedAt); } static protected class GlobalOptoutResult { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 58c6703a1..143de537d 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -465,8 +465,8 @@ else if(emailHash != null) { identityResponse = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(clientSideKeypair.getSiteId(), 0, 0), - input.toHashedDiiIdentity(this.identityScope, privacyBits.getAsInt(), Instant.now()), - OptoutCheckPolicy.RespectOptOut)); + input.toHashedDiiIdentity(this.identityScope), + OptoutCheckPolicy.RespectOptOut, privacyBits.getAsInt(), Instant.now())); } catch (KeyManager.NoActiveKeyException e){ SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, platformType); return; @@ -878,7 +878,7 @@ private void handleTokenValidateV1(RoutingContext rc) { || (Arrays.equals(ValidateIdentityForPhoneHash, input.getIdentityInput()) && input.getIdentityType() == IdentityType.Phone)) { try { final Instant now = Instant.now(); - if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope, 0, now), now)) { + if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope), now)) { ResponseUtil.Success(rc, Boolean.TRUE); } else { ResponseUtil.Success(rc, Boolean.FALSE); @@ -911,7 +911,7 @@ private void handleTokenValidateV2(RoutingContext rc) { final Instant now = Instant.now(); final String token = req.getString("token"); - if (this.idService.advertisingTokenMatches(token, input.toHashedDiiIdentity(this.identityScope, 0, now), now)) { + if (this.idService.advertisingTokenMatches(token, input.toHashedDiiIdentity(this.identityScope), now)) { ResponseUtil.SuccessV2(rc, Boolean.TRUE); } else { ResponseUtil.SuccessV2(rc, Boolean.FALSE); @@ -940,8 +940,8 @@ private void handleTokenGenerateV1(RoutingContext rc) { final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), - input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), - OptoutCheckPolicy.defaultPolicy())); + input.toHashedDiiIdentity(this.identityScope), + OptoutCheckPolicy.defaultPolicy(), 1, Instant.now())); //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); @@ -996,8 +996,8 @@ private void handleTokenGenerateV2(RoutingContext rc) { final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), - input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), - OptoutCheckPolicy.respectOptOut())); + input.toHashedDiiIdentity(this.identityScope), + OptoutCheckPolicy.respectOptOut(),1, Instant.now())); if (t.isOptedOut()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy @@ -1012,8 +1012,8 @@ private void handleTokenGenerateV2(RoutingContext rc) { final IdentityResponse optOutTokens = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), - optOutTokenInput.toHashedDiiIdentity(this.identityScope, pb.getAsInt(), Instant.now()), - OptoutCheckPolicy.DoNotRespect)); + optOutTokenInput.toHashedDiiIdentity(this.identityScope), + OptoutCheckPolicy.DoNotRespect, pb.getAsInt(), Instant.now())); ResponseUtil.SuccessV2(rc, optOutTokens.toJsonV1()); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, optOutTokens.getAdvertisingTokenVersion(), platformType); @@ -1052,8 +1052,8 @@ else if (!input.isValid()) { final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId, 0, 0), - input.toHashedDiiIdentity(this.identityScope, 1, Instant.now()), - OptoutCheckPolicy.defaultPolicy())); + input.toHashedDiiIdentity(this.identityScope), + OptoutCheckPolicy.defaultPolicy(), 1, Instant.now())); //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); @@ -1094,7 +1094,7 @@ private void handleValidate(RoutingContext rc) { if (input != null && input.isValid() && Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput())) { try { final Instant now = Instant.now(); - if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope, 0, now), now)) { + if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope), now)) { rc.response().end("true"); } else { rc.response().end("false"); @@ -1115,7 +1115,7 @@ private void handleLogoutAsync(RoutingContext rc) { final InputUtil.InputVal input = this.phoneSupport ? getTokenInputV1(rc) : getTokenInput(rc); if (input.isValid()) { final Instant now = Instant.now(); - this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope, 0, now), now, ar -> { + this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope), now, ar -> { if (ar.succeeded()) { rc.response().end("OK"); } else { @@ -1134,7 +1134,7 @@ private Future handleLogoutAsyncV2(RoutingContext rc) { final Instant now = Instant.now(); Promise promise = Promise.promise(); - this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope, 0, now), now, ar -> { + this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope), now, ar -> { if (ar.succeeded()) { JsonObject body = new JsonObject(); body.put("optout", "OK"); @@ -1156,7 +1156,7 @@ private void handleOptOutGet(RoutingContext rc) { if (input.isValid()) { try { final Instant now = Instant.now(); - final HashedDiiIdentity hashedDiiIdentity = input.toHashedDiiIdentity(this.identityScope, 0, now); + final HashedDiiIdentity hashedDiiIdentity = input.toHashedDiiIdentity(this.identityScope); final Instant result = this.idService.getLatestOptoutEntry(hashedDiiIdentity, now); long timestamp = result == null ? -1 : result.getEpochSecond(); rc.response().setStatusCode(200) @@ -1241,7 +1241,7 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUidResponse.rawUid)); @@ -1264,7 +1264,7 @@ else if (!input.isValid()) { } else { final Instant now = Instant.now(); - final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope, 0, now), now); + final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); rc.response().end(EncodingUtils.toBase64String(rawUidResponse.rawUid)); } } catch (Exception ex) { @@ -1462,7 +1462,7 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal if (input != null && input.isValid()) { final RawUidResponse rawUidResponse = idService.mapIdentity( new MapRequest( - input.toHashedDiiIdentity(this.identityScope, 0, now), + input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.respectOptOut(), now)); diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 656d50f98..b2255e1d0 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -101,7 +101,9 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { now.plusSeconds(60), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid, 121, now) + new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid), + 121, + now ); final byte[] encodedBytes = encoder.encodeIntoAdvertisingToken(adTokenInput, now); @@ -111,8 +113,8 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { assertEquals(adTokenInput.createdAt, decoded.createdAt); assertEquals(adTokenInput.expiresAt, decoded.expiresAt); assertTrue(adTokenInput.rawUidIdentity.matches(decoded.rawUidIdentity)); - assertEquals(adTokenInput.rawUidIdentity.privacyBits, decoded.rawUidIdentity.privacyBits); - assertEquals(adTokenInput.rawUidIdentity.establishedAt, decoded.rawUidIdentity.establishedAt); + assertEquals(adTokenInput.privacyBits, decoded.privacyBits); + assertEquals(adTokenInput.establishedAt, decoded.establishedAt); assertEquals(adTokenInput.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index efc7c0578..5c3b23433 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -127,9 +127,7 @@ private HashedDiiIdentity createHashedDiiIdentity(String rawIdentityHash, Identi return new HashedDiiIdentity( scope, type, - rawIdentityHash.getBytes(StandardCharsets.UTF_8), - 0, - this.now.minusSeconds(234) + rawIdentityHash.getBytes(StandardCharsets.UTF_8) ); } @@ -139,11 +137,10 @@ private AdvertisingTokenInput validateAndGetToken(EncryptedTokenEncoder tokenEnc return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); } - private void assertIdentityScopeIdentityTypeAndEstablishedAt(UserIdentity expctedValues, - UserIdentity actualValues) { + private void assertIdentityScopeIdentityType(UserIdentity expctedValues, + UserIdentity actualValues) { assertEquals(expctedValues.identityScope, actualValues.identityScope); assertEquals(expctedValues.identityType, actualValues.identityType); - assertEquals(expctedValues.establishedAt, actualValues.establishedAt); } @ParameterizedTest @@ -152,7 +149,8 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(siteId, 124, 125), createHashedDiiIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), - OptoutCheckPolicy.DoNotRespect + OptoutCheckPolicy.DoNotRespect, 0, + this.now.minusSeconds(234) ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); @@ -162,13 +160,15 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { UIDOperatorVerticleTest.validateAdvertisingToken(identityResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identityResponse.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenInput.sourcePublisher.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); + assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); + assertEquals(identityRequest.establishedAt, advertisingTokenInput.establishedAt); RefreshTokenInput refreshTokenInput = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); assertEquals(this.now, refreshTokenInput.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput.expiresAt); assertEquals(identityRequest.sourcePublisher.siteId, refreshTokenInput.sourcePublisher.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(identityRequest.hashedDiiIdentity, refreshTokenInput.firstLevelHashIdentity); + assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, refreshTokenInput.firstLevelHashIdentity); + assertEquals(identityRequest.establishedAt, refreshTokenInput.firstLevelHashIdentity.establishedAt); setNow(Instant.now().plusSeconds(200)); @@ -184,8 +184,9 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { AdvertisingTokenInput advertisingTokenInput2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput2.expiresAt); assertEquals(advertisingTokenInput.sourcePublisher.siteId, advertisingTokenInput2.sourcePublisher.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(advertisingTokenInput.rawUidIdentity, + assertIdentityScopeIdentityType(advertisingTokenInput.rawUidIdentity, advertisingTokenInput2.rawUidIdentity); + assertEquals(advertisingTokenInput.establishedAt, advertisingTokenInput2.establishedAt); assertArrayEquals(advertisingTokenInput.rawUidIdentity.rawUid, advertisingTokenInput2.rawUidIdentity.rawUid); @@ -193,7 +194,8 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(this.now, refreshTokenInput2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput2.expiresAt); assertEquals(refreshTokenInput.sourcePublisher.siteId, refreshTokenInput2.sourcePublisher.siteId); - assertIdentityScopeIdentityTypeAndEstablishedAt(refreshTokenInput.firstLevelHashIdentity, refreshTokenInput2.firstLevelHashIdentity); + assertIdentityScopeIdentityType(refreshTokenInput.firstLevelHashIdentity, refreshTokenInput2.firstLevelHashIdentity); + assertEquals(refreshTokenInput.firstLevelHashIdentity.establishedAt, refreshTokenInput2.firstLevelHashIdentity.establishedAt); assertArrayEquals(refreshTokenInput.firstLevelHashIdentity.firstLevelHash, refreshTokenInput2.firstLevelHashIdentity.firstLevelHash); } @@ -203,8 +205,8 @@ public void testTestOptOutKey_DoNotRespectOptout() { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), - OptoutCheckPolicy.DoNotRespect + inputVal.toHashedDiiIdentity(IdentityScope.UID2), + OptoutCheckPolicy.DoNotRespect, 0, this.now ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); @@ -222,8 +224,8 @@ public void testTestOptOutKey_RespectOptout() { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(IdentityScope.UID2, 0, this.now), - OptoutCheckPolicy.RespectOptOut + inputVal.toHashedDiiIdentity(IdentityScope.UID2), + OptoutCheckPolicy.RespectOptOut, 0, this.now ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); assertTrue(identityResponse.isOptedOut()); @@ -238,8 +240,8 @@ public void testTestOptOutKeyIdentityScopeMismatch() { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(IdentityScope.EUID, 0, this.now), - OptoutCheckPolicy.DoNotRespect + inputVal.toHashedDiiIdentity(IdentityScope.EUID), + OptoutCheckPolicy.DoNotRespect, 0, this.now ); final IdentityResponse identityResponse = euidService.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); @@ -264,12 +266,14 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit final IdentityRequest identityRequestForceGenerate = new IdentityRequest( new SourcePublisher(123, 124, 125), hashedDiiIdentity, - OptoutCheckPolicy.DoNotRespect); + OptoutCheckPolicy.DoNotRespect,0, + this.now.minusSeconds(234)); final IdentityRequest identityRequestRespectOptOut = new IdentityRequest( new SourcePublisher(123, 124, 125), hashedDiiIdentity, - OptoutCheckPolicy.RespectOptOut); + OptoutCheckPolicy.RespectOptOut, 0, + this.now.minusSeconds(234)); // the clock value shouldn't matter here when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) @@ -394,8 +398,8 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope, 0, this.now), - OptoutCheckPolicy.RespectOptOut + inputVal.toHashedDiiIdentity(scope), + OptoutCheckPolicy.RespectOptOut, 0, this.now ); // identity has no optout record, ensure generate still returns optout @@ -426,7 +430,8 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, InputUtil.InputVal inputVal = generateInputVal(type, id); final MapRequest mapRequestRespectOptOut = new MapRequest( - inputVal.toHashedDiiIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope), +// inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); @@ -460,8 +465,8 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope, 0, this.now), - OptoutCheckPolicy.DoNotRespect + inputVal.toHashedDiiIdentity(scope), + OptoutCheckPolicy.DoNotRespect, 0, this.now ); IdentityResponse identityResponse; @@ -499,8 +504,8 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope, 0, this.now), - OptoutCheckPolicy.RespectOptOut + inputVal.toHashedDiiIdentity(scope), + OptoutCheckPolicy.RespectOptOut, 0, this.now ); // identity has optout record, ensure still generates @@ -540,7 +545,7 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str InputUtil.InputVal inputVal = generateInputVal(type, id); final MapRequest mapRequestRespectOptOut = new MapRequest( - inputVal.toHashedDiiIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -574,8 +579,8 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope, 0, this.now), - OptoutCheckPolicy.RespectOptOut + inputVal.toHashedDiiIdentity(scope), + OptoutCheckPolicy.RespectOptOut, 0, this.now ); // all identities have optout records, ensure validate identities still get generated @@ -611,7 +616,7 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i InputUtil.InputVal inputVal = generateInputVal(type, id); final MapRequest mapRequestRespectOptOut = new MapRequest( - inputVal.toHashedDiiIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -642,8 +647,8 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope, 0, this.now), - OptoutCheckPolicy.DoNotRespect + inputVal.toHashedDiiIdentity(scope), + OptoutCheckPolicy.DoNotRespect, 1, Instant.now() ); IdentityResponse identityResponse; if(scope == IdentityScope.EUID) { @@ -703,8 +708,8 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope, 0, this.now), - OptoutCheckPolicy.RespectOptOut); + inputVal.toHashedDiiIdentity(scope), + OptoutCheckPolicy.RespectOptOut, 0, this.now); IdentityResponse identityResponse; AdvertisingTokenInput advertisingTokenInput; @@ -733,7 +738,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String assertNotEquals(RefreshResponse.Optout, refreshResponse); final MapRequest mapRequest = new MapRequest( - inputVal.toHashedDiiIdentity(scope, 0, this.now), + inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, now); final RawUidResponse rawUidResponse; diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index ea8385779..1e09c6ea7 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1180,10 +1180,10 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi String advertisingTokenString = body.getString("advertising_token"); final Instant now = Instant.now(); final String token = advertisingTokenString; - final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDiiIdentity(getIdentityScope(), 0, now), now); + final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDiiIdentity(getIdentityScope()), now); assertTrue(matchedOptedOutIdentity); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertTrue(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertTrue(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertTokenStatusMetrics( 201, @@ -1229,8 +1229,8 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1271,8 +1271,8 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1315,8 +1315,8 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1374,8 +1374,8 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1586,8 +1586,8 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -2498,8 +2498,8 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -2537,8 +2537,8 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -2581,8 +2581,8 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits).isClientSideTokenOptedOut()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); + assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -4010,7 +4010,7 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver // When we refresh the token the user has opted out. when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) - .thenReturn(advertisingTokenInput.rawUidIdentity.establishedAt.plusSeconds(1)); + .thenReturn(advertisingTokenInput.establishedAt.plusSeconds(1)); sendTokenRefresh("v2", vertx, testContext, genBody.getString("refresh_token"), genBody.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("optout", refreshRespJson.getString("status")); @@ -4202,7 +4202,7 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisin } private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { - final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingTokenInput.rawUidIdentity.privacyBits); + final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingTokenInput.privacyBits); final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshTokenInput.firstLevelHashIdentity.privacyBits); final byte[] rawUid = getRawUidFromIdentity(identityType, diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 58f555818..1c6153d22 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -155,8 +155,7 @@ static HashedDiiIdentity[] createHashedDiiIdentities() { for (int i = 0; i < 65536; i++) { final byte[] diiHash = new byte[33]; new Random().nextBytes(diiHash); - arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, diiHash, 0, - Instant.now().minusSeconds(120)); + arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, diiHash); } return arr; } diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index e907f638c..bc8fddb27 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -8,6 +8,7 @@ import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; +import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -42,7 +43,7 @@ static IdentityResponse[] createAdvertisingTokens() { uidService.generateIdentity(new IdentityRequest( publisher, hashedDiiIdentities[i], - OptoutCheckPolicy.DoNotRespect))); + OptoutCheckPolicy.DoNotRespect, 1, Instant.now()))); } return tokens.toArray(new IdentityResponse[tokens.size()]); } @@ -53,7 +54,7 @@ public IdentityResponse TokenGenerationBenchmark() { return uidService.generateIdentity(new IdentityRequest( publisher, hashedDiiIdentities[(idx++) & 65535], - OptoutCheckPolicy.DoNotRespect)); + OptoutCheckPolicy.DoNotRespect, 1, Instant.now())); } @Benchmark From 7538bfbc86394d78a5233bb388c7a9dd440b5704 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 16 Oct 2024 19:08:48 +1100 Subject: [PATCH 33/61] added comments --- .../java/com/uid2/operator/service/EncryptedTokenEncoder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 67fac4d1d..f3e22c5b5 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -55,6 +55,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey m encodePublisherRequesterV3(sitePayload, t.sourcePublisher); sitePayload.appendInt(t.privacyBits); sitePayload.appendLong(t.establishedAt.toEpochMilli()); + // this is the refreshedAt field in the spec - but effectively it is the time this advertising token is generated sitePayload.appendLong(t.createdAt.toEpochMilli()); sitePayload.appendBytes(t.rawUidIdentity.rawUid); // 32 or 33 bytes @@ -253,6 +254,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes final SourcePublisher sourcePublisher = decodeSourcePublisherV3(sitePayload, 0); final int privacyBits = sitePayload.getInt(16); final Instant establishedAt = Instant.ofEpochMilli(sitePayload.getLong(20)); + // refreshedAt is currently not used final Instant refreshedAt = Instant.ofEpochMilli(sitePayload.getLong(28)); final byte[] rawUid = sitePayload.slice(36, sitePayload.length()).getBytes(); final IdentityScope identityScope = rawUid.length == 32 ? IdentityScope.UID2 : decodeIdentityScopeV3(rawUid[0]); From 249c25dedd2f81414503ac56a19c6dd1039e2b1e Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 16 Oct 2024 19:23:42 +1100 Subject: [PATCH 34/61] fixed variable name --- .../java/com/uid2/operator/service/UIDOperatorService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index eed0c0bb8..2b4288151 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -193,10 +193,10 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { - final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResponse rawUidResponse = generateRawUid(hashedDiiIdentity, asOf); + final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); + final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, asOf); - this.optOutStore.addEntry(hashedDiiIdentity, rawUidResponse.rawUid, r -> { + this.optOutStore.addEntry(firstLevelHashIdentity, rawUidResponse.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { From 53f4de1bbf979c1fcf69d33e498c51ede2f3efd9 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 16 Oct 2024 19:25:25 +1100 Subject: [PATCH 35/61] fixed variable name --- .../java/com/uid2/operator/service/UIDOperatorService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index c460ba8c1..440c7fc8e 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -193,10 +193,10 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { - final FirstLevelHashIdentity hashedDiiIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResponse rawUidResponse = generateRawUid(hashedDiiIdentity, asOf); + final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); + final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, asOf); - this.optOutStore.addEntry(hashedDiiIdentity, rawUidResponse.rawUid, r -> { + this.optOutStore.addEntry(firstLevelHashIdentity, rawUidResponse.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { From 4c1de75cb033397ba94965d21d630e985163a529 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 21 Oct 2024 12:25:10 +1100 Subject: [PATCH 36/61] Moved privacyBits out of FirstLevelHashIdentity and treat it as a separate input --- .../operator/model/AdvertisingTokenInput.java | 1 - .../operator/model/RefreshTokenInput.java | 6 +++- .../userIdentity/FirstLevelHashIdentity.java | 7 +---- .../service/EncryptedTokenEncoder.java | 18 +++++++----- .../operator/service/UIDOperatorService.java | 29 ++++++++++++------- .../com/uid2/operator/TokenEncodingTest.java | 5 ++-- .../operator/UIDOperatorVerticleTest.java | 2 +- 7 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java index 2d32dc4f4..a9bcbc11f 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java @@ -9,7 +9,6 @@ public class AdvertisingTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final RawUidIdentity rawUidIdentity; - public final int privacyBits; public final Instant establishedAt; diff --git a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java index 15bef6a0c..2d306bbfb 100644 --- a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java +++ b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java @@ -9,12 +9,16 @@ public class RefreshTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final FirstLevelHashIdentity firstLevelHashIdentity; + // inherited from the previous refresh token's privacy bits + public final int privacyBits; + public RefreshTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { + SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, int privacyBits) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.sourcePublisher = sourcePublisher; this.firstLevelHashIdentity = firstLevelHashIdentity; + this.privacyBits = privacyBits; } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index 5eb13526a..b549833ed 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -10,19 +10,14 @@ public class FirstLevelHashIdentity extends UserIdentity { public final byte[] firstLevelHash; - // for brand new token generation, it should contain 1 - // if the first level hash is from token/refresh call, it will inherit from the refresh token - public final int privacyBits; - // for brand new token generation, it should be the time it is generated // if the first level hash is from token/refresh call, it will be when the raw UID was originally created in the earliest token generation public final Instant establishedAt; - public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, int privacyBits, + public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, Instant establishedAt) { super(identityScope, identityType); this.firstLevelHash = firstLevelHash; - this.privacyBits = privacyBits; this.establishedAt = establishedAt; } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index f3e22c5b5..c60d3f96a 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -127,8 +127,9 @@ private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), new SourcePublisher(siteId, 0, 0), - new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, identity, privacyBits, - Instant.ofEpochMilli(establishedMillis))); + new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, identity, + Instant.ofEpochMilli(establishedMillis)), + privacyBits); } private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { @@ -161,7 +162,8 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { return new RefreshTokenInput( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, privacyBits, establishedAt)); + new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, establishedAt), + privacyBits); } @Override @@ -308,7 +310,8 @@ public byte[] encodeIntoRefreshTokenV2(RefreshTokenInput t, KeysetKey serviceKey // give an extra minute for clients which are trying to refresh tokens close to or at the refresh expiry timestamp b.appendLong(t.expiresAt.plusSeconds(60).toEpochMilli()); b.appendInt(serviceKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(t.sourcePublisher, t.firstLevelHashIdentity, serviceKey); + final byte[] encryptedIdentity = encryptIdentityV2(t.sourcePublisher, t.firstLevelHashIdentity, serviceKey, + t.privacyBits); b.appendBytes(encryptedIdentity); return b.getBytes(); } @@ -319,7 +322,7 @@ public byte[] encodeIntoRefreshTokenV3(RefreshTokenInput t, KeysetKey serviceKey refreshPayload.appendLong(t.createdAt.toEpochMilli()); encodeOperatorIdentityV3(refreshPayload, t.operatorIdentity); encodePublisherRequesterV3(refreshPayload, t.sourcePublisher); - refreshPayload.appendInt(t.firstLevelHashIdentity.privacyBits); + refreshPayload.appendInt(t.privacyBits); refreshPayload.appendLong(t.firstLevelHashIdentity.establishedAt.toEpochMilli()); refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHashIdentity.identityScope, t.firstLevelHashIdentity.identityType)); refreshPayload.appendBytes(t.firstLevelHashIdentity.firstLevelHash); @@ -368,8 +371,9 @@ private String generateAdvertisingTokenString(AdvertisingTokenInput advertisingT return bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); } - private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, KeysetKey key) { - return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, firstLevelHashIdentity.privacyBits, + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, + KeysetKey key, int privacyBits) { + return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, privacyBits, firstLevelHashIdentity.establishedAt, key); } diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 2b4288151..b76261f87 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -109,13 +109,13 @@ public IdentityResponse generateIdentity(IdentityRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); final byte[] firstLevelHash = getFirstLevelHash(request.hashedDiiIdentity.hashedDii, now); final FirstLevelHashIdentity firstLevelHashIdentity = new FirstLevelHashIdentity( - request.hashedDiiIdentity.identityScope, request.hashedDiiIdentity.identityType, firstLevelHash, request.privacyBits, + request.hashedDiiIdentity.identityScope, request.hashedDiiIdentity.identityType, firstLevelHash, request.establishedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { return IdentityResponse.OptOutIdentityResponse; } else { - return generateIdentity(request.sourcePublisher, firstLevelHashIdentity); + return generateIdentity(request.sourcePublisher, firstLevelHashIdentity, request.privacyBits); } } @@ -136,7 +136,7 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { return RefreshResponse.Expired; } - final PrivacyBits privacyBits = PrivacyBits.fromInt(token.firstLevelHashIdentity.privacyBits); + final PrivacyBits privacyBits = PrivacyBits.fromInt(token.privacyBits); final boolean isCstg = privacyBits.isClientSideTokenGenerated(); try { @@ -146,7 +146,9 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { final Duration durationSinceLastRefresh = Duration.between(token.createdAt, now); if (!optedOut) { - IdentityResponse identityResponse = this.generateIdentity(token.sourcePublisher, token.firstLevelHashIdentity); + IdentityResponse identityResponse = this.generateIdentity(token.sourcePublisher, + token.firstLevelHashIdentity, + token.privacyBits); return RefreshResponse.createRefreshedResponse(identityResponse, durationSinceLastRefresh, isCstg); } else { @@ -231,7 +233,7 @@ private FirstLevelHashIdentity getFirstLevelHashIdentity(HashedDiiIdentity hashe private FirstLevelHashIdentity getFirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] identityHash, Instant asOf) { final byte[] firstLevelHash = getFirstLevelHash(identityHash, asOf); - return new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, 0, null); + return new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, null); } private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { @@ -249,7 +251,8 @@ private RawUidResponse generateRawUid(FirstLevelHashIdentity firstLevelHashIdent rotatingSalt.getHashedId()); } - private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity) { + private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, + FirstLevelHashIdentity firstLevelHashIdentity, int privacyBits) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); @@ -258,22 +261,26 @@ private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, First rawUidResponse.rawUid); return this.encoder.encodeIntoIdentityResponse( - this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc, firstLevelHashIdentity.privacyBits, firstLevelHashIdentity.establishedAt), - this.createRefreshTokenInput(sourcePublisher, firstLevelHashIdentity, nowUtc), + this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc, privacyBits, + firstLevelHashIdentity.establishedAt), + this.createRefreshTokenInput(sourcePublisher, firstLevelHashIdentity, nowUtc, privacyBits), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc ); } - private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, - Instant now) { + private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublisher, + FirstLevelHashIdentity firstLevelHashIdentity, + Instant now, + int privacyBits) { return new RefreshTokenInput( this.refreshTokenVersion, now, now.plusMillis(refreshExpiresAfter.toMillis()), this.operatorIdentity, sourcePublisher, - firstLevelHashIdentity); + firstLevelHashIdentity, + privacyBits); } private AdvertisingTokenInput createAdvertisingTokenInput(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index b2255e1d0..2057b8891 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -59,7 +59,8 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, 121, now) + new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, now), + 121 ); if (tokenVersion == TokenVersion.V4) { @@ -74,7 +75,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { int addSeconds = (tokenVersion == TokenVersion.V2) ? 60 : 0; //todo: why is there a 60 second buffer in encodeV2() but not in encodeV3()? assertEquals(refreshTokenInput.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); assertTrue(refreshTokenInput.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); - assertEquals(refreshTokenInput.firstLevelHashIdentity.privacyBits, decoded.firstLevelHashIdentity.privacyBits); + assertEquals(refreshTokenInput.privacyBits, decoded.privacyBits); assertEquals(refreshTokenInput.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); assertEquals(refreshTokenInput.sourcePublisher.siteId, decoded.sourcePublisher.siteId); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 1e09c6ea7..c0afecbc6 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4203,7 +4203,7 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisin private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingTokenInput.privacyBits); - final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshTokenInput.firstLevelHashIdentity.privacyBits); + final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshTokenInput.privacyBits); final byte[] rawUid = getRawUidFromIdentity(identityType, identity, From 062f90887422c78af1803411eeb32ab1e23890fb Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 21 Oct 2024 12:37:29 +1100 Subject: [PATCH 37/61] Added a new IdentityRequest constructor to set default values for privacyBits and establishedAt fields --- .../com/uid2/operator/model/IdentityRequest.java | 13 +++++++++++++ .../com/uid2/operator/model/RefreshTokenInput.java | 2 +- .../java/com/uid2/operator/util/PrivacyBits.java | 3 +++ .../uid2/operator/vertx/UIDOperatorVerticle.java | 6 +++--- .../com/uid2/operator/UIDOperatorServiceTest.java | 2 +- .../operator/benchmark/TokenEndecBenchmark.java | 4 ++-- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index a4f7c9b1d..a6c7bfc9c 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -1,6 +1,7 @@ package com.uid2.operator.model; import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.util.PrivacyBits; import java.time.Instant; @@ -26,6 +27,18 @@ public IdentityRequest( this.establishedAt = establishedAt; } + public IdentityRequest( + SourcePublisher sourcePublisher, + HashedDiiIdentity hashedDiiIdentity, + OptoutCheckPolicy tokenGeneratePolicy) + { + this.sourcePublisher = sourcePublisher; + this.hashedDiiIdentity = hashedDiiIdentity; + this.optoutCheckPolicy = tokenGeneratePolicy; + this.privacyBits = PrivacyBits.DEFAULT_PRIVACY_BIT_VALUE; + this.establishedAt = Instant.now(); + } + public boolean shouldCheckOptOut() { return optoutCheckPolicy.equals(OptoutCheckPolicy.RespectOptOut); } diff --git a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java index 2d306bbfb..9b45ca3e9 100644 --- a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java +++ b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java @@ -9,7 +9,7 @@ public class RefreshTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final FirstLevelHashIdentity firstLevelHashIdentity; - // inherited from the previous refresh token's privacy bits + // by default, inherited from the previous refresh token's privacy bits public final int privacyBits; diff --git a/src/main/java/com/uid2/operator/util/PrivacyBits.java b/src/main/java/com/uid2/operator/util/PrivacyBits.java index f8b7edf6a..11edde226 100644 --- a/src/main/java/com/uid2/operator/util/PrivacyBits.java +++ b/src/main/java/com/uid2/operator/util/PrivacyBits.java @@ -3,6 +3,9 @@ public class PrivacyBits { + // For historical reason this bit is set + public static final int DEFAULT_PRIVACY_BIT_VALUE = 1; + private static final int BIT_LEGACY = 0; private static final int BIT_CSTG = 1; private static final int BIT_CSTG_OPTOUT = 2; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 143de537d..828dd2c14 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -941,7 +941,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { new IdentityRequest( new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope), - OptoutCheckPolicy.defaultPolicy(), 1, Instant.now())); + OptoutCheckPolicy.defaultPolicy())); //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); @@ -997,7 +997,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { new IdentityRequest( new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope), - OptoutCheckPolicy.respectOptOut(),1, Instant.now())); + OptoutCheckPolicy.respectOptOut())); if (t.isOptedOut()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy @@ -1053,7 +1053,7 @@ else if (!input.isValid()) { new IdentityRequest( new SourcePublisher(siteId, 0, 0), input.toHashedDiiIdentity(this.identityScope), - OptoutCheckPolicy.defaultPolicy(), 1, Instant.now())); + OptoutCheckPolicy.defaultPolicy())); //Integer.parseInt(rc.queryParam("privacy_bits").get(0)))); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 5c3b23433..4d749f4d7 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -648,7 +648,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), - OptoutCheckPolicy.DoNotRespect, 1, Instant.now() + OptoutCheckPolicy.DoNotRespect ); IdentityResponse identityResponse; if(scope == IdentityScope.EUID) { diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index bc8fddb27..14a650047 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -43,7 +43,7 @@ static IdentityResponse[] createAdvertisingTokens() { uidService.generateIdentity(new IdentityRequest( publisher, hashedDiiIdentities[i], - OptoutCheckPolicy.DoNotRespect, 1, Instant.now()))); + OptoutCheckPolicy.DoNotRespect))); } return tokens.toArray(new IdentityResponse[tokens.size()]); } @@ -54,7 +54,7 @@ public IdentityResponse TokenGenerationBenchmark() { return uidService.generateIdentity(new IdentityRequest( publisher, hashedDiiIdentities[(idx++) & 65535], - OptoutCheckPolicy.DoNotRespect, 1, Instant.now())); + OptoutCheckPolicy.DoNotRespect)); } @Benchmark From 76a134579c312e1ddcf0ef092242e50577759a35 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 12:35:47 +1100 Subject: [PATCH 38/61] Update src/main/java/com/uid2/operator/model/IdentityRequest.java Co-authored-by: mcollins-ttd <118872455+mcollins-ttd@users.noreply.github.com> --- src/main/java/com/uid2/operator/model/IdentityRequest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index a6c7bfc9c..877a95d72 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -32,11 +32,8 @@ public IdentityRequest( HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy) { - this.sourcePublisher = sourcePublisher; - this.hashedDiiIdentity = hashedDiiIdentity; - this.optoutCheckPolicy = tokenGeneratePolicy; - this.privacyBits = PrivacyBits.DEFAULT_PRIVACY_BIT_VALUE; - this.establishedAt = Instant.now(); + this(sourcePublisher, hashedDiiIdentity, tokenGeneratePolicy, PrivacyBits.DEFAULT_PRIVACY_BIT_VALUE, Instant.now()); + } public boolean shouldCheckOptOut() { From 5db6e4f29cec6c19ac9e6512df9713a9a5ecdb71 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 13:47:28 +1100 Subject: [PATCH 39/61] Replace privacy bits type to PrivacyBits class instance --- .../operator/model/AdvertisingTokenInput.java | 5 ++- .../uid2/operator/model/IdentityRequest.java | 6 +-- .../operator/model/RefreshTokenInput.java | 5 ++- .../service/EncryptedTokenEncoder.java | 23 ++++++----- .../operator/service/UIDOperatorService.java | 9 ++--- .../com/uid2/operator/util/PrivacyBits.java | 20 +++++++++- .../operator/vertx/UIDOperatorVerticle.java | 4 +- .../com/uid2/operator/TokenEncodingTest.java | 5 ++- .../uid2/operator/UIDOperatorServiceTest.java | 23 ++++++----- .../operator/UIDOperatorVerticleTest.java | 40 +++++++++---------- 10 files changed, 81 insertions(+), 59 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java index a9bcbc11f..0458498e9 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java @@ -3,17 +3,18 @@ import java.time.Instant; import com.uid2.operator.model.userIdentity.RawUidIdentity; +import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.TokenVersion; public class AdvertisingTokenInput extends VersionedToken { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final RawUidIdentity rawUidIdentity; - public final int privacyBits; + public final PrivacyBits privacyBits; public final Instant establishedAt; public AdvertisingTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, int privacyBits, + SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, PrivacyBits privacyBits, Instant establishedAt) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index 877a95d72..84a16c698 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -10,14 +10,14 @@ public final class IdentityRequest { public final HashedDiiIdentity hashedDiiIdentity; public final OptoutCheckPolicy optoutCheckPolicy; - public final int privacyBits; + public final PrivacyBits privacyBits; public final Instant establishedAt; public IdentityRequest( SourcePublisher sourcePublisher, HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy, - int privacyBits, + PrivacyBits privacyBits, Instant establishedAt) { this.sourcePublisher = sourcePublisher; @@ -32,7 +32,7 @@ public IdentityRequest( HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy) { - this(sourcePublisher, hashedDiiIdentity, tokenGeneratePolicy, PrivacyBits.DEFAULT_PRIVACY_BIT_VALUE, Instant.now()); + this(sourcePublisher, hashedDiiIdentity, tokenGeneratePolicy, PrivacyBits.DEFAULT, Instant.now()); } diff --git a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java index 9b45ca3e9..8abcf98bc 100644 --- a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java +++ b/src/main/java/com/uid2/operator/model/RefreshTokenInput.java @@ -3,6 +3,7 @@ import java.time.Instant; import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.TokenVersion; public class RefreshTokenInput extends VersionedToken { @@ -10,11 +11,11 @@ public class RefreshTokenInput extends VersionedToken { public final SourcePublisher sourcePublisher; public final FirstLevelHashIdentity firstLevelHashIdentity; // by default, inherited from the previous refresh token's privacy bits - public final int privacyBits; + public final PrivacyBits privacyBits; public RefreshTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, int privacyBits) { + SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.sourcePublisher = sourcePublisher; diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index c60d3f96a..eb13b485d 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -3,6 +3,7 @@ import com.uid2.operator.model.*; import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; import com.uid2.operator.model.userIdentity.RawUidIdentity; +import com.uid2.operator.util.PrivacyBits; import com.uid2.operator.vertx.ClientInputValidationException; import com.uid2.shared.Const.Data; import com.uid2.shared.encryption.AesCbc; @@ -53,7 +54,7 @@ private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenInput t, KeysetKey m private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer sitePayload = Buffer.buffer(69); encodePublisherRequesterV3(sitePayload, t.sourcePublisher); - sitePayload.appendInt(t.privacyBits); + sitePayload.appendInt(t.privacyBits.getAsInt()); sitePayload.appendLong(t.establishedAt.toEpochMilli()); // this is the refreshedAt field in the spec - but effectively it is the time this advertising token is generated sitePayload.appendLong(t.createdAt.toEpochMilli()); @@ -120,7 +121,7 @@ private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { throw new ClientInputValidationException("Failed to decode refreshTokenV2: Identity segment is not valid base64.", e); } - final int privacyBits = b2.getInt(8 + length); + final PrivacyBits privacyBits = PrivacyBits.fromInt(b2.getInt(8 + length)); final long establishedMillis = b2.getLong(8 + length + 4); return new RefreshTokenInput( @@ -147,7 +148,7 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { final Instant createdAt = Instant.ofEpochMilli(b2.getLong(8)); final OperatorIdentity operatorIdentity = decodeOperatorIdentityV3(b2, 16); final SourcePublisher sourcePublisher = decodeSourcePublisherV3(b2, 29); - final int privacyBits = b2.getInt(45); + final PrivacyBits privacyBits = PrivacyBits.fromInt(b2.getInt(45)); final Instant establishedAt = Instant.ofEpochMilli(b2.getLong(49)); final IdentityScope identityScope = decodeIdentityScopeV3(b2.getByte(57)); final IdentityType identityType = decodeIdentityTypeV3(b2.getByte(57)); @@ -222,7 +223,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { final byte[] rawUid = EncodingUtils.fromBase64(b3.slice(8, 8 + length).getBytes()); - final int privacyBits = b3.getInt(8 + length); + final PrivacyBits privacyBits = PrivacyBits.fromInt(b3.getInt(8 + length)); final long establishedMillis = b3.getLong(8 + length + 4); return new AdvertisingTokenInput( @@ -254,7 +255,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes final Buffer sitePayload = Buffer.buffer(AesGcm.decrypt(masterPayloadBytes, 33, this.keyManager.getKey(siteKeyId))); final SourcePublisher sourcePublisher = decodeSourcePublisherV3(sitePayload, 0); - final int privacyBits = sitePayload.getInt(16); + final PrivacyBits privacyBits = PrivacyBits.fromInt(sitePayload.getInt(16)); final Instant establishedAt = Instant.ofEpochMilli(sitePayload.getLong(20)); // refreshedAt is currently not used final Instant refreshedAt = Instant.ofEpochMilli(sitePayload.getLong(28)); @@ -322,7 +323,7 @@ public byte[] encodeIntoRefreshTokenV3(RefreshTokenInput t, KeysetKey serviceKey refreshPayload.appendLong(t.createdAt.toEpochMilli()); encodeOperatorIdentityV3(refreshPayload, t.operatorIdentity); encodePublisherRequesterV3(refreshPayload, t.sourcePublisher); - refreshPayload.appendInt(t.privacyBits); + refreshPayload.appendInt(t.privacyBits.getAsInt()); refreshPayload.appendLong(t.firstLevelHashIdentity.establishedAt.toEpochMilli()); refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHashIdentity.identityScope, t.firstLevelHashIdentity.identityType)); refreshPayload.appendBytes(t.firstLevelHashIdentity.firstLevelHash); @@ -337,7 +338,7 @@ public byte[] encodeIntoRefreshTokenV3(RefreshTokenInput t, KeysetKey serviceKey } private void encodeSiteIdentityV2(Buffer b, SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, - KeysetKey siteEncryptionKey, int privacyBits, Instant establishedAt) { + KeysetKey siteEncryptionKey, PrivacyBits privacyBits, Instant establishedAt) { b.appendInt(siteEncryptionKey.getId()); final byte[] encryptedIdentity = encryptIdentityV2(sourcePublisher, rawUidIdentity, siteEncryptionKey, privacyBits, establishedAt); b.appendBytes(encryptedIdentity); @@ -372,19 +373,19 @@ private String generateAdvertisingTokenString(AdvertisingTokenInput advertisingT } private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, - KeysetKey key, int privacyBits) { + KeysetKey key, PrivacyBits privacyBits) { return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, privacyBits, firstLevelHashIdentity.establishedAt, key); } private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, - KeysetKey key, int privacyBits, Instant establishedAt) { + KeysetKey key, PrivacyBits privacyBits, Instant establishedAt) { return encryptIdentityV2(sourcePublisher, rawUidIdentity.rawUid, privacyBits, establishedAt, key); } - private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, byte[] id, int privacyBits, + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, byte[] id, PrivacyBits privacyBits, Instant establishedAt, KeysetKey key) { Buffer b = Buffer.buffer(); try { @@ -392,7 +393,7 @@ private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, byte[] id, int final byte[] identityBytes = EncodingUtils.toBase64(id); b.appendInt(identityBytes.length); b.appendBytes(identityBytes); - b.appendInt(privacyBits); + b.appendInt(privacyBits.getAsInt()); b.appendLong(establishedAt.toEpochMilli()); return AesCbc.encrypt(b.getBytes(), key).getPayload(); } catch (Exception e) { diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index b76261f87..d1ac83cb6 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -136,8 +136,7 @@ public RefreshResponse refreshIdentity(RefreshTokenInput token) { return RefreshResponse.Expired; } - final PrivacyBits privacyBits = PrivacyBits.fromInt(token.privacyBits); - final boolean isCstg = privacyBits.isClientSideTokenGenerated(); + final boolean isCstg = token.privacyBits.isClientSideTokenGenerated(); try { final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(token.firstLevelHashIdentity, true); @@ -252,7 +251,7 @@ private RawUidResponse generateRawUid(FirstLevelHashIdentity firstLevelHashIdent } private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, - FirstLevelHashIdentity firstLevelHashIdentity, int privacyBits) { + FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); @@ -272,7 +271,7 @@ private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, Instant now, - int privacyBits) { + PrivacyBits privacyBits) { return new RefreshTokenInput( this.refreshTokenVersion, now, @@ -284,7 +283,7 @@ private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublishe } private AdvertisingTokenInput createAdvertisingTokenInput(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, - Instant now, int privacyBits, Instant establishedAt) { + Instant now, PrivacyBits privacyBits, Instant establishedAt) { TokenVersion tokenVersion; if (siteIdsUsingV4Tokens.contains(sourcePublisher.siteId)) { tokenVersion = TokenVersion.V4; diff --git a/src/main/java/com/uid2/operator/util/PrivacyBits.java b/src/main/java/com/uid2/operator/util/PrivacyBits.java index 11edde226..41e3159ee 100644 --- a/src/main/java/com/uid2/operator/util/PrivacyBits.java +++ b/src/main/java/com/uid2/operator/util/PrivacyBits.java @@ -4,7 +4,7 @@ public class PrivacyBits { // For historical reason this bit is set - public static final int DEFAULT_PRIVACY_BIT_VALUE = 1; + public static final PrivacyBits DEFAULT = PrivacyBits.fromInt(1); private static final int BIT_LEGACY = 0; private static final int BIT_CSTG = 1; @@ -19,6 +19,24 @@ public class PrivacyBits { public PrivacyBits() { } + public PrivacyBits(PrivacyBits pb) { + bits = pb.bits; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !obj.getClass().equals(this.getClass())) { + return false; + } + PrivacyBits other = (PrivacyBits)obj; + return this.bits == other.bits; + } + + @Override + public int hashCode() { + return this.bits; + } + public PrivacyBits(int bits) { this.bits = bits; } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 828dd2c14..b68f4d04b 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -466,7 +466,7 @@ else if(emailHash != null) { new IdentityRequest( new SourcePublisher(clientSideKeypair.getSiteId(), 0, 0), input.toHashedDiiIdentity(this.identityScope), - OptoutCheckPolicy.RespectOptOut, privacyBits.getAsInt(), Instant.now())); + OptoutCheckPolicy.RespectOptOut, privacyBits, Instant.now())); } catch (KeyManager.NoActiveKeyException e){ SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, platformType); return; @@ -1013,7 +1013,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { new IdentityRequest( new SourcePublisher(siteId, 0, 0), optOutTokenInput.toHashedDiiIdentity(this.identityScope), - OptoutCheckPolicy.DoNotRespect, pb.getAsInt(), Instant.now())); + OptoutCheckPolicy.DoNotRespect, pb, Instant.now())); ResponseUtil.SuccessV2(rc, optOutTokens.toJsonV1()); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, optOutTokens.getAdvertisingTokenVersion(), platformType); diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 2057b8891..484caae54 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -6,6 +6,7 @@ import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.TokenUtils; +import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.Const.Data; import com.uid2.shared.model.TokenVersion; import com.uid2.shared.store.CloudPath; @@ -60,7 +61,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, now), - 121 + PrivacyBits.fromInt(121) ); if (tokenVersion == TokenVersion.V4) { @@ -103,7 +104,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid), - 121, + PrivacyBits.fromInt(121), now ); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 4d749f4d7..18b72e24c 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -6,6 +6,7 @@ import com.uid2.operator.model.userIdentity.UserIdentity; import com.uid2.operator.service.*; import com.uid2.operator.store.IOptOutStore; +import com.uid2.operator.util.PrivacyBits; import com.uid2.operator.vertx.OperatorShutdownHandler; import com.uid2.shared.store.CloudPath; import com.uid2.shared.store.RotatingSaltProvider; @@ -149,7 +150,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(siteId, 124, 125), createHashedDiiIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), - OptoutCheckPolicy.DoNotRespect, 0, + OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now.minusSeconds(234) ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); @@ -206,7 +207,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.UID2), - OptoutCheckPolicy.DoNotRespect, 0, this.now + OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); @@ -225,7 +226,7 @@ public void testTestOptOutKey_RespectOptout() { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.UID2), - OptoutCheckPolicy.RespectOptOut, 0, this.now + OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); assertTrue(identityResponse.isOptedOut()); @@ -241,7 +242,7 @@ public void testTestOptOutKeyIdentityScopeMismatch() { final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.EUID), - OptoutCheckPolicy.DoNotRespect, 0, this.now + OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); final IdentityResponse identityResponse = euidService.generateIdentity(identityRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); @@ -266,13 +267,13 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit final IdentityRequest identityRequestForceGenerate = new IdentityRequest( new SourcePublisher(123, 124, 125), hashedDiiIdentity, - OptoutCheckPolicy.DoNotRespect,0, + OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now.minusSeconds(234)); final IdentityRequest identityRequestRespectOptOut = new IdentityRequest( new SourcePublisher(123, 124, 125), hashedDiiIdentity, - OptoutCheckPolicy.RespectOptOut, 0, + OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now.minusSeconds(234)); // the clock value shouldn't matter here @@ -399,7 +400,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), - OptoutCheckPolicy.RespectOptOut, 0, this.now + OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); // identity has no optout record, ensure generate still returns optout @@ -466,7 +467,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), - OptoutCheckPolicy.DoNotRespect, 0, this.now + OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); IdentityResponse identityResponse; @@ -505,7 +506,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), - OptoutCheckPolicy.RespectOptOut, 0, this.now + OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); // identity has optout record, ensure still generates @@ -580,7 +581,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), - OptoutCheckPolicy.RespectOptOut, 0, this.now + OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); // all identities have optout records, ensure validate identities still get generated @@ -709,7 +710,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String final IdentityRequest identityRequest = new IdentityRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), - OptoutCheckPolicy.RespectOptOut, 0, this.now); + OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now); IdentityResponse identityResponse; AdvertisingTokenInput advertisingTokenInput; diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index c0afecbc6..b936bcde7 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1182,8 +1182,8 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi final String token = advertisingTokenString; final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDiiIdentity(getIdentityScope()), now); assertTrue(matchedOptedOutIdentity); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertTrue(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertTrue(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertTokenStatusMetrics( 201, @@ -1229,8 +1229,8 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1271,8 +1271,8 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1315,8 +1315,8 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1374,8 +1374,8 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -1586,8 +1586,8 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -2498,8 +2498,8 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -2537,8 +2537,8 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -2581,8 +2581,8 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenGenerated()); - assertFalse(PrivacyBits.fromInt(advertisingTokenInput.privacyBits).isClientSideTokenOptedOut()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); @@ -4202,8 +4202,8 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisin } private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { - final PrivacyBits advertisingTokenPrivacyBits = PrivacyBits.fromInt(advertisingTokenInput.privacyBits); - final PrivacyBits refreshTokenPrivacyBits = PrivacyBits.fromInt(refreshTokenInput.privacyBits); + final PrivacyBits advertisingTokenPrivacyBits = advertisingTokenInput.privacyBits; + final PrivacyBits refreshTokenPrivacyBits = refreshTokenInput.privacyBits; final byte[] rawUid = getRawUidFromIdentity(identityType, identity, From 741237d8e5b2448c066ffef3f78b97535e8287a2 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 13:56:55 +1100 Subject: [PATCH 40/61] Replace privacy bits type to PrivacyBits class instance --- .../com/uid2/operator/PrivacyBitsTest.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/test/java/com/uid2/operator/PrivacyBitsTest.java diff --git a/src/test/java/com/uid2/operator/PrivacyBitsTest.java b/src/test/java/com/uid2/operator/PrivacyBitsTest.java new file mode 100644 index 000000000..15cea9f9a --- /dev/null +++ b/src/test/java/com/uid2/operator/PrivacyBitsTest.java @@ -0,0 +1,64 @@ +package com.uid2.operator; + +import com.uid2.operator.service.EncodingUtils; +import com.uid2.operator.util.PrivacyBits; +import com.uid2.shared.cloud.EmbeddedResourceStorage; +import com.uid2.shared.store.CloudPath; +import com.uid2.shared.store.reader.RotatingClientKeyProvider; +import com.uid2.shared.store.scope.GlobalScope; +import io.vertx.core.json.JsonObject; +import org.junit.Test; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import static org.junit.Assert.*; + + +public class PrivacyBitsTest { + @Test + public void generateNewClientKeys() throws NoSuchAlgorithmException { + assertEquals(PrivacyBits.DEFAULT.getAsInt(), 1); + PrivacyBits pb1 = new PrivacyBits(); + assertEquals(pb1.getAsInt(), 0); + assertEquals(pb1.hashCode(), 0); + assertNotEquals(pb1, PrivacyBits.fromInt(1)); + assertNotEquals(pb1, PrivacyBits.fromInt(121)); + assertFalse(pb1.isClientSideTokenGenerated()); + assertFalse(pb1.isClientSideTokenOptedOut()); + + pb1.setLegacyBit(); + assertEquals(pb1.getAsInt(), 0b1); + assertEquals(pb1.hashCode(), 0b1); + assertEquals(pb1, PrivacyBits.fromInt(1)); + assertNotEquals(pb1, PrivacyBits.fromInt(121)); + assertFalse(pb1.isClientSideTokenGenerated()); + assertFalse(pb1.isClientSideTokenOptedOut()); + + + pb1.setClientSideTokenGenerate(); + assertEquals(pb1.getAsInt(), 0b11); + assertEquals(pb1.hashCode(), 0b11); + assertEquals(pb1, PrivacyBits.fromInt(3)); + assertNotEquals(pb1, PrivacyBits.fromInt(121)); + assertTrue(pb1.isClientSideTokenGenerated()); + assertFalse(pb1.isClientSideTokenOptedOut()); + + + pb1.setClientSideTokenGenerateOptout(); + assertEquals(pb1.getAsInt(), 0b111); + assertEquals(pb1.hashCode(), 0b111); + assertEquals(pb1, PrivacyBits.fromInt(7)); + assertNotEquals(pb1, PrivacyBits.fromInt(121)); + assertTrue(pb1.isClientSideTokenGenerated()); + assertTrue(pb1.isClientSideTokenOptedOut()); + + PrivacyBits pb2 = new PrivacyBits(pb1); + assertEquals(pb2.getAsInt(), 0b111); + + PrivacyBits pb3 = PrivacyBits.fromInt(0b10110); + assertEquals(pb3.getAsInt(), 0b10110); + pb3.setLegacyBit(); + assertEquals(pb3.getAsInt(), 0b10111); + } +} From 39000173ab7d7d9254e945fe4ba79faaa9cbfade Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 13:57:27 +1100 Subject: [PATCH 41/61] Replace privacy bits type to PrivacyBits class instance --- src/test/java/com/uid2/operator/PrivacyBitsTest.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/test/java/com/uid2/operator/PrivacyBitsTest.java b/src/test/java/com/uid2/operator/PrivacyBitsTest.java index 15cea9f9a..e22ac6845 100644 --- a/src/test/java/com/uid2/operator/PrivacyBitsTest.java +++ b/src/test/java/com/uid2/operator/PrivacyBitsTest.java @@ -1,17 +1,8 @@ package com.uid2.operator; -import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.util.PrivacyBits; -import com.uid2.shared.cloud.EmbeddedResourceStorage; -import com.uid2.shared.store.CloudPath; -import com.uid2.shared.store.reader.RotatingClientKeyProvider; -import com.uid2.shared.store.scope.GlobalScope; -import io.vertx.core.json.JsonObject; import org.junit.Test; - import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - import static org.junit.Assert.*; From e5b104dbfe68a667ba2fca8d63f96e35d71369f0 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 14:49:04 +1100 Subject: [PATCH 42/61] missing a newline --- src/test/java/com/uid2/operator/UIDOperatorServiceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 18b72e24c..223b0625c 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -159,7 +159,8 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertNotNull(identityResponse); UIDOperatorVerticleTest.validateAdvertisingToken(identityResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identityResponse.getAdvertisingToken());assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); + AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identityResponse.getAdvertisingToken()); + assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenInput.sourcePublisher.siteId); assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); assertEquals(identityRequest.establishedAt, advertisingTokenInput.establishedAt); From e25cd19d6446115cbac3714d2288b905b7c531e9 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 16:13:58 +1100 Subject: [PATCH 43/61] 1. Added PrivacyBitsTest/IdentityResponseTest/RawUidResponseTest classes 2. added some extra check for firstLevelHash in existing tests --- .../uid2/operator/UIDOperatorServiceTest.java | 14 +++++- .../utilTests/IdentityResponseTest.java | 48 +++++++++++++++++++ .../{ => utilTests}/PrivacyBitsTest.java | 4 +- .../utilTests/RawUidResponseTest.java | 30 ++++++++++++ 4 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java rename src/test/java/com/uid2/operator/{ => utilTests}/PrivacyBitsTest.java (94%) create mode 100644 src/test/java/com/uid2/operator/utilTests/RawUidResponseTest.java diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 223b0625c..0f2a19714 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -19,6 +19,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + +import static com.uid2.operator.service.TokenUtils.getFirstLevelHash; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.params.ParameterizedTest; @@ -46,7 +48,7 @@ public class UIDOperatorServiceTest { UIDOperatorService uid2Service; UIDOperatorService euidService; Instant now; - + RotatingSaltProvider saltProvider; final int IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS = 600; final int REFRESH_TOKEN_EXPIRES_AFTER_SECONDS = 900; final int REFRESH_IDENTITY_TOKEN_AFTER_SECONDS = 300; @@ -67,7 +69,7 @@ void setup() throws Exception { new GlobalScope(new CloudPath("/com.uid2.core/test/keysets/metadata.json"))); keysetProvider.loadContent(); - RotatingSaltProvider saltProvider = new RotatingSaltProvider( + saltProvider = new RotatingSaltProvider( new EmbeddedResourceStorage(Main.class), "/com.uid2.core/test/salts/metadata.json"); saltProvider.loadContent(); @@ -164,6 +166,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenInput.sourcePublisher.siteId); assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); assertEquals(identityRequest.establishedAt, advertisingTokenInput.establishedAt); + assertEquals(identityRequest.privacyBits, advertisingTokenInput.privacyBits); RefreshTokenInput refreshTokenInput = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); assertEquals(this.now, refreshTokenInput.createdAt); @@ -172,6 +175,11 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, refreshTokenInput.firstLevelHashIdentity); assertEquals(identityRequest.establishedAt, refreshTokenInput.firstLevelHashIdentity.establishedAt); + final byte[] firstLevelHash = getFirstLevelHash(identityRequest.hashedDiiIdentity.hashedDii, + saltProvider.getSnapshot(this.now).getFirstLevelSalt() ); + assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + + setNow(Instant.now().plusSeconds(200)); reset(shutdownHandler); @@ -191,6 +199,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(advertisingTokenInput.establishedAt, advertisingTokenInput2.establishedAt); assertArrayEquals(advertisingTokenInput.rawUidIdentity.rawUid, advertisingTokenInput2.rawUidIdentity.rawUid); + assertEquals(identityRequest.privacyBits, advertisingTokenInput2.privacyBits); RefreshTokenInput refreshTokenInput2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); assertEquals(this.now, refreshTokenInput2.createdAt); @@ -199,6 +208,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertIdentityScopeIdentityType(refreshTokenInput.firstLevelHashIdentity, refreshTokenInput2.firstLevelHashIdentity); assertEquals(refreshTokenInput.firstLevelHashIdentity.establishedAt, refreshTokenInput2.firstLevelHashIdentity.establishedAt); assertArrayEquals(refreshTokenInput.firstLevelHashIdentity.firstLevelHash, refreshTokenInput2.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(firstLevelHash, refreshTokenInput2.firstLevelHashIdentity.firstLevelHash); } @Test diff --git a/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java b/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java new file mode 100644 index 000000000..5a9b4023c --- /dev/null +++ b/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java @@ -0,0 +1,48 @@ +package com.uid2.operator.utilTests; + +import com.uid2.operator.model.IdentityResponse; +import com.uid2.shared.model.TokenVersion; +import io.vertx.core.json.JsonObject; +import org.junit.Test; + +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +import static org.junit.Assert.*; + + +public class IdentityResponseTest { + @Test + public void doIdentityResponseTest() throws NoSuchAlgorithmException { + assertEquals(IdentityResponse.OptOutIdentityResponse.getAdvertisingToken(), ""); + assertTrue(IdentityResponse.OptOutIdentityResponse.isOptedOut()); + + IdentityResponse nullAdTokenValue = new IdentityResponse(null, TokenVersion.V4, "refreshToken", null,null,null); + assertTrue(nullAdTokenValue.isOptedOut()); + + Instant identityExpires = Instant.now(); + Instant refreshFrom = identityExpires.plus(5, ChronoUnit.MINUTES); + Instant refreshExpires = identityExpires.plus(10, ChronoUnit.MINUTES); + IdentityResponse response1 = new IdentityResponse("adToken", TokenVersion.V3, "refreshToken", identityExpires + , refreshExpires, refreshFrom); + + assertEquals(response1.getAdvertisingToken(), "adToken"); + assertEquals(response1.getAdvertisingTokenVersion(), TokenVersion.V3); + assertEquals(response1.getRefreshToken(), "refreshToken"); + assertEquals(response1.getIdentityExpires(), identityExpires); + assertEquals(response1.getRefreshExpires(), refreshExpires); + assertEquals(response1.getRefreshFrom(), refreshFrom); + + JsonObject jsonV1 = response1.toJsonV1(); + assertEquals(jsonV1.getString("advertising_token"), response1.getAdvertisingToken()); + assertEquals(jsonV1.getString("refresh_token"), response1.getRefreshToken()); + assertEquals(jsonV1.getLong("refresh_expires").longValue(), response1.getRefreshExpires().toEpochMilli()); + assertEquals(jsonV1.getLong("refresh_from").longValue(), response1.getRefreshFrom().toEpochMilli()); + + JsonObject jsonV0 = response1.toJsonV0(); + assertEquals(jsonV0.getString("advertisement_token"), response1.getAdvertisingToken()); + assertEquals(jsonV0.getString("advertising_token"), response1.getAdvertisingToken()); + assertEquals(jsonV0.getString("refresh_token"), response1.getRefreshToken()); + } +} diff --git a/src/test/java/com/uid2/operator/PrivacyBitsTest.java b/src/test/java/com/uid2/operator/utilTests/PrivacyBitsTest.java similarity index 94% rename from src/test/java/com/uid2/operator/PrivacyBitsTest.java rename to src/test/java/com/uid2/operator/utilTests/PrivacyBitsTest.java index e22ac6845..91750bf87 100644 --- a/src/test/java/com/uid2/operator/PrivacyBitsTest.java +++ b/src/test/java/com/uid2/operator/utilTests/PrivacyBitsTest.java @@ -1,4 +1,4 @@ -package com.uid2.operator; +package com.uid2.operator.utilTests; import com.uid2.operator.util.PrivacyBits; import org.junit.Test; @@ -8,7 +8,7 @@ public class PrivacyBitsTest { @Test - public void generateNewClientKeys() throws NoSuchAlgorithmException { + public void doPrivacyBitsTest() throws NoSuchAlgorithmException { assertEquals(PrivacyBits.DEFAULT.getAsInt(), 1); PrivacyBits pb1 = new PrivacyBits(); assertEquals(pb1.getAsInt(), 0); diff --git a/src/test/java/com/uid2/operator/utilTests/RawUidResponseTest.java b/src/test/java/com/uid2/operator/utilTests/RawUidResponseTest.java new file mode 100644 index 000000000..4e759b853 --- /dev/null +++ b/src/test/java/com/uid2/operator/utilTests/RawUidResponseTest.java @@ -0,0 +1,30 @@ +package com.uid2.operator.utilTests; + +import com.uid2.operator.model.RawUidResponse; +import org.junit.Test; + +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +import static org.junit.Assert.*; + + +public class RawUidResponseTest { + @Test + public void doRawUidResponseTest() throws NoSuchAlgorithmException { + assertEquals(RawUidResponse.OptoutIdentity.bucketId, ""); + assertTrue(RawUidResponse.OptoutIdentity.isOptedOut()); + + RawUidResponse optoutResponse = new RawUidResponse(new byte[33], null); + assertTrue(optoutResponse.isOptedOut()); + + byte[] rawUid = new byte[33]; + for(int i = 0; i < 33; i++) { + rawUid[i] = (byte) i; + } + + RawUidResponse generatedUid = new RawUidResponse(rawUid, "12345"); + assertFalse(generatedUid.isOptedOut()); + assertTrue(Arrays.equals(rawUid, generatedUid.rawUid)); + } +} From 986cf2e03c816626f876e4a30e162f6b88b4ea20 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 18:01:19 +1100 Subject: [PATCH 44/61] Created verifyFirstLevelHashIdentityAndEstablishedAt method for verifying FirstLevelHashIdentity and added more checks for FirstLevel and check the correctness of raw Uid/First level hash in various unit tests --- .../operator/UIDOperatorVerticleTest.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index b936bcde7..0049a0d7b 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1236,7 +1236,7 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput, body, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1278,7 +1278,7 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput, body, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1303,6 +1303,8 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertNotNull(bodyJson); String genRefreshToken = bodyJson.getString("refresh_token"); + EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -1311,7 +1313,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertEquals("success", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); assertNotNull(refreshBody); - EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); @@ -1323,6 +1325,11 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); + + assertEquals(firstRefreshTokenInput.firstLevelHashIdentity.establishedAt, + refreshTokenInput.firstLevelHashIdentity.establishedAt); + assertTrue(firstRefreshTokenInput.firstLevelHashIdentity.matches(refreshTokenInput.firstLevelHashIdentity)); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); @@ -2504,8 +2511,10 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, + firstLevelSalt), refreshTokenInput, body, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2515,6 +2524,18 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test }); } + void verifyFirstLevelHashIdentityAndEstablishedAt(byte[] expectedFirstLevelHash, + RefreshTokenInput refreshTokenInput, + JsonObject receivedJsonBody, + Instant establishedTime) { + + assertArrayEquals(expectedFirstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + assertEqualsClose(establishedTime, refreshTokenInput.firstLevelHashIdentity.establishedAt, 10); + assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); + assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); + assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); + } + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -2544,7 +2565,7 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput, body, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2590,7 +2611,8 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, + firstLevelSalt), refreshTokenInput, refreshBody, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -4070,7 +4092,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, genBody, identityType); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); - + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenInput, genBody, now); assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_expires")), 10); @@ -4098,6 +4120,8 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenAfterRefreshSource, refreshBody, now); + assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); From f445180b4b471152013fa29050c0110b95f2fa25 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 18:02:16 +1100 Subject: [PATCH 45/61] Created verifyFirstLevelHashIdentityAndEstablishedAt method for verifying FirstLevelHashIdentity and added more checks for FirstLevel and check the correctness of raw Uid/First level hash in various unit tests --- .../uid2/operator/UIDOperatorVerticleTest.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 0049a0d7b..b28655600 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1304,6 +1304,10 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t String genRefreshToken = bodyJson.getString("refresh_token"); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + + AdvertisingTokenInput firstAdvertisingTokenInput = validateAndGetToken(encoder, bodyJson, + IdentityType.Email); + RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -1316,19 +1320,29 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); + + // checks that the raw Uid from raw input, from original tokgen/generate response and the subsequent + // token/refresh response are identical assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertArrayEquals(firstAdvertisingTokenInput.rawUidIdentity.rawUid, + advertisingTokenInput.rawUidIdentity.rawUid); + String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); + // check that first level hash from token/generate's refresh token and token/refresh's refresh token + // are identical assertEquals(firstRefreshTokenInput.firstLevelHashIdentity.establishedAt, refreshTokenInput.firstLevelHashIdentity.establishedAt); assertTrue(firstRefreshTokenInput.firstLevelHashIdentity.matches(refreshTokenInput.firstLevelHashIdentity)); + + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, + firstLevelSalt), refreshTokenInput, refreshBody, now); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); From fa1c0f198ad1305270ff22b7d1e66a296e3fd3f5 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 28 Oct 2024 18:46:04 +1100 Subject: [PATCH 46/61] Checking privacy bits in more tests in UIDOperatorVerticleTest --- .../operator/UIDOperatorVerticleTest.java | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index b28655600..cb30b0ffd 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1228,7 +1228,6 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); @@ -1236,6 +1235,9 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); + + verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput, body, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -1248,6 +1250,12 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test }); } + public void verifyPrivacyBits(PrivacyBits expectedValue, AdvertisingTokenInput advertisingTokenInput, + RefreshTokenInput refreshTokenInput) { + assertEquals(advertisingTokenInput.privacyBits, expectedValue); + assertEquals(advertisingTokenInput.privacyBits, refreshTokenInput.privacyBits); + } + @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext testContext) { @@ -1278,6 +1286,8 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); + + verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput, body, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -1340,7 +1350,10 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertEquals(firstRefreshTokenInput.firstLevelHashIdentity.establishedAt, refreshTokenInput.firstLevelHashIdentity.establishedAt); assertTrue(firstRefreshTokenInput.firstLevelHashIdentity.matches(refreshTokenInput.firstLevelHashIdentity)); - + + verifyPrivacyBits(PrivacyBits.DEFAULT, firstAdvertisingTokenInput, refreshTokenInput); + verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput, refreshBody, now); @@ -2527,6 +2540,7 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); + verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput, body, now); @@ -2579,6 +2593,8 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); + + verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput, body, now); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); @@ -2603,6 +2619,9 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC JsonObject bodyJson = genRespJson.getJsonObject("body"); assertNotNull(bodyJson); + EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + AdvertisingTokenInput firstAdvertisingTokenInput = validateAndGetToken(encoder, bodyJson, + IdentityType.Phone); String genRefreshToken = bodyJson.getString("refresh_token"); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -2612,7 +2631,7 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertEquals("success", refreshRespJson.getString("status")); JsonObject refreshBody = refreshRespJson.getJsonObject("body"); assertNotNull(refreshBody); - EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); + AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); @@ -2625,6 +2644,9 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); + + verifyPrivacyBits(PrivacyBits.DEFAULT, firstAdvertisingTokenInput, refreshTokenInput); + verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput, refreshBody, now); @@ -4106,7 +4128,13 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, genBody, identityType); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); + + PrivacyBits pb = new PrivacyBits(); + pb.setLegacyBit(); + pb.setClientSideTokenGenerate(); + verifyPrivacyBits(pb, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenInput, genBody, now); + assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_expires")), 10); @@ -4134,6 +4162,8 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); + verifyPrivacyBits(pb, adTokenFromRefresh, refreshTokenInput); + verifyPrivacyBits(pb, adTokenFromRefresh, refreshTokenAfterRefreshSource); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenAfterRefreshSource, refreshBody, now); assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, identityType, id); From 20d695c8c72f6da4d1d45d0abab6ee0fe63a2a19 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Tue, 29 Oct 2024 02:02:10 +0000 Subject: [PATCH 47/61] [CI Pipeline] Released Snapshot version: 5.41.1-alpha-116-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4dddd15aa..428f9c4cb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.41.0 + 5.41.1-alpha-116-SNAPSHOT UTF-8 From c950c6d9b1c0426db343e16532b315a6fdab2bdb Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 30 Oct 2024 14:04:37 +1100 Subject: [PATCH 48/61] revered version in pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 428f9c4cb..4dddd15aa 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.41.1-alpha-116-SNAPSHOT + 5.41.0 UTF-8 From a908e1f6b0e8b0f6897d7971051a73737d635b83 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 30 Oct 2024 16:25:45 +1100 Subject: [PATCH 49/61] added some comments and renamed refreshIdentity method param to input instead of oken --- .../uid2/operator/model/IdentityResponse.java | 3 +++ .../userIdentity/FirstLevelHashIdentity.java | 1 + .../service/EncryptedTokenEncoder.java | 1 + .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 20 +++++++++---------- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 8b3ad4a43..45d8b4a59 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -9,9 +9,12 @@ // jsonified public class IdentityResponse { public static IdentityResponse OptOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); + + //aka UID token private final String advertisingToken; private final TokenVersion advertisingTokenVersion; private final String refreshToken; + // when the advertising token/uid token expires private final Instant identityExpires; private final Instant refreshExpires; private final Instant refreshFrom; diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java index b549833ed..4df2b1c6c 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java @@ -21,6 +21,7 @@ public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identity this.establishedAt = establishedAt; } + // explicitly not checking establishedAt - this is only for making sure the first level hash matches a new input public boolean matches(FirstLevelHashIdentity that) { return this.identityScope.equals(that.identityScope) && this.identityType.equals(that.identityType) && diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index eb13b485d..85961981d 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -57,6 +57,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey m sitePayload.appendInt(t.privacyBits.getAsInt()); sitePayload.appendLong(t.establishedAt.toEpochMilli()); // this is the refreshedAt field in the spec - but effectively it is the time this advertising token is generated + // this is a redundant field as it is stored in master payload again, can consider dropping this field in future token version sitePayload.appendLong(t.createdAt.toEpochMilli()); sitePayload.appendBytes(t.rawUidIdentity.rawUid); // 32 or 33 bytes diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 38624848d..dc6671cef 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -14,7 +14,7 @@ public interface IUIDOperatorService { IdentityResponse generateIdentity(IdentityRequest request); - RefreshResponse refreshIdentity(RefreshTokenInput refreshTokenInput); + RefreshResponse refreshIdentity(RefreshTokenInput input); RawUidResponse mapIdentity(MapRequest request); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 2b36b1b3c..f5ba469b9 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -120,34 +120,34 @@ public IdentityResponse generateIdentity(IdentityRequest request) { } @Override - public RefreshResponse refreshIdentity(RefreshTokenInput token) { + public RefreshResponse refreshIdentity(RefreshTokenInput input) { // should not be possible as different scopes should be using different keys, but just in case - if (token.firstLevelHashIdentity.identityScope != this.identityScope) { + if (input.firstLevelHashIdentity.identityScope != this.identityScope) { return RefreshResponse.Invalid; } - if (token.firstLevelHashIdentity.establishedAt.isBefore(RefreshCutoff)) { + if (input.firstLevelHashIdentity.establishedAt.isBefore(RefreshCutoff)) { return RefreshResponse.Deprecated; } final Instant now = clock.instant(); - if (token.expiresAt.isBefore(now)) { + if (input.expiresAt.isBefore(now)) { return RefreshResponse.Expired; } - final boolean isCstg = token.privacyBits.isClientSideTokenGenerated(); + final boolean isCstg = input.privacyBits.isClientSideTokenGenerated(); try { - final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(token.firstLevelHashIdentity, true); + final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(input.firstLevelHashIdentity, true); final boolean optedOut = logoutEntry.isOptedOut(); - final Duration durationSinceLastRefresh = Duration.between(token.createdAt, now); + final Duration durationSinceLastRefresh = Duration.between(input.createdAt, now); if (!optedOut) { - IdentityResponse identityResponse = this.generateIdentity(token.sourcePublisher, - token.firstLevelHashIdentity, - token.privacyBits); + IdentityResponse identityResponse = this.generateIdentity(input.sourcePublisher, + input.firstLevelHashIdentity, + input.privacyBits); return RefreshResponse.createRefreshedResponse(identityResponse, durationSinceLastRefresh, isCstg); } else { From 04dfc147100a71e171829e82ae9fbb182a89f36d Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 30 Oct 2024 17:30:09 +1100 Subject: [PATCH 50/61] fixed unit tests checking establishedAt between advertisingTokenInput & refreshTokenInput's --- .../com/uid2/operator/util/PrivacyBits.java | 3 +++ .../uid2/operator/UIDOperatorServiceTest.java | 4 +--- .../operator/UIDOperatorVerticleTest.java | 24 +++++++++++-------- .../utilTests/IdentityResponseTest.java | 4 +++- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/uid2/operator/util/PrivacyBits.java b/src/main/java/com/uid2/operator/util/PrivacyBits.java index 41e3159ee..0df69d7fd 100644 --- a/src/main/java/com/uid2/operator/util/PrivacyBits.java +++ b/src/main/java/com/uid2/operator/util/PrivacyBits.java @@ -58,6 +58,9 @@ public boolean isClientSideTokenOptedOut() { public void setLegacyBit() { setBit(BIT_LEGACY);//unknown why this bit is set in https://github.com/IABTechLab/uid2-operator/blob/dbab58346e367c9d4122ad541ff9632dc37bd410/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java#L534 } + public boolean isLegacyBitSet() { + return isBitSet(BIT_LEGACY); + } private void setBit(int position) { bits |= (1 << position); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 644ed3d07..794228db8 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -7,7 +7,6 @@ import com.uid2.operator.service.*; import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; -import com.uid2.operator.service.ITokenEncoder; import com.uid2.operator.service.InputUtil; import com.uid2.operator.service.UIDOperatorService; import com.uid2.operator.store.IOptOutStore; @@ -337,7 +336,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit assertNotNull(advertisingTokenInput.rawUidIdentity); assertNotNull(identityResponseAfterOptOut); assertTrue(identityResponseAfterOptOut.getAdvertisingToken() == null || identityResponseAfterOptOut.getAdvertisingToken().isEmpty()); - + assertTrue(identityResponseAfterOptOut.isOptedOut()); } @ParameterizedTest @@ -464,7 +463,6 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, final MapRequest mapRequestRespectOptOut = new MapRequest( inputVal.toHashedDiiIdentity(scope), -// inputVal.toHashedDiiIdentity(scope, 0, this.now), OptoutCheckPolicy.RespectOptOut, now); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index cb30b0ffd..a8bddccfc 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -1238,7 +1238,7 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput, body, now); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1288,7 +1288,7 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput, body, now); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -1320,6 +1320,8 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + assertEquals(firstAdvertisingTokenInput.establishedAt, firstRefreshTokenInput.firstLevelHashIdentity.establishedAt); + when(this.optOutStore.getLatestEntry(any())).thenReturn(null); sendTokenRefresh(apiVersion, vertx, ClientVersionHeader, iosClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> @@ -1355,7 +1357,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, - firstLevelSalt), refreshTokenInput, refreshBody, now); + firstLevelSalt), refreshTokenInput, refreshBody, firstAdvertisingTokenInput.establishedAt); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); @@ -1620,6 +1622,8 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); + assertTrue(advertisingTokenInput.privacyBits.isLegacyBitSet()); + assertEquals(advertisingTokenInput.privacyBits, PrivacyBits.DEFAULT); assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); @@ -2542,7 +2546,7 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, - firstLevelSalt), refreshTokenInput, body, now); + firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2555,10 +2559,10 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test void verifyFirstLevelHashIdentityAndEstablishedAt(byte[] expectedFirstLevelHash, RefreshTokenInput refreshTokenInput, JsonObject receivedJsonBody, - Instant establishedTime) { + Instant expectedEstablishedTime) { assertArrayEquals(expectedFirstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); - assertEqualsClose(establishedTime, refreshTokenInput.firstLevelHashIdentity.establishedAt, 10); + assertEquals(expectedEstablishedTime, refreshTokenInput.firstLevelHashIdentity.establishedAt); assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); @@ -2595,7 +2599,7 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput, body, now); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2648,7 +2652,7 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC verifyPrivacyBits(PrivacyBits.DEFAULT, firstAdvertisingTokenInput, refreshTokenInput); verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, - firstLevelSalt), refreshTokenInput, refreshBody, now); + firstLevelSalt), refreshTokenInput, refreshBody, advertisingTokenInput.establishedAt); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -4133,7 +4137,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id pb.setLegacyBit(); pb.setClientSideTokenGenerate(); verifyPrivacyBits(pb, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenInput, genBody, now); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenInput, genBody, advertisingTokenInput.establishedAt); assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); @@ -4164,7 +4168,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id verifyPrivacyBits(pb, adTokenFromRefresh, refreshTokenInput); verifyPrivacyBits(pb, adTokenFromRefresh, refreshTokenAfterRefreshSource); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenAfterRefreshSource, refreshBody, now); + verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenAfterRefreshSource, refreshBody, advertisingTokenInput.establishedAt); assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); diff --git a/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java b/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java index 5a9b4023c..c8ff6feed 100644 --- a/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java +++ b/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java @@ -24,9 +24,11 @@ public void doIdentityResponseTest() throws NoSuchAlgorithmException { Instant identityExpires = Instant.now(); Instant refreshFrom = identityExpires.plus(5, ChronoUnit.MINUTES); Instant refreshExpires = identityExpires.plus(10, ChronoUnit.MINUTES); + + + IdentityResponse response1 = new IdentityResponse("adToken", TokenVersion.V3, "refreshToken", identityExpires , refreshExpires, refreshFrom); - assertEquals(response1.getAdvertisingToken(), "adToken"); assertEquals(response1.getAdvertisingTokenVersion(), TokenVersion.V3); assertEquals(response1.getRefreshToken(), "refreshToken"); From 2edcb05239c63ca64051a03627d6ae7b868a607b Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 30 Oct 2024 18:19:01 +1100 Subject: [PATCH 51/61] Refactored unit test codes to standardise the advertisingTokenInput/refreshTokenInput verification --- .../operator/UIDOperatorVerticleTest.java | 230 ++++++++++-------- 1 file changed, 125 insertions(+), 105 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index a8bddccfc..98c64b685 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -854,9 +854,6 @@ RefreshTokenInput decodeRefreshToken(EncryptedTokenEncoder encoder, String refre assertEquals(identityType, refreshTokenInput.firstLevelHashIdentity.identityType); return refreshTokenInput; } - RefreshTokenInput decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString) { - return decodeRefreshToken(encoder, refreshTokenString, IdentityType.Email); - } @ParameterizedTest @ValueSource(strings = {"v1", "v2"}) @@ -1228,21 +1225,13 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - - verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); - - assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); - assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); - assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_from")), 10); + assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), + PrivacyBits.DEFAULT, + body, + TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt)); assertStatsCollector("/" + apiVersion + "/token/generate", null, "test-contact", clientSiteId); @@ -1250,6 +1239,21 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test }); } + public void assertAdvertisingTokenRefreshTokenInputs(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, + int expectedClientSiteId, byte[] expectedRawUidIdentity, PrivacyBits expectedPrivacyBits, JsonObject identityResponse, byte[] firstLevelHashIdentity) { + + assertEquals(expectedClientSiteId, advertisingTokenInput.sourcePublisher.siteId); + assertEquals(expectedClientSiteId, refreshTokenInput.sourcePublisher.siteId); + assertArrayEquals(expectedRawUidIdentity, advertisingTokenInput.rawUidIdentity.rawUid); + + verifyPrivacyBits(expectedPrivacyBits, advertisingTokenInput, refreshTokenInput); + verifyFirstLevelHashIdentityAndEstablishedAt(firstLevelHashIdentity, refreshTokenInput, identityResponse, advertisingTokenInput.establishedAt); + + assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("identity_expires")), 10); + assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("refresh_expires")), 10); + assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("refresh_from")), 10); + } + public void verifyPrivacyBits(PrivacyBits expectedValue, AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput) { assertEquals(advertisingTokenInput.privacyBits, expectedValue); @@ -1278,21 +1282,13 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token"), IdentityType.Email); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token")); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - - verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); - - assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); - assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); - assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_from")), 10); + assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), + PrivacyBits.DEFAULT, + body, + TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt)); testContext.completeNow(); }); @@ -1318,12 +1314,23 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingTokenInput firstAdvertisingTokenInput = validateAndGetToken(encoder, bodyJson, IdentityType.Email); - RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); assertEquals(firstAdvertisingTokenInput.establishedAt, firstRefreshTokenInput.firstLevelHashIdentity.establishedAt); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); + + byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()); + byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt); + + assertAdvertisingTokenRefreshTokenInputs(firstAdvertisingTokenInput, firstRefreshTokenInput, clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); + + sendTokenRefresh(apiVersion, vertx, ClientVersionHeader, iosClientVersionHeaderValue, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("success", refreshRespJson.getString("status")); @@ -1332,39 +1339,35 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - - // checks that the raw Uid from raw input, from original tokgen/generate response and the subsequent - // token/refresh response are identical - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - assertArrayEquals(firstAdvertisingTokenInput.rawUidIdentity.rawUid, - advertisingTokenInput.rawUidIdentity.rawUid); - - String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); - - // check that first level hash from token/generate's refresh token and token/refresh's refresh token - // are identical - assertEquals(firstRefreshTokenInput.firstLevelHashIdentity.establishedAt, - refreshTokenInput.firstLevelHashIdentity.establishedAt); - assertTrue(firstRefreshTokenInput.firstLevelHashIdentity.matches(refreshTokenInput.firstLevelHashIdentity)); - - verifyPrivacyBits(PrivacyBits.DEFAULT, firstAdvertisingTokenInput, refreshTokenInput); - verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, - firstLevelSalt), refreshTokenInput, refreshBody, firstAdvertisingTokenInput.establishedAt); - - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); - - assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); - assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); - assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_from")), 10); + // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh + assertAdvertisingTokenRefreshTokenInputs( + advertisingTokenInput, + firstRefreshTokenInput, + clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); + assertAdvertisingTokenRefreshTokenInputs( + firstAdvertisingTokenInput, + refreshTokenInput, + clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); + assertAdvertisingTokenRefreshTokenInputs( + advertisingTokenInput, + refreshTokenInput, + clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); assertTokenStatusMetrics( clientSiteId, @@ -1417,7 +1420,7 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); @@ -1590,7 +1593,7 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); @@ -1629,7 +1632,7 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token")); + RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); @@ -2535,22 +2538,13 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, - firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); - - assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); - assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); - assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_from")), 10); + assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), + PrivacyBits.DEFAULT, + body, + TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt)); testContext.completeNow(); }); @@ -2589,21 +2583,14 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt), refreshTokenInput, body, advertisingTokenInput.establishedAt); + assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), + PrivacyBits.DEFAULT, + body, + TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt)); - assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); - assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); - assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_from")), 10); testContext.completeNow(); }); @@ -2627,9 +2614,19 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC AdvertisingTokenInput firstAdvertisingTokenInput = validateAndGetToken(encoder, bodyJson, IdentityType.Phone); String genRefreshToken = bodyJson.getString("refresh_token"); + RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); + byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()); + byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt); + + assertAdvertisingTokenRefreshTokenInputs(firstAdvertisingTokenInput, firstRefreshTokenInput, clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); + sendTokenRefresh(apiVersion, vertx, testContext, genRefreshToken, bodyJson.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("success", refreshRespJson.getString("status")); @@ -2638,25 +2635,48 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); - - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); - String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - verifyPrivacyBits(PrivacyBits.DEFAULT, firstAdvertisingTokenInput, refreshTokenInput); - verifyPrivacyBits(PrivacyBits.DEFAULT, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(phone, - firstLevelSalt), refreshTokenInput, refreshBody, advertisingTokenInput.establishedAt); + // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh + assertAdvertisingTokenRefreshTokenInputs( + advertisingTokenInput, + firstRefreshTokenInput, + clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); + assertAdvertisingTokenRefreshTokenInputs( + firstAdvertisingTokenInput, + refreshTokenInput, + clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); + assertAdvertisingTokenRefreshTokenInputs( + advertisingTokenInput, + refreshTokenInput, + clientSiteId, + expectedRawUidIdentity, + PrivacyBits.DEFAULT, + bodyJson, + expectedFirstLevelHashIdentity); - assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); - assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); - assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_from")), 10); + assertTokenStatusMetrics( + clientSiteId, + apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.GenerateV1 : TokenResponseStatsCollector.Endpoint.GenerateV2, + TokenResponseStatsCollector.ResponseStatus.Success, + //didn't set any specific header + TokenResponseStatsCollector.PlatformType.Other); + assertTokenStatusMetrics( + clientSiteId, + apiVersion.equals("v1") ? TokenResponseStatsCollector.Endpoint.RefreshV1 : TokenResponseStatsCollector.Endpoint.RefreshV2, + TokenResponseStatsCollector.ResponseStatus.Success, + //didn't set any specific header + TokenResponseStatsCollector.PlatformType.Other); testContext.completeNow(); }); From ca4494553e4599e884a72556288df939485aac15 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Wed, 30 Oct 2024 18:27:16 +1100 Subject: [PATCH 52/61] Refactored unit test codes to standardise the advertisingTokenInput/refreshTokenInput verification --- .../operator/UIDOperatorVerticleTest.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 98c64b685..452b6ecc9 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4153,12 +4153,21 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); - PrivacyBits pb = new PrivacyBits(); - pb.setLegacyBit(); - pb.setClientSideTokenGenerate(); - verifyPrivacyBits(pb, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenInput, genBody, advertisingTokenInput.establishedAt); + + byte[] expectedRawUidIdentity = getRawUidFromIdentity(identityType, id, firstLevelSalt, rotatingSalt123.getSalt()); + byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt); + + PrivacyBits expectedPrivacyBits = new PrivacyBits(); + expectedPrivacyBits.setLegacyBit(); + expectedPrivacyBits.setClientSideTokenGenerate(); + + assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, + clientSideTokenGenerateSiteId, + expectedRawUidIdentity, + expectedPrivacyBits, + genBody, + expectedFirstLevelHashIdentity); assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_expires")), 10); @@ -4186,10 +4195,12 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id assertNotEquals(genRefreshToken, refreshTokenStringNew); RefreshTokenInput refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); - verifyPrivacyBits(pb, adTokenFromRefresh, refreshTokenInput); - verifyPrivacyBits(pb, adTokenFromRefresh, refreshTokenAfterRefreshSource); - verifyFirstLevelHashIdentityAndEstablishedAt(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), refreshTokenAfterRefreshSource, refreshBody, advertisingTokenInput.establishedAt); - + assertAdvertisingTokenRefreshTokenInputs(adTokenFromRefresh, refreshTokenAfterRefreshSource, + clientSideTokenGenerateSiteId, + expectedRawUidIdentity, + expectedPrivacyBits, + genBody, + expectedFirstLevelHashIdentity); assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); From da549b011d1bfdfa864ea72bf5ede0f381af8813 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 4 Nov 2024 12:42:39 +1100 Subject: [PATCH 53/61] Code review feedback --- src/main/java/com/uid2/operator/IdentityConst.java | 2 +- .../java/com/uid2/operator/model/IdentityRequest.java | 6 ++---- .../java/com/uid2/operator/model/IdentityResponse.java | 1 + src/main/java/com/uid2/operator/model/MapRequest.java | 3 +-- .../java/com/uid2/operator/model/RawUidResponse.java | 2 +- .../java/com/uid2/operator/model/SourcePublisher.java | 6 ++++++ .../uid2/operator/model/userIdentity/UserIdentity.java | 4 +--- .../uid2/operator/service/EncryptedTokenEncoder.java | 2 +- .../com/uid2/operator/vertx/UIDOperatorVerticle.java | 10 +++++----- .../com/uid2/operator/benchmark/BenchmarkCommon.java | 2 +- 10 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/uid2/operator/IdentityConst.java b/src/main/java/com/uid2/operator/IdentityConst.java index 9362ade6e..9dad70a0c 100644 --- a/src/main/java/com/uid2/operator/IdentityConst.java +++ b/src/main/java/com/uid2/operator/IdentityConst.java @@ -7,7 +7,7 @@ public class IdentityConst { public static final String OptOutTokenIdentityForEmail = "optout@unifiedid.com"; public static final String OptOutTokenIdentityForPhone = "+00000000001"; - // DIIs for for testing with token/validate endpoint, see https://unifiedid.com/docs/endpoints/post-token-validate + // DIIs for testing with token/validate endpoint, see https://unifiedid.com/docs/endpoints/post-token-validate public static final String ValidateIdentityForEmail = "validate@example.com"; public static final String ValidateIdentityForPhone = "+12345678901"; public static final byte[] ValidateIdentityForEmailHash = EncodingUtils.getSha256Bytes(IdentityConst.ValidateIdentityForEmail); diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/IdentityRequest.java index 84a16c698..c1cca1d75 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityRequest.java @@ -18,8 +18,7 @@ public IdentityRequest( HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy, PrivacyBits privacyBits, - Instant establishedAt) - { + Instant establishedAt) { this.sourcePublisher = sourcePublisher; this.hashedDiiIdentity = hashedDiiIdentity; this.optoutCheckPolicy = tokenGeneratePolicy; @@ -30,8 +29,7 @@ public IdentityRequest( public IdentityRequest( SourcePublisher sourcePublisher, HashedDiiIdentity hashedDiiIdentity, - OptoutCheckPolicy tokenGeneratePolicy) - { + OptoutCheckPolicy tokenGeneratePolicy) { this(sourcePublisher, hashedDiiIdentity, tokenGeneratePolicy, PrivacyBits.DEFAULT, Instant.now()); } diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 45d8b4a59..11e2f4c6e 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -7,6 +7,7 @@ // this defines all the fields for the response of the /token/generate and /client/generate endpoints before they are // jsonified +// todo: can be converted to record later public class IdentityResponse { public static IdentityResponse OptOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); diff --git a/src/main/java/com/uid2/operator/model/MapRequest.java b/src/main/java/com/uid2/operator/model/MapRequest.java index 925296e44..660503041 100644 --- a/src/main/java/com/uid2/operator/model/MapRequest.java +++ b/src/main/java/com/uid2/operator/model/MapRequest.java @@ -12,8 +12,7 @@ public final class MapRequest { public MapRequest( HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy optoutCheckPolicy, - Instant asOf) - { + Instant asOf) { this.hashedDiiIdentity = hashedDiiIdentity; this.optoutCheckPolicy = optoutCheckPolicy; this.asOf = asOf; diff --git a/src/main/java/com/uid2/operator/model/RawUidResponse.java b/src/main/java/com/uid2/operator/model/RawUidResponse.java index 249bef4c5..bbd98931f 100644 --- a/src/main/java/com/uid2/operator/model/RawUidResponse.java +++ b/src/main/java/com/uid2/operator/model/RawUidResponse.java @@ -2,7 +2,7 @@ // Contains the computed raw UID and its bucket ID from identity/map request public class RawUidResponse { - public static RawUidResponse OptoutIdentity = new RawUidResponse(new byte[33], ""); + public static final RawUidResponse OptoutIdentity = new RawUidResponse(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) public final byte[] rawUid; public final String bucketId; diff --git a/src/main/java/com/uid2/operator/model/SourcePublisher.java b/src/main/java/com/uid2/operator/model/SourcePublisher.java index 4f13fd53e..a6b4f49cd 100644 --- a/src/main/java/com/uid2/operator/model/SourcePublisher.java +++ b/src/main/java/com/uid2/operator/model/SourcePublisher.java @@ -11,4 +11,10 @@ public SourcePublisher(int siteId, int clientKeyId, long publisherId) { this.clientKeyId = clientKeyId; this.publisherId = publisherId; } + + public SourcePublisher(int siteId) { + this.siteId = siteId; + this.clientKeyId = 0; + this.publisherId = 0; + } } diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java index 8221a8c61..8b6c042c5 100644 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java @@ -3,9 +3,7 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.IdentityType; -import java.time.Instant; - -//base class for all other HshedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields +//base class for all other HashedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields public abstract class UserIdentity { public final IdentityScope identityScope; diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 85961981d..4dfb36937 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -128,7 +128,7 @@ private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { return new RefreshTokenInput( TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), - new SourcePublisher(siteId, 0, 0), + new SourcePublisher(siteId), new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, identity, Instant.ofEpochMilli(establishedMillis)), privacyBits); diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index dfe2a4dd5..055659924 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -468,7 +468,7 @@ else if(emailHash != null) { try { identityResponse = this.idService.generateIdentity( new IdentityRequest( - new SourcePublisher(clientSideKeypair.getSiteId(), 0, 0), + new SourcePublisher(clientSideKeypair.getSiteId()), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.RespectOptOut, privacyBits, Instant.now())); } catch (KeyManager.NoActiveKeyException e){ @@ -941,7 +941,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { if (isTokenInputValid(input, rc)) { final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( - new SourcePublisher(siteId, 0, 0), + new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.defaultPolicy())); ResponseUtil.Success(rc, t.toJsonV1()); @@ -993,7 +993,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( - new SourcePublisher(siteId, 0, 0), + new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.respectOptOut())); @@ -1009,7 +1009,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { final IdentityResponse optOutTokens = this.idService.generateIdentity( new IdentityRequest( - new SourcePublisher(siteId, 0, 0), + new SourcePublisher(siteId), optOutTokenInput.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.DoNotRespect, pb, Instant.now())); @@ -1049,7 +1049,7 @@ else if (!input.isValid()) { siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); final IdentityResponse t = this.idService.generateIdentity( new IdentityRequest( - new SourcePublisher(siteId, 0, 0), + new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.defaultPolicy())); diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 1c6153d22..c5b062ad8 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -168,7 +168,7 @@ static SourcePublisher createSourcePublisher() throws Exception { for (ClientKey client : clients.getAll()) { if (client.hasRole(Role.GENERATOR)) { - return new SourcePublisher(client.getSiteId(), 0, 0); + return new SourcePublisher(client.getSiteId()); } } throw new IllegalStateException("embedded resource does not include any publisher key"); From c6586a55e3f4226470a3b25269dbbe84c819374c Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 4 Nov 2024 13:13:32 +1100 Subject: [PATCH 54/61] renamed IUIDOperatorService#mapIdentity to mapHashedDiiIdentity --- .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 2 +- .../operator/vertx/UIDOperatorVerticle.java | 2 +- .../uid2/operator/UIDOperatorServiceTest.java | 24 +++++++++---------- .../benchmark/IdentityMapBenchmark.java | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index dc6671cef..5aef54f7a 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -16,7 +16,7 @@ public interface IUIDOperatorService { RefreshResponse refreshIdentity(RefreshTokenInput input); - RawUidResponse mapIdentity(MapRequest request); + RawUidResponse mapHashedDiiIdentity(MapRequest request); @Deprecated RawUidResponse map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index f5ba469b9..965afdb4b 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -161,7 +161,7 @@ public RefreshResponse refreshIdentity(RefreshTokenInput input) { } @Override - public RawUidResponse mapIdentity(MapRequest request) { + public RawUidResponse mapHashedDiiIdentity(MapRequest request) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 055659924..52a4d7e8d 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1450,7 +1450,7 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal for (int i = 0; i < count; ++i) { final InputUtil.InputVal input = inputList[i]; if (input != null && input.isValid()) { - final RawUidResponse rawUidResponse = idService.mapIdentity( + final RawUidResponse rawUidResponse = idService.mapHashedDiiIdentity( new MapRequest( input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.respectOptOut(), diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 794228db8..0a4b56299 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -367,15 +367,15 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide if (scope == IdentityScope.UID2) { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResponse = uid2Service.mapIdentity(mapRequestForceMap); + rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUidResponseShouldBeOptOut = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponseShouldBeOptOut = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); } else { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResponse = euidService.mapIdentity(mapRequestForceMap); + rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestForceMap); reset(shutdownHandler); - rawUidResponseShouldBeOptOut = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponseShouldBeOptOut = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); @@ -471,10 +471,10 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); } else { - rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); @@ -585,10 +585,10 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); } else { - rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); @@ -656,10 +656,10 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i final RawUidResponse rawUidResponse; if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); } else { - rawUidResponse = uid2Service.mapIdentity(mapRequestRespectOptOut); + rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); @@ -775,10 +775,10 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String final RawUidResponse rawUidResponse; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapIdentity(mapRequest); + rawUidResponse = euidService.mapHashedDiiIdentity(mapRequest); } else { - rawUidResponse = uid2Service.mapIdentity(mapRequest); + rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 880875fc0..59b033542 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -32,6 +32,6 @@ public RawUidResponse IdentityMapRawThroughput() { @Benchmark @BenchmarkMode(Mode.Throughput) public RawUidResponse IdentityMapWithOptOutThroughput() { - return uidService.mapIdentity(new MapRequest(hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); + return uidService.mapHashedDiiIdentity(new MapRequest(hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } From d76bceb4ae71f6576038412b96631958bdfb861a Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 4 Nov 2024 13:26:40 +1100 Subject: [PATCH 55/61] renamed to --- .../operator/vertx/UIDOperatorVerticle.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 52a4d7e8d..9cc9d2d05 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -939,13 +939,13 @@ private void handleTokenGenerateV1(RoutingContext rc) { final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc); platformType = getPlatformType(rc); if (isTokenInputValid(input, rc)) { - final IdentityResponse t = this.idService.generateIdentity( + final IdentityResponse response = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.defaultPolicy())); - ResponseUtil.Success(rc, t.toJsonV1()); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), platformType); + ResponseUtil.Success(rc, response.toJsonV1()); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, response.getAdvertisingTokenVersion(), platformType); } } catch (Exception e) { SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token v1", siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, platformType); @@ -991,13 +991,13 @@ private void handleTokenGenerateV2(RoutingContext rc) { return; } - final IdentityResponse t = this.idService.generateIdentity( + final IdentityResponse response = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.respectOptOut())); - if (t.isOptedOut()) { + if (response.isOptedOut()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy final InputUtil.InputVal optOutTokenInput = input.getIdentityType() == IdentityType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) @@ -1020,8 +1020,8 @@ private void handleTokenGenerateV2(RoutingContext rc) { recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.OptOut, siteProvider, null, platformType); } } else { - ResponseUtil.SuccessV2(rc, t.toJsonV1()); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), platformType); + ResponseUtil.SuccessV2(rc, response.toJsonV1()); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV2, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, response.getAdvertisingTokenVersion(), platformType); } } } catch (KeyManager.NoActiveKeyException e) { @@ -1047,14 +1047,14 @@ else if (!input.isValid()) { try { siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); - final IdentityResponse t = this.idService.generateIdentity( + final IdentityResponse response = this.idService.generateIdentity( new IdentityRequest( new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.defaultPolicy())); - recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, t.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Other); - sendJsonResponse(rc, t.toJsonV0()); + recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, response.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Other); + sendJsonResponse(rc, response.toJsonV0()); } catch (Exception e) { SendServerErrorResponseAndRecordStats(rc, "Unknown error while generating token", siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Unknown, siteProvider, e, TokenResponseStatsCollector.PlatformType.Other); From 23a6f50b815c623b9be395103c3af219d24e8478 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 4 Nov 2024 15:59:14 +1100 Subject: [PATCH 56/61] Code review feedback and renamed AdvertisingTOkenInput/RefreshTokenInput to AdvertisingTokenRequest/RefreshTOkenRequest --- ...nput.java => AdvertisingTokenRequest.java} | 9 +- .../uid2/operator/model/RefreshResponse.java | 11 +- ...kenInput.java => RefreshTokenRequest.java} | 7 +- .../service/EncryptedTokenEncoder.java | 54 ++-- .../uid2/operator/service/ITokenEncoder.java | 10 +- .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 24 +- .../operator/store/CloudSyncOptOutStore.java | 4 +- .../operator/vertx/UIDOperatorVerticle.java | 10 +- .../com/uid2/operator/TokenEncodingTest.java | 38 +-- .../uid2/operator/UIDOperatorServiceTest.java | 114 ++++---- .../operator/UIDOperatorVerticleTest.java | 248 +++++++++--------- 12 files changed, 267 insertions(+), 264 deletions(-) rename src/main/java/com/uid2/operator/model/{AdvertisingTokenInput.java => AdvertisingTokenRequest.java} (61%) rename src/main/java/com/uid2/operator/model/{RefreshTokenInput.java => RefreshTokenRequest.java} (66%) diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java similarity index 61% rename from src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java rename to src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java index 0458498e9..226b0e122 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenInput.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java @@ -6,16 +6,17 @@ import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.TokenVersion; -public class AdvertisingTokenInput extends VersionedToken { +// class containing enough data to create a new uid or advertising token +public class AdvertisingTokenRequest extends VersionedToken { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final RawUidIdentity rawUidIdentity; public final PrivacyBits privacyBits; public final Instant establishedAt; - public AdvertisingTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, PrivacyBits privacyBits, - Instant establishedAt) { + public AdvertisingTokenRequest(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, + SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, PrivacyBits privacyBits, + Instant establishedAt) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.sourcePublisher = sourcePublisher; diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/RefreshResponse.java index 2a520fcc4..7fc556b1f 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/RefreshResponse.java @@ -4,11 +4,12 @@ public class RefreshResponse { - public static RefreshResponse Invalid = new RefreshResponse(Status.Invalid, IdentityResponse.OptOutIdentityResponse); - public static RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.OptOutIdentityResponse); - public static RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.OptOutIdentityResponse); - public static RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.OptOutIdentityResponse); - public static RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.OptOutIdentityResponse); + public static final RefreshResponse Invalid = new RefreshResponse(Status.Invalid, + IdentityResponse.OptOutIdentityResponse); + public static final RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.OptOutIdentityResponse); + public static final RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.OptOutIdentityResponse); + public static final RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.OptOutIdentityResponse); + public static final RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.OptOutIdentityResponse); private final Status status; private final IdentityResponse identityResponse; private final Duration durationSinceLastRefresh; diff --git a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java b/src/main/java/com/uid2/operator/model/RefreshTokenRequest.java similarity index 66% rename from src/main/java/com/uid2/operator/model/RefreshTokenInput.java rename to src/main/java/com/uid2/operator/model/RefreshTokenRequest.java index 8abcf98bc..770b6dff5 100644 --- a/src/main/java/com/uid2/operator/model/RefreshTokenInput.java +++ b/src/main/java/com/uid2/operator/model/RefreshTokenRequest.java @@ -6,7 +6,8 @@ import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.TokenVersion; -public class RefreshTokenInput extends VersionedToken { +// class containing enough data to create a new refresh token +public class RefreshTokenRequest extends VersionedToken { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final FirstLevelHashIdentity firstLevelHashIdentity; @@ -14,8 +15,8 @@ public class RefreshTokenInput extends VersionedToken { public final PrivacyBits privacyBits; - public RefreshTokenInput(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { + public RefreshTokenRequest(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, + SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.sourcePublisher = sourcePublisher; diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 4dfb36937..0ca19d803 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -25,7 +25,7 @@ public EncryptedTokenEncoder(KeyManager keyManager) { this.keyManager = keyManager; } - public byte[] encodeIntoAdvertisingToken(AdvertisingTokenInput t, Instant asOf) { + public byte[] encodeIntoAdvertisingToken(AdvertisingTokenRequest t, Instant asOf) { final KeysetKey masterKey = this.keyManager.getMasterKey(asOf); final KeysetKey siteEncryptionKey = this.keyManager.getActiveKeyBySiteIdWithFallback(t.sourcePublisher.siteId, Data.AdvertisingTokenSiteId, asOf); @@ -34,7 +34,7 @@ public byte[] encodeIntoAdvertisingToken(AdvertisingTokenInput t, Instant asOf) : encodeIntoAdvertisingTokenV3(t, masterKey, siteEncryptionKey); //TokenVersion.V4 also calls encodeV3() since the byte array is identical between V3 and V4 } - private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { + private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenRequest t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer b = Buffer.buffer(); b.appendByte((byte) t.version.rawVersion); @@ -51,7 +51,7 @@ private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenInput t, KeysetKey m return b.getBytes(); } - private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey masterKey, KeysetKey siteKey) { + private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenRequest t, KeysetKey masterKey, KeysetKey siteKey) { final Buffer sitePayload = Buffer.buffer(69); encodePublisherRequesterV3(sitePayload, t.sourcePublisher); sitePayload.appendInt(t.privacyBits.getAsInt()); @@ -78,7 +78,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenInput t, KeysetKey m } @Override - public RefreshTokenInput decodeRefreshToken(String s) { + public RefreshTokenRequest decodeRefreshToken(String s) { if (s != null && !s.isEmpty()) { final byte[] bytes; try { @@ -97,7 +97,7 @@ public RefreshTokenInput decodeRefreshToken(String s) { throw new ClientInputValidationException("Invalid refresh token version"); } - private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { + private RefreshTokenRequest decodeRefreshTokenV2(Buffer b) { final Instant createdAt = Instant.ofEpochMilli(b.getLong(1)); //final Instant expiresAt = Instant.ofEpochMilli(b.getLong(9)); final Instant validTill = Instant.ofEpochMilli(b.getLong(17)); @@ -125,7 +125,7 @@ private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { final PrivacyBits privacyBits = PrivacyBits.fromInt(b2.getInt(8 + length)); final long establishedMillis = b2.getLong(8 + length + 4); - return new RefreshTokenInput( + return new RefreshTokenRequest( TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), new SourcePublisher(siteId), @@ -134,7 +134,7 @@ private RefreshTokenInput decodeRefreshTokenV2(Buffer b) { privacyBits); } - private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { + private RefreshTokenRequest decodeRefreshTokenV3(Buffer b, byte[] bytes) { final int keyId = b.getInt(2); final KeysetKey key = this.keyManager.getKey(keyId); @@ -162,14 +162,14 @@ private RefreshTokenInput decodeRefreshTokenV3(Buffer b, byte[] bytes) { throw new ClientInputValidationException("Failed to decode refreshTokenV3: Identity type mismatch"); } - return new RefreshTokenInput( + return new RefreshTokenRequest( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, establishedAt), privacyBits); } @Override - public AdvertisingTokenInput decodeAdvertisingToken(String base64AdvertisingToken) { + public AdvertisingTokenRequest decodeAdvertisingToken(String base64AdvertisingToken) { //Logic and code copied from: https://github.com/IABTechLab/uid2-client-java/blob/0220ef43c1661ecf3b8f4ed2db524e2db31c06b5/src/main/java/com/uid2/client/Uid2Encryption.java#L37 if (base64AdvertisingToken.length() < 4) { throw new ClientInputValidationException("Advertising token is too short"); @@ -204,7 +204,7 @@ public AdvertisingTokenInput decodeAdvertisingToken(String base64AdvertisingToke return decodeAdvertisingTokenV3orV4(b, bytes, tokenVersion); } - public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { + public AdvertisingTokenRequest decodeAdvertisingTokenV2(Buffer b) { try { final int masterKeyId = b.getInt(1); @@ -227,7 +227,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { final PrivacyBits privacyBits = PrivacyBits.fromInt(b3.getInt(8 + length)); final long establishedMillis = b3.getLong(8 + length + 4); - return new AdvertisingTokenInput( + return new AdvertisingTokenRequest( TokenVersion.V2, Instant.ofEpochMilli(establishedMillis), Instant.ofEpochMilli(expiresMillis), @@ -244,7 +244,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV2(Buffer b) { } - public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, TokenVersion tokenVersion) { + public AdvertisingTokenRequest decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, TokenVersion tokenVersion) { final int masterKeyId = b.getInt(2); final byte[] masterPayloadBytes = AesGcm.decrypt(bytes, 6, this.keyManager.getKey(masterKeyId)); @@ -274,7 +274,7 @@ public AdvertisingTokenInput decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes } } - return new AdvertisingTokenInput( + return new AdvertisingTokenRequest( tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, new RawUidIdentity(identityScope, identityType, rawUid), privacyBits, establishedAt @@ -289,7 +289,7 @@ private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVer .register(Metrics.globalRegistry).increment(); } - public byte[] encodeIntoRefreshToken(RefreshTokenInput t, Instant asOf) { + public byte[] encodeIntoRefreshToken(RefreshTokenRequest t, Instant asOf) { final KeysetKey serviceKey = this.keyManager.getRefreshKey(asOf); switch (t.version) { @@ -304,7 +304,7 @@ public byte[] encodeIntoRefreshToken(RefreshTokenInput t, Instant asOf) { } } - public byte[] encodeIntoRefreshTokenV2(RefreshTokenInput t, KeysetKey serviceKey) { + public byte[] encodeIntoRefreshTokenV2(RefreshTokenRequest t, KeysetKey serviceKey) { final Buffer b = Buffer.buffer(); b.appendByte((byte) t.version.rawVersion); b.appendLong(t.createdAt.toEpochMilli()); @@ -318,7 +318,7 @@ public byte[] encodeIntoRefreshTokenV2(RefreshTokenInput t, KeysetKey serviceKey return b.getBytes(); } - public byte[] encodeIntoRefreshTokenV3(RefreshTokenInput t, KeysetKey serviceKey) { + public byte[] encodeIntoRefreshTokenV3(RefreshTokenRequest t, KeysetKey serviceKey) { final Buffer refreshPayload = Buffer.buffer(90); refreshPayload.appendLong(t.expiresAt.toEpochMilli()); refreshPayload.appendLong(t.createdAt.toEpochMilli()); @@ -351,26 +351,26 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi } @Override - public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf) { - final String advertisingToken = generateAdvertisingTokenString(advertisingTokenInput, asOf); - final String refreshToken = generateRefreshTokenString(refreshTokenInput, asOf); + public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, Instant refreshFrom, Instant asOf) { + final String advertisingToken = generateAdvertisingTokenString(advertisingTokenRequest, asOf); + final String refreshToken = generateRefreshTokenString(refreshTokenRequest, asOf); return new IdentityResponse( advertisingToken, - advertisingTokenInput.version, + advertisingTokenRequest.version, refreshToken, - advertisingTokenInput.expiresAt, - refreshTokenInput.expiresAt, + advertisingTokenRequest.expiresAt, + refreshTokenRequest.expiresAt, refreshFrom ); } - private String generateRefreshTokenString(RefreshTokenInput refreshTokenInput, Instant asOf) { - return EncodingUtils.toBase64String(encodeIntoRefreshToken(refreshTokenInput, asOf)); + private String generateRefreshTokenString(RefreshTokenRequest refreshTokenRequest, Instant asOf) { + return EncodingUtils.toBase64String(encodeIntoRefreshToken(refreshTokenRequest, asOf)); } - private String generateAdvertisingTokenString(AdvertisingTokenInput advertisingTokenInput, Instant asOf) { - final byte[] advertisingTokenBytes = encodeIntoAdvertisingToken(advertisingTokenInput, asOf); - return bytesToBase64Token(advertisingTokenBytes, advertisingTokenInput.version); + private String generateAdvertisingTokenString(AdvertisingTokenRequest advertisingTokenRequest, Instant asOf) { + final byte[] advertisingTokenBytes = encodeIntoAdvertisingToken(advertisingTokenRequest, asOf); + return bytesToBase64Token(advertisingTokenBytes, advertisingTokenRequest.version); } private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, diff --git a/src/main/java/com/uid2/operator/service/ITokenEncoder.java b/src/main/java/com/uid2/operator/service/ITokenEncoder.java index 9380dc8c2..cac7994ae 100644 --- a/src/main/java/com/uid2/operator/service/ITokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/ITokenEncoder.java @@ -1,15 +1,15 @@ package com.uid2.operator.service; -import com.uid2.operator.model.AdvertisingTokenInput; +import com.uid2.operator.model.AdvertisingTokenRequest; import com.uid2.operator.model.IdentityResponse; -import com.uid2.operator.model.RefreshTokenInput; +import com.uid2.operator.model.RefreshTokenRequest; import java.time.Instant; public interface ITokenEncoder { - IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, Instant refreshFrom, Instant asOf); + IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, Instant refreshFrom, Instant asOf); - AdvertisingTokenInput decodeAdvertisingToken(String base64String); + AdvertisingTokenRequest decodeAdvertisingToken(String base64String); - RefreshTokenInput decodeRefreshToken(String base64String); + RefreshTokenRequest decodeRefreshToken(String base64String); } diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 5aef54f7a..eacb244a2 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -14,7 +14,7 @@ public interface IUIDOperatorService { IdentityResponse generateIdentity(IdentityRequest request); - RefreshResponse refreshIdentity(RefreshTokenInput input); + RefreshResponse refreshIdentity(RefreshTokenRequest input); RawUidResponse mapHashedDiiIdentity(MapRequest request); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 965afdb4b..9f0e36975 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -120,7 +120,7 @@ public IdentityResponse generateIdentity(IdentityRequest request) { } @Override - public RefreshResponse refreshIdentity(RefreshTokenInput input) { + public RefreshResponse refreshIdentity(RefreshTokenRequest input) { // should not be possible as different scopes should be using different keys, but just in case if (input.firstLevelHashIdentity.identityScope != this.identityScope) { return RefreshResponse.Invalid; @@ -211,7 +211,7 @@ public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentit final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, asOf); - final AdvertisingTokenInput token = this.encoder.decodeAdvertisingToken(advertisingToken); + final AdvertisingTokenRequest token = this.encoder.decodeAdvertisingToken(advertisingToken); return Arrays.equals(rawUidResponse.rawUid, token.rawUidIdentity.rawUid); } @@ -260,19 +260,19 @@ private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, rawUidResponse.rawUid); return this.encoder.encodeIntoIdentityResponse( - this.createAdvertisingTokenInput(sourcePublisher, rawUidIdentity, nowUtc, privacyBits, + this.createAdvertisingTokenRequest(sourcePublisher, rawUidIdentity, nowUtc, privacyBits, firstLevelHashIdentity.establishedAt), - this.createRefreshTokenInput(sourcePublisher, firstLevelHashIdentity, nowUtc, privacyBits), + this.createRefreshTokenRequest(sourcePublisher, firstLevelHashIdentity, nowUtc, privacyBits), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc ); } - private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublisher, - FirstLevelHashIdentity firstLevelHashIdentity, - Instant now, - PrivacyBits privacyBits) { - return new RefreshTokenInput( + private RefreshTokenRequest createRefreshTokenRequest(SourcePublisher sourcePublisher, + FirstLevelHashIdentity firstLevelHashIdentity, + Instant now, + PrivacyBits privacyBits) { + return new RefreshTokenRequest( this.refreshTokenVersion, now, now.plusMillis(refreshExpiresAfter.toMillis()), @@ -282,8 +282,8 @@ private RefreshTokenInput createRefreshTokenInput(SourcePublisher sourcePublishe privacyBits); } - private AdvertisingTokenInput createAdvertisingTokenInput(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, - Instant now, PrivacyBits privacyBits, Instant establishedAt) { + private AdvertisingTokenRequest createAdvertisingTokenRequest(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, + Instant now, PrivacyBits privacyBits, Instant establishedAt) { TokenVersion tokenVersion; if (siteIdsUsingV4Tokens.contains(sourcePublisher.siteId)) { tokenVersion = TokenVersion.V4; @@ -297,7 +297,7 @@ private AdvertisingTokenInput createAdvertisingTokenInput(SourcePublisher source } tokenVersion = (pseudoRandomNumber <= this.advertisingTokenV4Percentage) ? TokenVersion.V4 : this.tokenVersionToUseIfNotV4; } - return new AdvertisingTokenInput(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, sourcePublisher, rawUidIdentity, + return new AdvertisingTokenRequest(tokenVersion, now, now.plusMillis(identityExpiresAfter.toMillis()), this.operatorIdentity, sourcePublisher, rawUidIdentity, privacyBits, establishedAt); } diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index bff6f4f9b..de52a6c75 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -92,8 +92,8 @@ public void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] adver return; } - this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath). - addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.firstLevelHash)) + this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath) + .addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.firstLevelHash)) .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) // advertising id aka raw UID .putHeader("Authorization", remoteApiBearerToken) .as(BodyCodec.string()) diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 9cc9d2d05..83c6e5ce8 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1765,25 +1765,25 @@ private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVer } private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { - final RefreshTokenInput refreshTokenInput; + final RefreshTokenRequest refreshTokenRequest; try { if (AuthMiddleware.isAuthenticated(rc)) { rc.put(Const.RoutingContextData.SiteId, AuthMiddleware.getAuthClient(ClientKey.class, rc).getSiteId()); } - refreshTokenInput = this.encoder.decodeRefreshToken(tokenStr); + refreshTokenRequest = this.encoder.decodeRefreshToken(tokenStr); } catch (ClientInputValidationException cie) { LOGGER.warn("Failed to decode refresh token for site ID: " + rc.data().get(Const.RoutingContextData.SiteId), cie); return RefreshResponse.Invalid; } - if (refreshTokenInput == null) { + if (refreshTokenRequest == null) { return RefreshResponse.Invalid; } if (!AuthMiddleware.isAuthenticated(rc)) { - rc.put(Const.RoutingContextData.SiteId, refreshTokenInput.sourcePublisher.siteId); + rc.put(Const.RoutingContextData.SiteId, refreshTokenRequest.sourcePublisher.siteId); } recordRefreshTokenVersionCount(String.valueOf(rc.data().get(Const.RoutingContextData.SiteId)), this.getRefreshTokenVersion(tokenStr)); - return this.idService.refreshIdentity(refreshTokenInput); + return this.idService.refreshIdentity(refreshTokenRequest); } public static String getSiteName(ISiteStore siteStore, Integer siteId) { diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 484caae54..4affea1f0 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -55,7 +55,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity("test@example.com", "some-salt"); - final RefreshTokenInput refreshTokenInput = new RefreshTokenInput(tokenVersion, + final RefreshTokenRequest refreshTokenRequest = new RefreshTokenRequest(tokenVersion, now, now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), @@ -65,20 +65,20 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { ); if (tokenVersion == TokenVersion.V4) { - Assert.assertThrows(Exception.class, () -> encoder.encodeIntoRefreshToken(refreshTokenInput, now)); + Assert.assertThrows(Exception.class, () -> encoder.encodeIntoRefreshToken(refreshTokenRequest, now)); return; //V4 not supported for RefreshTokens } - final byte[] encodedBytes = encoder.encodeIntoRefreshToken(refreshTokenInput, now); - final RefreshTokenInput decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); + final byte[] encodedBytes = encoder.encodeIntoRefreshToken(refreshTokenRequest, now); + final RefreshTokenRequest decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); assertEquals(tokenVersion, decoded.version); - assertEquals(refreshTokenInput.createdAt, decoded.createdAt); + assertEquals(refreshTokenRequest.createdAt, decoded.createdAt); int addSeconds = (tokenVersion == TokenVersion.V2) ? 60 : 0; //todo: why is there a 60 second buffer in encodeV2() but not in encodeV3()? - assertEquals(refreshTokenInput.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); - assertTrue(refreshTokenInput.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); - assertEquals(refreshTokenInput.privacyBits, decoded.privacyBits); - assertEquals(refreshTokenInput.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); - assertEquals(refreshTokenInput.sourcePublisher.siteId, decoded.sourcePublisher.siteId); + assertEquals(refreshTokenRequest.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); + assertTrue(refreshTokenRequest.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); + assertEquals(refreshTokenRequest.privacyBits, decoded.privacyBits); + assertEquals(refreshTokenRequest.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); + assertEquals(refreshTokenRequest.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 25 : 2); @@ -97,7 +97,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { final byte[] rawUid = UIDOperatorVerticleTest.getRawUid(IdentityType.Email, "test@example.com", IdentityScope.UID2, tokenVersion != TokenVersion.V2); - final AdvertisingTokenInput adTokenInput = new AdvertisingTokenInput( + final AdvertisingTokenRequest adTokenRequest = new AdvertisingTokenRequest( tokenVersion, now, now.plusSeconds(60), @@ -108,16 +108,16 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { now ); - final byte[] encodedBytes = encoder.encodeIntoAdvertisingToken(adTokenInput, now); - final AdvertisingTokenInput decoded = encoder.decodeAdvertisingToken(EncryptedTokenEncoder.bytesToBase64Token(encodedBytes, tokenVersion)); + final byte[] encodedBytes = encoder.encodeIntoAdvertisingToken(adTokenRequest, now); + final AdvertisingTokenRequest decoded = encoder.decodeAdvertisingToken(EncryptedTokenEncoder.bytesToBase64Token(encodedBytes, tokenVersion)); assertEquals(tokenVersion, decoded.version); - assertEquals(adTokenInput.createdAt, decoded.createdAt); - assertEquals(adTokenInput.expiresAt, decoded.expiresAt); - assertTrue(adTokenInput.rawUidIdentity.matches(decoded.rawUidIdentity)); - assertEquals(adTokenInput.privacyBits, decoded.privacyBits); - assertEquals(adTokenInput.establishedAt, decoded.establishedAt); - assertEquals(adTokenInput.sourcePublisher.siteId, decoded.sourcePublisher.siteId); + assertEquals(adTokenRequest.createdAt, decoded.createdAt); + assertEquals(adTokenRequest.expiresAt, decoded.expiresAt); + assertTrue(adTokenRequest.rawUidIdentity.matches(decoded.rawUidIdentity)); + assertEquals(adTokenRequest.privacyBits, decoded.privacyBits); + assertEquals(adTokenRequest.establishedAt, decoded.establishedAt); + assertEquals(adTokenRequest.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 1 : 2); //TODO - extract master key from token should be a helper function diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 0a4b56299..741050dcd 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -154,7 +154,7 @@ private HashedDiiIdentity createHashedDiiIdentity(String rawIdentityHash, Identi ); } - private AdvertisingTokenInput validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, IdentityType type, int siteId) { + private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, IdentityType type, int siteId) { TokenVersion tokenVersion = (scope == IdentityScope.UID2) ? uid2Service.getAdvertisingTokenVersionForTests(siteId) : euidService.getAdvertisingTokenVersionForTests(siteId); UIDOperatorVerticleTest.validateAdvertisingToken(advertisingTokenString, tokenVersion, scope, type); return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); @@ -181,29 +181,29 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertNotNull(identityResponse); UIDOperatorVerticleTest.validateAdvertisingToken(identityResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingTokenInput advertisingTokenInput = tokenEncoder.decodeAdvertisingToken(identityResponse.getAdvertisingToken()); - assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput.expiresAt); - assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenInput.sourcePublisher.siteId); - assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, advertisingTokenInput.rawUidIdentity); - assertEquals(identityRequest.establishedAt, advertisingTokenInput.establishedAt); - assertEquals(identityRequest.privacyBits, advertisingTokenInput.privacyBits); - - RefreshTokenInput refreshTokenInput = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); - assertEquals(this.now, refreshTokenInput.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput.expiresAt); - assertEquals(identityRequest.sourcePublisher.siteId, refreshTokenInput.sourcePublisher.siteId); - assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, refreshTokenInput.firstLevelHashIdentity); - assertEquals(identityRequest.establishedAt, refreshTokenInput.firstLevelHashIdentity.establishedAt); + AdvertisingTokenRequest advertisingTokenRequest = tokenEncoder.decodeAdvertisingToken(identityResponse.getAdvertisingToken()); + assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenRequest.expiresAt); + assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenRequest.sourcePublisher.siteId); + assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, advertisingTokenRequest.rawUidIdentity); + assertEquals(identityRequest.establishedAt, advertisingTokenRequest.establishedAt); + assertEquals(identityRequest.privacyBits, advertisingTokenRequest.privacyBits); + + RefreshTokenRequest refreshTokenRequest = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + assertEquals(this.now, refreshTokenRequest.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenRequest.expiresAt); + assertEquals(identityRequest.sourcePublisher.siteId, refreshTokenRequest.sourcePublisher.siteId); + assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, refreshTokenRequest.firstLevelHashIdentity); + assertEquals(identityRequest.establishedAt, refreshTokenRequest.firstLevelHashIdentity.establishedAt); final byte[] firstLevelHash = getFirstLevelHash(identityRequest.hashedDiiIdentity.hashedDii, saltProvider.getSnapshot(this.now).getFirstLevelSalt() ); - assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(firstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); setNow(Instant.now().plusSeconds(200)); reset(shutdownHandler); - final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshTokenInput); + final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshTokenRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(refreshResponse); @@ -211,24 +211,24 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertNotNull(refreshResponse.getIdentityResponse()); UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingTokenInput advertisingTokenInput2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken()); - assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenInput2.expiresAt); - assertEquals(advertisingTokenInput.sourcePublisher.siteId, advertisingTokenInput2.sourcePublisher.siteId); - assertIdentityScopeIdentityType(advertisingTokenInput.rawUidIdentity, - advertisingTokenInput2.rawUidIdentity); - assertEquals(advertisingTokenInput.establishedAt, advertisingTokenInput2.establishedAt); - assertArrayEquals(advertisingTokenInput.rawUidIdentity.rawUid, - advertisingTokenInput2.rawUidIdentity.rawUid); - assertEquals(identityRequest.privacyBits, advertisingTokenInput2.privacyBits); - - RefreshTokenInput refreshTokenInput2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); - assertEquals(this.now, refreshTokenInput2.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenInput2.expiresAt); - assertEquals(refreshTokenInput.sourcePublisher.siteId, refreshTokenInput2.sourcePublisher.siteId); - assertIdentityScopeIdentityType(refreshTokenInput.firstLevelHashIdentity, refreshTokenInput2.firstLevelHashIdentity); - assertEquals(refreshTokenInput.firstLevelHashIdentity.establishedAt, refreshTokenInput2.firstLevelHashIdentity.establishedAt); - assertArrayEquals(refreshTokenInput.firstLevelHashIdentity.firstLevelHash, refreshTokenInput2.firstLevelHashIdentity.firstLevelHash); - assertArrayEquals(firstLevelHash, refreshTokenInput2.firstLevelHashIdentity.firstLevelHash); + AdvertisingTokenRequest advertisingTokenRequest2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken()); + assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenRequest2.expiresAt); + assertEquals(advertisingTokenRequest.sourcePublisher.siteId, advertisingTokenRequest2.sourcePublisher.siteId); + assertIdentityScopeIdentityType(advertisingTokenRequest.rawUidIdentity, + advertisingTokenRequest2.rawUidIdentity); + assertEquals(advertisingTokenRequest.establishedAt, advertisingTokenRequest2.establishedAt); + assertArrayEquals(advertisingTokenRequest.rawUidIdentity.rawUid, + advertisingTokenRequest2.rawUidIdentity.rawUid); + assertEquals(identityRequest.privacyBits, advertisingTokenRequest2.privacyBits); + + RefreshTokenRequest refreshTokenRequest2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); + assertEquals(this.now, refreshTokenRequest2.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenRequest2.expiresAt); + assertEquals(refreshTokenRequest.sourcePublisher.siteId, refreshTokenRequest2.sourcePublisher.siteId); + assertIdentityScopeIdentityType(refreshTokenRequest.firstLevelHashIdentity, refreshTokenRequest2.firstLevelHashIdentity); + assertEquals(refreshTokenRequest.firstLevelHashIdentity.establishedAt, refreshTokenRequest2.firstLevelHashIdentity.establishedAt); + assertArrayEquals(refreshTokenRequest.firstLevelHashIdentity.firstLevelHash, refreshTokenRequest2.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(firstLevelHash, refreshTokenRequest2.firstLevelHashIdentity.firstLevelHash); } @Test @@ -246,8 +246,8 @@ public void testTestOptOutKey_DoNotRespectOptout() { assertNotNull(identityResponse); assertFalse(identityResponse.isOptedOut()); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); - assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenInput)); + final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenRequest)); } @Test @@ -280,9 +280,9 @@ public void testTestOptOutKeyIdentityScopeMismatch() { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshTokenInput)); + assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshTokenRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -312,13 +312,13 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); final IdentityResponse identityResponse; - final AdvertisingTokenInput advertisingTokenInput; + final AdvertisingTokenRequest advertisingTokenRequest; final IdentityResponse identityResponseAfterOptOut; if (scope == IdentityScope.UID2) { identityResponse = uid2Service.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); identityResponseAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); @@ -326,14 +326,14 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit identityResponse = euidService.generateIdentity(identityRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); identityResponseAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotNull(advertisingTokenInput.rawUidIdentity); + assertNotNull(advertisingTokenRequest.rawUidIdentity); assertNotNull(identityResponseAfterOptOut); assertTrue(identityResponseAfterOptOut.getAdvertisingToken() == null || identityResponseAfterOptOut.getAdvertisingToken().isEmpty()); assertTrue(identityResponseAfterOptOut.isOptedOut()); @@ -515,9 +515,9 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput)); + assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -557,9 +557,9 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput)); + assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -618,19 +618,19 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); IdentityResponse identityResponse; - AdvertisingTokenInput advertisingTokenInput; + AdvertisingTokenRequest advertisingTokenRequest; if (scope == IdentityScope.EUID) { identityResponse = euidService.generateIdentity(identityRequest); } else { identityResponse = uid2Service.generateIdentity(identityRequest); } - advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); - assertNotNull(advertisingTokenInput.rawUidIdentity); + assertNotNull(advertisingTokenRequest.rawUidIdentity); } @@ -693,8 +693,8 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop assertNotEquals(identityResponse, IdentityResponse.OptOutIdentityResponse); assertNotNull(identityResponse); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); - RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput); + final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest); assertTrue(refreshResponse.isRefreshed()); assertNotNull(refreshResponse.getIdentityResponse()); assertNotEquals(RefreshResponse.Optout, refreshResponse); @@ -743,25 +743,25 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now); IdentityResponse identityResponse; - AdvertisingTokenInput advertisingTokenInput; + AdvertisingTokenRequest advertisingTokenRequest; reset(shutdownHandler); if(scope == IdentityScope.EUID) { identityResponse = euidService.generateIdentity(identityRequest); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); } else { identityResponse = uid2Service.generateIdentity(identityRequest); - advertisingTokenInput = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(identityResponse); assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); - assertNotNull(advertisingTokenInput.rawUidIdentity); + assertNotNull(advertisingTokenRequest.rawUidIdentity); - final RefreshTokenInput refreshTokenInput = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenInput); + RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertTrue(refreshResponse.isRefreshed()); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 452b6ecc9..6ceeca9be 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -813,14 +813,14 @@ private void assertStatsCollector(String path, String referer, String apiContact assertEquals(siteId, messageItem.getSiteId()); } - private AdvertisingTokenInput validateAndGetToken(EncryptedTokenEncoder encoder, JsonObject body, IdentityType identityType) { //See UID2-79+Token+and+ID+format+v3 + private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder encoder, JsonObject body, IdentityType identityType) { //See UID2-79+Token+and+ID+format+v3 final String advertisingTokenString = body.getString("advertising_token"); validateAdvertisingToken(advertisingTokenString, getTokenVersion(), getIdentityScope(), identityType); - AdvertisingTokenInput advertisingTokenInput = encoder.decodeAdvertisingToken(advertisingTokenString); + AdvertisingTokenRequest advertisingTokenRequest = encoder.decodeAdvertisingToken(advertisingTokenString); if (getTokenVersion() == TokenVersion.V4) { - assertEquals(identityType, advertisingTokenInput.rawUidIdentity.identityType); + assertEquals(identityType, advertisingTokenRequest.rawUidIdentity.identityType); } - return advertisingTokenInput; + return advertisingTokenRequest; } public static void validateAdvertisingToken(String advertisingTokenString, TokenVersion tokenVersion, IdentityScope identityScope, IdentityType identityType) { @@ -848,11 +848,11 @@ public static void validateAdvertisingToken(String advertisingTokenString, Token } } - RefreshTokenInput decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { - RefreshTokenInput refreshTokenInput = encoder.decodeRefreshToken(refreshTokenString); - assertEquals(getIdentityScope(), refreshTokenInput.firstLevelHashIdentity.identityScope); - assertEquals(identityType, refreshTokenInput.firstLevelHashIdentity.identityType); - return refreshTokenInput; + RefreshTokenRequest decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { + RefreshTokenRequest refreshTokenRequest = encoder.decodeRefreshToken(refreshTokenString); + assertEquals(getIdentityScope(), refreshTokenRequest.firstLevelHashIdentity.identityScope); + assertEquals(identityType, refreshTokenRequest.firstLevelHashIdentity.identityType); + return refreshTokenRequest; } @ParameterizedTest @@ -1164,23 +1164,23 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, identityType); - RefreshTokenInput refreshTokenInput = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, identityType); + RefreshTokenRequest refreshTokenRequest = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); final byte[] rawUid = getRawUidFromIdentity(identityType, optOutTokenInput.getNormalized(), firstLevelSalt, rotatingSalt123.getSalt()); final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity(optOutTokenInput.getNormalized(), firstLevelSalt); - assertArrayEquals(rawUid, advertisingTokenInput.rawUidIdentity.rawUid); - assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(rawUid, advertisingTokenRequest.rawUidIdentity.rawUid); + assertArrayEquals(firstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); String advertisingTokenString = body.getString("advertising_token"); final Instant now = Instant.now(); final String token = advertisingTokenString; final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDiiIdentity(getIdentityScope()), now); assertTrue(matchedOptedOutIdentity); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertTrue(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); + assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); + assertTrue(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); assertTokenStatusMetrics( 201, @@ -1224,10 +1224,10 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -1239,25 +1239,25 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test }); } - public void assertAdvertisingTokenRefreshTokenInputs(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, - int expectedClientSiteId, byte[] expectedRawUidIdentity, PrivacyBits expectedPrivacyBits, JsonObject identityResponse, byte[] firstLevelHashIdentity) { + public void assertAdvertisingTokenRefreshTokenRequests(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, + int expectedClientSiteId, byte[] expectedRawUidIdentity, PrivacyBits expectedPrivacyBits, JsonObject identityResponse, byte[] firstLevelHashIdentity) { - assertEquals(expectedClientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertEquals(expectedClientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(expectedRawUidIdentity, advertisingTokenInput.rawUidIdentity.rawUid); + assertEquals(expectedClientSiteId, advertisingTokenRequest.sourcePublisher.siteId); + assertEquals(expectedClientSiteId, refreshTokenRequest.sourcePublisher.siteId); + assertArrayEquals(expectedRawUidIdentity, advertisingTokenRequest.rawUidIdentity.rawUid); - verifyPrivacyBits(expectedPrivacyBits, advertisingTokenInput, refreshTokenInput); - verifyFirstLevelHashIdentityAndEstablishedAt(firstLevelHashIdentity, refreshTokenInput, identityResponse, advertisingTokenInput.establishedAt); + verifyPrivacyBits(expectedPrivacyBits, advertisingTokenRequest, refreshTokenRequest); + verifyFirstLevelHashIdentityAndEstablishedAt(firstLevelHashIdentity, refreshTokenRequest, identityResponse, advertisingTokenRequest.establishedAt); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("refresh_expires")), 10); assertEqualsClose(now.plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("refresh_from")), 10); } - public void verifyPrivacyBits(PrivacyBits expectedValue, AdvertisingTokenInput advertisingTokenInput, - RefreshTokenInput refreshTokenInput) { - assertEquals(advertisingTokenInput.privacyBits, expectedValue); - assertEquals(advertisingTokenInput.privacyBits, refreshTokenInput.privacyBits); + public void verifyPrivacyBits(PrivacyBits expectedValue, AdvertisingTokenRequest advertisingTokenRequest, + RefreshTokenRequest refreshTokenRequest) { + assertEquals(advertisingTokenRequest.privacyBits, expectedValue); + assertEquals(advertisingTokenRequest.privacyBits, refreshTokenRequest.privacyBits); } @ParameterizedTest @@ -1281,10 +1281,10 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token"), IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token"), IdentityType.Email); - assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -1311,12 +1311,12 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t String genRefreshToken = bodyJson.getString("refresh_token"); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput firstAdvertisingTokenInput = validateAndGetToken(encoder, bodyJson, + AdvertisingTokenRequest firstAdvertisingTokenRequest = validateAndGetToken(encoder, bodyJson, IdentityType.Email); - RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + RefreshTokenRequest firstRefreshTokenRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertEquals(firstAdvertisingTokenInput.establishedAt, firstRefreshTokenInput.firstLevelHashIdentity.establishedAt); + assertEquals(firstAdvertisingTokenRequest.establishedAt, firstRefreshTokenRequest.firstLevelHashIdentity.establishedAt); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -1324,7 +1324,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()); byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt); - assertAdvertisingTokenRefreshTokenInputs(firstAdvertisingTokenInput, firstRefreshTokenInput, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstRefreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, @@ -1338,31 +1338,31 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertNotNull(refreshBody); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Email); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh - assertAdvertisingTokenRefreshTokenInputs( - advertisingTokenInput, - firstRefreshTokenInput, + assertAdvertisingTokenRefreshTokenRequests( + advertisingTokenRequest, + firstRefreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, expectedFirstLevelHashIdentity); - assertAdvertisingTokenRefreshTokenInputs( - firstAdvertisingTokenInput, - refreshTokenInput, + assertAdvertisingTokenRefreshTokenRequests( + firstAdvertisingTokenRequest, + refreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, expectedFirstLevelHashIdentity); - assertAdvertisingTokenRefreshTokenInputs( - advertisingTokenInput, - refreshTokenInput, + assertAdvertisingTokenRefreshTokenRequests( + advertisingTokenRequest, + refreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -1411,18 +1411,18 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT assertNotNull(refreshBody); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Email); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); + assertEquals(clientSiteId, refreshTokenRequest.sourcePublisher.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -1589,13 +1589,13 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); + assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + assertEquals(clientSiteId, refreshTokenRequest.sourcePublisher.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); testContext.completeNow(); }); @@ -1623,18 +1623,18 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); - assertTrue(advertisingTokenInput.privacyBits.isLegacyBitSet()); - assertEquals(advertisingTokenInput.privacyBits, PrivacyBits.DEFAULT); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenGenerated()); - assertFalse(advertisingTokenInput.privacyBits.isClientSideTokenOptedOut()); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenInput.rawUidIdentity.rawUid); + assertTrue(advertisingTokenRequest.privacyBits.isLegacyBitSet()); + assertEquals(advertisingTokenRequest.privacyBits, PrivacyBits.DEFAULT); + assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); + assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); + assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertEquals(clientSiteId, refreshTokenInput.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenInput.firstLevelHashIdentity.firstLevelHash); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + assertEquals(clientSiteId, refreshTokenRequest.sourcePublisher.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2537,10 +2537,10 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Phone); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -2551,15 +2551,15 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test } void verifyFirstLevelHashIdentityAndEstablishedAt(byte[] expectedFirstLevelHash, - RefreshTokenInput refreshTokenInput, + RefreshTokenRequest refreshTokenRequest, JsonObject receivedJsonBody, Instant expectedEstablishedTime) { - assertArrayEquals(expectedFirstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash); - assertEquals(expectedEstablishedTime, refreshTokenInput.firstLevelHashIdentity.establishedAt); - assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); - assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); - assertTrue(refreshTokenInput.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); + assertArrayEquals(expectedFirstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); + assertEquals(expectedEstablishedTime, refreshTokenRequest.firstLevelHashIdentity.establishedAt); + assertTrue(refreshTokenRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); + assertTrue(refreshTokenRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); + assertTrue(refreshTokenRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); } @ParameterizedTest @@ -2582,10 +2582,10 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Phone); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Phone); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -2611,17 +2611,17 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertNotNull(bodyJson); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput firstAdvertisingTokenInput = validateAndGetToken(encoder, bodyJson, + AdvertisingTokenRequest firstAdvertisingTokenRequest = validateAndGetToken(encoder, bodyJson, IdentityType.Phone); String genRefreshToken = bodyJson.getString("refresh_token"); - RefreshTokenInput firstRefreshTokenInput = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + RefreshTokenRequest firstRefreshTokenRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()); byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt); - assertAdvertisingTokenRefreshTokenInputs(firstAdvertisingTokenInput, firstRefreshTokenInput, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstRefreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, @@ -2634,31 +2634,31 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertNotNull(refreshBody); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh - assertAdvertisingTokenRefreshTokenInputs( - advertisingTokenInput, - firstRefreshTokenInput, + assertAdvertisingTokenRefreshTokenRequests( + advertisingTokenRequest, + firstRefreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, expectedFirstLevelHashIdentity); - assertAdvertisingTokenRefreshTokenInputs( - firstAdvertisingTokenInput, - refreshTokenInput, + assertAdvertisingTokenRefreshTokenRequests( + firstAdvertisingTokenRequest, + refreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, expectedFirstLevelHashIdentity); - assertAdvertisingTokenRefreshTokenInputs( - advertisingTokenInput, - refreshTokenInput, + assertAdvertisingTokenRefreshTokenRequests( + advertisingTokenRequest, + refreshTokenRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -4085,14 +4085,14 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver assertEquals("success", response.getString("status")); final JsonObject genBody = response.getJsonObject("body"); - final AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, genBody, identityType); - final RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); + final AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, identityType); + final RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); - assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenRequest, refreshTokenRequest, clientSideTokenGenerateSiteId, identityType, id); // When we refresh the token the user has opted out. when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) - .thenReturn(advertisingTokenInput.establishedAt.plusSeconds(1)); + .thenReturn(advertisingTokenRequest.establishedAt.plusSeconds(1)); sendTokenRefresh("v2", vertx, testContext, genBody.getString("refresh_token"), genBody.getString("refresh_response_key"), 200, refreshRespJson -> { assertEquals("optout", refreshRespJson.getString("status")); @@ -4149,9 +4149,9 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id decodeV2RefreshToken(respJson); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, genBody, identityType); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, identityType); - RefreshTokenInput refreshTokenInput = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); + RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); @@ -4162,13 +4162,13 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id expectedPrivacyBits.setLegacyBit(); expectedPrivacyBits.setClientSideTokenGenerate(); - assertAdvertisingTokenRefreshTokenInputs(advertisingTokenInput, refreshTokenInput, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSideTokenGenerateSiteId, expectedRawUidIdentity, expectedPrivacyBits, genBody, expectedFirstLevelHashIdentity); - assertAreClientSideGeneratedTokens(advertisingTokenInput, refreshTokenInput, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenRequest, refreshTokenRequest, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_from")), 10); @@ -4189,13 +4189,13 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id EncryptedTokenEncoder encoder2 = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); //make sure the new advertising token from refresh looks right - AdvertisingTokenInput adTokenFromRefresh = validateAndGetToken(encoder2, refreshBody, identityType); + AdvertisingTokenRequest adTokenFromRefresh = validateAndGetToken(encoder2, refreshBody, identityType); String refreshTokenStringNew = refreshBody.getString("decrypted_refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenInput refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); + RefreshTokenRequest refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); - assertAdvertisingTokenRefreshTokenInputs(adTokenFromRefresh, refreshTokenAfterRefreshSource, + assertAdvertisingTokenRefreshTokenRequests(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, expectedRawUidIdentity, expectedPrivacyBits, @@ -4295,18 +4295,18 @@ void cstgInvalidInput(String identityType, String rawUID, Vertx vertx, VertxTest }); } - private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, int siteId, IdentityType identityType, String identity) { - assertAreClientSideGeneratedTokens(advertisingTokenInput, - refreshTokenInput, + private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, int siteId, IdentityType identityType, String identity) { + assertAreClientSideGeneratedTokens(advertisingTokenRequest, + refreshTokenRequest, siteId, identityType, identity, false); } - private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisingTokenInput, RefreshTokenInput refreshTokenInput, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { - final PrivacyBits advertisingTokenPrivacyBits = advertisingTokenInput.privacyBits; - final PrivacyBits refreshTokenPrivacyBits = refreshTokenInput.privacyBits; + private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { + final PrivacyBits advertisingTokenPrivacyBits = advertisingTokenRequest.privacyBits; + final PrivacyBits refreshTokenPrivacyBits = refreshTokenRequest.privacyBits; final byte[] rawUid = getRawUidFromIdentity(identityType, identity, @@ -4322,11 +4322,11 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenInput advertisin () -> assertTrue(refreshTokenPrivacyBits.isClientSideTokenGenerated(), "Refresh token privacy bits CSTG flag is incorrect"), () -> assertEquals(expectedOptOut, refreshTokenPrivacyBits.isClientSideTokenOptedOut(), "Refresh token privacy bits CSTG optout flag is incorrect"), - () -> assertEquals(siteId, advertisingTokenInput.sourcePublisher.siteId, "Advertising token site ID is incorrect"), - () -> assertEquals(siteId, refreshTokenInput.sourcePublisher.siteId, "Refresh token site ID is incorrect"), + () -> assertEquals(siteId, advertisingTokenRequest.sourcePublisher.siteId, "Advertising token site ID is incorrect"), + () -> assertEquals(siteId, refreshTokenRequest.sourcePublisher.siteId, "Refresh token site ID is incorrect"), - () -> assertArrayEquals(rawUid, advertisingTokenInput.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), - () -> assertArrayEquals(firstLevelHash, refreshTokenInput.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") + () -> assertArrayEquals(rawUid, advertisingTokenRequest.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), + () -> assertArrayEquals(firstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") ); } @@ -4556,16 +4556,16 @@ void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTe assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenInput advertisingTokenInput = validateAndGetToken(encoder, body, IdentityType.Email); - assertEquals(clientSiteId, advertisingTokenInput.sourcePublisher.siteId); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); + assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); //Uses a key from default keyset int clientKeyId; - if (advertisingTokenInput.version == TokenVersion.V3 || advertisingTokenInput.version == TokenVersion.V4) { + if (advertisingTokenRequest.version == TokenVersion.V3 || advertisingTokenRequest.version == TokenVersion.V4) { String advertisingTokenString = body.getString("advertising_token"); byte[] bytes = null; - if (advertisingTokenInput.version == TokenVersion.V3) { + if (advertisingTokenRequest.version == TokenVersion.V3) { bytes = EncodingUtils.fromBase64(advertisingTokenString); - } else if (advertisingTokenInput.version == TokenVersion.V4) { + } else if (advertisingTokenRequest.version == TokenVersion.V4) { bytes = Uid2Base64UrlCoder.decode(advertisingTokenString); //same as V3 but use Base64URL encoding } final Buffer b = Buffer.buffer(bytes); @@ -4575,7 +4575,7 @@ void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTe final Buffer masterPayload = Buffer.buffer(masterPayloadBytes); clientKeyId = masterPayload.getInt(29); } else { - clientKeyId = advertisingTokenInput.sourcePublisher.clientKeyId; + clientKeyId = advertisingTokenRequest.sourcePublisher.clientKeyId; } switch (testRun) { case "MultiKeysets": From a002ad1b0374fa76c663bd8ec0b0810d15626433 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Thu, 5 Dec 2024 13:20:55 +1100 Subject: [PATCH 57/61] Code review feedback, Mainly renaming RefreshTokenRequest/RefreshResponse to TokenRefreshRequest/TokenRefreshResponse --- .../java/com/uid2/operator/IdentityConst.java | 2 +- .../model/AdvertisingTokenRequest.java | 4 +- .../uid2/operator/model/IdentityResponse.java | 2 +- .../uid2/operator/model/SourcePublisher.java | 4 + ...nRequest.java => TokenRefreshRequest.java} | 4 +- ...esponse.java => TokenRefreshResponse.java} | 24 ++-- ...dToken.java => VersionedTokenRequest.java} | 6 +- .../TokenResponseStatsCollector.java | 4 +- .../service/EncryptedTokenEncoder.java | 26 ++-- .../uid2/operator/service/ITokenEncoder.java | 6 +- .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 24 ++-- .../operator/vertx/UIDOperatorVerticle.java | 22 ++-- .../com/uid2/operator/TokenEncodingTest.java | 20 +-- .../uid2/operator/UIDOperatorServiceTest.java | 74 +++++------ .../operator/UIDOperatorVerticleTest.java | 122 +++++++++--------- .../benchmark/TokenEndecBenchmark.java | 3 +- .../utilTests/IdentityResponseTest.java | 4 +- 18 files changed, 178 insertions(+), 175 deletions(-) rename src/main/java/com/uid2/operator/model/{RefreshTokenRequest.java => TokenRefreshRequest.java} (88%) rename src/main/java/com/uid2/operator/model/{RefreshResponse.java => TokenRefreshResponse.java} (55%) rename src/main/java/com/uid2/operator/model/{VersionedToken.java => VersionedTokenRequest.java} (68%) diff --git a/src/main/java/com/uid2/operator/IdentityConst.java b/src/main/java/com/uid2/operator/IdentityConst.java index 9dad70a0c..402a99d88 100644 --- a/src/main/java/com/uid2/operator/IdentityConst.java +++ b/src/main/java/com/uid2/operator/IdentityConst.java @@ -13,7 +13,7 @@ public class IdentityConst { public static final byte[] ValidateIdentityForEmailHash = EncodingUtils.getSha256Bytes(IdentityConst.ValidateIdentityForEmail); public static final byte[] ValidateIdentityForPhoneHash = EncodingUtils.getSha256Bytes(IdentityConst.ValidateIdentityForPhone); - // DIIs to use when you want to generate a optout response in token generation or identity map + // DIIs to use when you want to generate an optout response in token generation or identity map public static final String OptOutIdentityForEmail = "optout@example.com"; public static final String OptOutIdentityForPhone = "+00000000000"; diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java index 226b0e122..f9a41caf6 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java @@ -6,8 +6,8 @@ import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.TokenVersion; -// class containing enough data to create a new uid or advertising token -public class AdvertisingTokenRequest extends VersionedToken { +// class containing enough information to create a new uid token (aka advertising token) +public class AdvertisingTokenRequest extends VersionedTokenRequest { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final RawUidIdentity rawUidIdentity; diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/IdentityResponse.java index 11e2f4c6e..746294064 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityResponse.java @@ -9,7 +9,7 @@ // jsonified // todo: can be converted to record later public class IdentityResponse { - public static IdentityResponse OptOutIdentityResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); + public static final IdentityResponse OptOutResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); //aka UID token private final String advertisingToken; diff --git a/src/main/java/com/uid2/operator/model/SourcePublisher.java b/src/main/java/com/uid2/operator/model/SourcePublisher.java index a6b4f49cd..bd19740a1 100644 --- a/src/main/java/com/uid2/operator/model/SourcePublisher.java +++ b/src/main/java/com/uid2/operator/model/SourcePublisher.java @@ -3,6 +3,10 @@ // The original publisher that requests to generate a UID token public class SourcePublisher { public final int siteId; + + // these 2 values are added into adverting/UID token and refresh token payload but + // are not really used for any real purposes currently so sometimes are set to 0 + // see the constructor below public final int clientKeyId; public final long publisherId; diff --git a/src/main/java/com/uid2/operator/model/RefreshTokenRequest.java b/src/main/java/com/uid2/operator/model/TokenRefreshRequest.java similarity index 88% rename from src/main/java/com/uid2/operator/model/RefreshTokenRequest.java rename to src/main/java/com/uid2/operator/model/TokenRefreshRequest.java index 770b6dff5..f5cc8b6eb 100644 --- a/src/main/java/com/uid2/operator/model/RefreshTokenRequest.java +++ b/src/main/java/com/uid2/operator/model/TokenRefreshRequest.java @@ -7,7 +7,7 @@ import com.uid2.shared.model.TokenVersion; // class containing enough data to create a new refresh token -public class RefreshTokenRequest extends VersionedToken { +public class TokenRefreshRequest extends VersionedTokenRequest { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; public final FirstLevelHashIdentity firstLevelHashIdentity; @@ -15,7 +15,7 @@ public class RefreshTokenRequest extends VersionedToken { public final PrivacyBits privacyBits; - public RefreshTokenRequest(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, + public TokenRefreshRequest(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; diff --git a/src/main/java/com/uid2/operator/model/RefreshResponse.java b/src/main/java/com/uid2/operator/model/TokenRefreshResponse.java similarity index 55% rename from src/main/java/com/uid2/operator/model/RefreshResponse.java rename to src/main/java/com/uid2/operator/model/TokenRefreshResponse.java index 7fc556b1f..5a52fa571 100644 --- a/src/main/java/com/uid2/operator/model/RefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/TokenRefreshResponse.java @@ -2,32 +2,32 @@ import java.time.Duration; -public class RefreshResponse { - - public static final RefreshResponse Invalid = new RefreshResponse(Status.Invalid, - IdentityResponse.OptOutIdentityResponse); - public static final RefreshResponse Optout = new RefreshResponse(Status.Optout, IdentityResponse.OptOutIdentityResponse); - public static final RefreshResponse Expired = new RefreshResponse(Status.Expired, IdentityResponse.OptOutIdentityResponse); - public static final RefreshResponse Deprecated = new RefreshResponse(Status.Deprecated, IdentityResponse.OptOutIdentityResponse); - public static final RefreshResponse NoActiveKey = new RefreshResponse(Status.NoActiveKey, IdentityResponse.OptOutIdentityResponse); +public class TokenRefreshResponse { + + public static final TokenRefreshResponse Invalid = new TokenRefreshResponse(Status.Invalid, + IdentityResponse.OptOutResponse); + public static final TokenRefreshResponse Optout = new TokenRefreshResponse(Status.Optout, IdentityResponse.OptOutResponse); + public static final TokenRefreshResponse Expired = new TokenRefreshResponse(Status.Expired, IdentityResponse.OptOutResponse); + public static final TokenRefreshResponse Deprecated = new TokenRefreshResponse(Status.Deprecated, IdentityResponse.OptOutResponse); + public static final TokenRefreshResponse NoActiveKey = new TokenRefreshResponse(Status.NoActiveKey, IdentityResponse.OptOutResponse); private final Status status; private final IdentityResponse identityResponse; private final Duration durationSinceLastRefresh; private final boolean isCstg; - private RefreshResponse(Status status, IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { + private TokenRefreshResponse(Status status, IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { this.status = status; this.identityResponse = identityResponse; this.durationSinceLastRefresh = durationSinceLastRefresh; this.isCstg = isCstg; } - private RefreshResponse(Status status, IdentityResponse identityResponse) { + private TokenRefreshResponse(Status status, IdentityResponse identityResponse) { this(status, identityResponse, null, false); } - public static RefreshResponse createRefreshedResponse(IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { - return new RefreshResponse(Status.Refreshed, identityResponse, durationSinceLastRefresh, isCstg); + public static TokenRefreshResponse createRefreshedResponse(IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { + return new TokenRefreshResponse(Status.Refreshed, identityResponse, durationSinceLastRefresh, isCstg); } public Status getStatus() { diff --git a/src/main/java/com/uid2/operator/model/VersionedToken.java b/src/main/java/com/uid2/operator/model/VersionedTokenRequest.java similarity index 68% rename from src/main/java/com/uid2/operator/model/VersionedToken.java rename to src/main/java/com/uid2/operator/model/VersionedTokenRequest.java index 5be86b80e..5cc9c5335 100644 --- a/src/main/java/com/uid2/operator/model/VersionedToken.java +++ b/src/main/java/com/uid2/operator/model/VersionedTokenRequest.java @@ -1,16 +1,16 @@ package com.uid2.operator.model; import java.time.Instant; -import java.util.Objects; + import com.uid2.shared.model.TokenVersion; -public abstract class VersionedToken { +public abstract class VersionedTokenRequest { public final TokenVersion version; public final Instant createdAt; public final Instant expiresAt; - public VersionedToken(TokenVersion version, Instant createdAt, Instant expiresAt) { + public VersionedTokenRequest(TokenVersion version, Instant createdAt, Instant expiresAt) { this.version = version; this.createdAt = createdAt; this.expiresAt = expiresAt; diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index fc28bba70..c5f46cc7e 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -1,6 +1,6 @@ package com.uid2.operator.monitoring; -import com.uid2.operator.model.RefreshResponse; +import com.uid2.operator.model.TokenRefreshResponse; import com.uid2.operator.vertx.UIDOperatorVerticle; import com.uid2.shared.model.TokenVersion; import com.uid2.shared.store.ISiteStore; @@ -69,7 +69,7 @@ private static void recordInternal(ISiteStore siteStore, Integer siteId, Endpoin builder.register(Metrics.globalRegistry).increment(); } - public static void recordRefresh(ISiteStore siteStore, Integer siteId, Endpoint endpoint, RefreshResponse refreshResponse, PlatformType platformType) { + public static void recordRefresh(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenRefreshResponse refreshResponse, PlatformType platformType) { if (!refreshResponse.isRefreshed()) { if (refreshResponse.isOptOut() || refreshResponse.isDeprecated()) { recordInternal(siteStore, siteId, endpoint, ResponseStatus.OptOut, refreshResponse.getIdentityResponse().getAdvertisingTokenVersion(), refreshResponse.isCstg(), platformType); diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 0ca19d803..26d019795 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -78,7 +78,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenRequest t, KeysetKey } @Override - public RefreshTokenRequest decodeRefreshToken(String s) { + public TokenRefreshRequest decodeRefreshToken(String s) { if (s != null && !s.isEmpty()) { final byte[] bytes; try { @@ -97,7 +97,7 @@ public RefreshTokenRequest decodeRefreshToken(String s) { throw new ClientInputValidationException("Invalid refresh token version"); } - private RefreshTokenRequest decodeRefreshTokenV2(Buffer b) { + private TokenRefreshRequest decodeRefreshTokenV2(Buffer b) { final Instant createdAt = Instant.ofEpochMilli(b.getLong(1)); //final Instant expiresAt = Instant.ofEpochMilli(b.getLong(9)); final Instant validTill = Instant.ofEpochMilli(b.getLong(17)); @@ -125,7 +125,7 @@ private RefreshTokenRequest decodeRefreshTokenV2(Buffer b) { final PrivacyBits privacyBits = PrivacyBits.fromInt(b2.getInt(8 + length)); final long establishedMillis = b2.getLong(8 + length + 4); - return new RefreshTokenRequest( + return new TokenRefreshRequest( TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), new SourcePublisher(siteId), @@ -134,7 +134,7 @@ private RefreshTokenRequest decodeRefreshTokenV2(Buffer b) { privacyBits); } - private RefreshTokenRequest decodeRefreshTokenV3(Buffer b, byte[] bytes) { + private TokenRefreshRequest decodeRefreshTokenV3(Buffer b, byte[] bytes) { final int keyId = b.getInt(2); final KeysetKey key = this.keyManager.getKey(keyId); @@ -162,7 +162,7 @@ private RefreshTokenRequest decodeRefreshTokenV3(Buffer b, byte[] bytes) { throw new ClientInputValidationException("Failed to decode refreshTokenV3: Identity type mismatch"); } - return new RefreshTokenRequest( + return new TokenRefreshRequest( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, establishedAt), privacyBits); @@ -289,7 +289,7 @@ private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVer .register(Metrics.globalRegistry).increment(); } - public byte[] encodeIntoRefreshToken(RefreshTokenRequest t, Instant asOf) { + public byte[] encodeIntoRefreshToken(TokenRefreshRequest t, Instant asOf) { final KeysetKey serviceKey = this.keyManager.getRefreshKey(asOf); switch (t.version) { @@ -304,7 +304,7 @@ public byte[] encodeIntoRefreshToken(RefreshTokenRequest t, Instant asOf) { } } - public byte[] encodeIntoRefreshTokenV2(RefreshTokenRequest t, KeysetKey serviceKey) { + public byte[] encodeIntoRefreshTokenV2(TokenRefreshRequest t, KeysetKey serviceKey) { final Buffer b = Buffer.buffer(); b.appendByte((byte) t.version.rawVersion); b.appendLong(t.createdAt.toEpochMilli()); @@ -318,7 +318,7 @@ public byte[] encodeIntoRefreshTokenV2(RefreshTokenRequest t, KeysetKey serviceK return b.getBytes(); } - public byte[] encodeIntoRefreshTokenV3(RefreshTokenRequest t, KeysetKey serviceKey) { + public byte[] encodeIntoRefreshTokenV3(TokenRefreshRequest t, KeysetKey serviceKey) { final Buffer refreshPayload = Buffer.buffer(90); refreshPayload.appendLong(t.expiresAt.toEpochMilli()); refreshPayload.appendLong(t.createdAt.toEpochMilli()); @@ -351,21 +351,21 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi } @Override - public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, Instant refreshFrom, Instant asOf) { + public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, Instant refreshFrom, Instant asOf) { final String advertisingToken = generateAdvertisingTokenString(advertisingTokenRequest, asOf); - final String refreshToken = generateRefreshTokenString(refreshTokenRequest, asOf); + final String refreshToken = generateRefreshTokenString(tokenRefreshRequest, asOf); return new IdentityResponse( advertisingToken, advertisingTokenRequest.version, refreshToken, advertisingTokenRequest.expiresAt, - refreshTokenRequest.expiresAt, + tokenRefreshRequest.expiresAt, refreshFrom ); } - private String generateRefreshTokenString(RefreshTokenRequest refreshTokenRequest, Instant asOf) { - return EncodingUtils.toBase64String(encodeIntoRefreshToken(refreshTokenRequest, asOf)); + private String generateRefreshTokenString(TokenRefreshRequest tokenRefreshRequest, Instant asOf) { + return EncodingUtils.toBase64String(encodeIntoRefreshToken(tokenRefreshRequest, asOf)); } private String generateAdvertisingTokenString(AdvertisingTokenRequest advertisingTokenRequest, Instant asOf) { diff --git a/src/main/java/com/uid2/operator/service/ITokenEncoder.java b/src/main/java/com/uid2/operator/service/ITokenEncoder.java index cac7994ae..c8beddc85 100644 --- a/src/main/java/com/uid2/operator/service/ITokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/ITokenEncoder.java @@ -2,14 +2,14 @@ import com.uid2.operator.model.AdvertisingTokenRequest; import com.uid2.operator.model.IdentityResponse; -import com.uid2.operator.model.RefreshTokenRequest; +import com.uid2.operator.model.TokenRefreshRequest; import java.time.Instant; public interface ITokenEncoder { - IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, Instant refreshFrom, Instant asOf); + IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, Instant refreshFrom, Instant asOf); AdvertisingTokenRequest decodeAdvertisingToken(String base64String); - RefreshTokenRequest decodeRefreshToken(String base64String); + TokenRefreshRequest decodeRefreshToken(String base64String); } diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index eacb244a2..879d784bd 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -14,7 +14,7 @@ public interface IUIDOperatorService { IdentityResponse generateIdentity(IdentityRequest request); - RefreshResponse refreshIdentity(RefreshTokenRequest input); + TokenRefreshResponse refreshIdentity(TokenRefreshRequest input); RawUidResponse mapHashedDiiIdentity(MapRequest request); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 9f0e36975..ee9685662 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -113,27 +113,27 @@ public IdentityResponse generateIdentity(IdentityRequest request) { request.establishedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return IdentityResponse.OptOutIdentityResponse; + return IdentityResponse.OptOutResponse; } else { return generateIdentity(request.sourcePublisher, firstLevelHashIdentity, request.privacyBits); } } @Override - public RefreshResponse refreshIdentity(RefreshTokenRequest input) { + public TokenRefreshResponse refreshIdentity(TokenRefreshRequest input) { // should not be possible as different scopes should be using different keys, but just in case if (input.firstLevelHashIdentity.identityScope != this.identityScope) { - return RefreshResponse.Invalid; + return TokenRefreshResponse.Invalid; } if (input.firstLevelHashIdentity.establishedAt.isBefore(RefreshCutoff)) { - return RefreshResponse.Deprecated; + return TokenRefreshResponse.Deprecated; } final Instant now = clock.instant(); if (input.expiresAt.isBefore(now)) { - return RefreshResponse.Expired; + return TokenRefreshResponse.Expired; } final boolean isCstg = input.privacyBits.isClientSideTokenGenerated(); @@ -149,14 +149,14 @@ public RefreshResponse refreshIdentity(RefreshTokenRequest input) { input.firstLevelHashIdentity, input.privacyBits); - return RefreshResponse.createRefreshedResponse(identityResponse, durationSinceLastRefresh, isCstg); + return TokenRefreshResponse.createRefreshedResponse(identityResponse, durationSinceLastRefresh, isCstg); } else { - return RefreshResponse.Optout; + return TokenRefreshResponse.Optout; } } catch (KeyManager.NoActiveKeyException e) { - return RefreshResponse.NoActiveKey; + return TokenRefreshResponse.NoActiveKey; } catch (Exception ex) { - return RefreshResponse.Invalid; + return TokenRefreshResponse.Invalid; } } @@ -262,17 +262,17 @@ private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenRequest(sourcePublisher, rawUidIdentity, nowUtc, privacyBits, firstLevelHashIdentity.establishedAt), - this.createRefreshTokenRequest(sourcePublisher, firstLevelHashIdentity, nowUtc, privacyBits), + this.createTokenRefreshRequest(sourcePublisher, firstLevelHashIdentity, nowUtc, privacyBits), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc ); } - private RefreshTokenRequest createRefreshTokenRequest(SourcePublisher sourcePublisher, + private TokenRefreshRequest createTokenRefreshRequest(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, Instant now, PrivacyBits privacyBits) { - return new RefreshTokenRequest( + return new TokenRefreshRequest( this.refreshTokenVersion, now, now.plusMillis(refreshExpiresAfter.toMillis()), diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 83c6e5ce8..ecfb9302e 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -813,7 +813,7 @@ private void handleTokenRefreshV1(RoutingContext rc) { } try { - final RefreshResponse r = this.refreshIdentity(rc, refreshToken); + final TokenRefreshResponse r = this.refreshIdentity(rc, refreshToken); siteId = rc.get(Const.RoutingContextData.SiteId); if (!r.isRefreshed()) { if (r.isOptOut() || r.isDeprecated()) { @@ -845,7 +845,7 @@ private void handleTokenRefreshV2(RoutingContext rc) { try { platformType = getPlatformType(rc); String tokenStr = (String) rc.data().get("request"); - final RefreshResponse r = this.refreshIdentity(rc, tokenStr); + final TokenRefreshResponse r = this.refreshIdentity(rc, tokenStr); siteId = rc.get(Const.RoutingContextData.SiteId); if (!r.isRefreshed()) { if (r.isOptOut() || r.isDeprecated()) { @@ -1070,7 +1070,7 @@ private void handleTokenRefresh(RoutingContext rc) { } try { - final RefreshResponse r = this.refreshIdentity(rc, tokenList.get(0)); + final TokenRefreshResponse r = this.refreshIdentity(rc, tokenList.get(0)); sendJsonResponse(rc, r.getIdentityResponse().toJsonV0()); @@ -1764,26 +1764,26 @@ private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVer } - private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { - final RefreshTokenRequest refreshTokenRequest; + private TokenRefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) { + final TokenRefreshRequest tokenRefreshRequest; try { if (AuthMiddleware.isAuthenticated(rc)) { rc.put(Const.RoutingContextData.SiteId, AuthMiddleware.getAuthClient(ClientKey.class, rc).getSiteId()); } - refreshTokenRequest = this.encoder.decodeRefreshToken(tokenStr); + tokenRefreshRequest = this.encoder.decodeRefreshToken(tokenStr); } catch (ClientInputValidationException cie) { LOGGER.warn("Failed to decode refresh token for site ID: " + rc.data().get(Const.RoutingContextData.SiteId), cie); - return RefreshResponse.Invalid; + return TokenRefreshResponse.Invalid; } - if (refreshTokenRequest == null) { - return RefreshResponse.Invalid; + if (tokenRefreshRequest == null) { + return TokenRefreshResponse.Invalid; } if (!AuthMiddleware.isAuthenticated(rc)) { - rc.put(Const.RoutingContextData.SiteId, refreshTokenRequest.sourcePublisher.siteId); + rc.put(Const.RoutingContextData.SiteId, tokenRefreshRequest.sourcePublisher.siteId); } recordRefreshTokenVersionCount(String.valueOf(rc.data().get(Const.RoutingContextData.SiteId)), this.getRefreshTokenVersion(tokenStr)); - return this.idService.refreshIdentity(refreshTokenRequest); + return this.idService.refreshIdentity(tokenRefreshRequest); } public static String getSiteName(ISiteStore siteStore, Integer siteId) { diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 4affea1f0..0b0009ef7 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -55,7 +55,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity("test@example.com", "some-salt"); - final RefreshTokenRequest refreshTokenRequest = new RefreshTokenRequest(tokenVersion, + final TokenRefreshRequest tokenRefreshRequest = new TokenRefreshRequest(tokenVersion, now, now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), @@ -65,20 +65,20 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { ); if (tokenVersion == TokenVersion.V4) { - Assert.assertThrows(Exception.class, () -> encoder.encodeIntoRefreshToken(refreshTokenRequest, now)); + Assert.assertThrows(Exception.class, () -> encoder.encodeIntoRefreshToken(tokenRefreshRequest, now)); return; //V4 not supported for RefreshTokens } - final byte[] encodedBytes = encoder.encodeIntoRefreshToken(refreshTokenRequest, now); - final RefreshTokenRequest decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); + final byte[] encodedBytes = encoder.encodeIntoRefreshToken(tokenRefreshRequest, now); + final TokenRefreshRequest decoded = encoder.decodeRefreshToken(EncodingUtils.toBase64String(encodedBytes)); assertEquals(tokenVersion, decoded.version); - assertEquals(refreshTokenRequest.createdAt, decoded.createdAt); + assertEquals(tokenRefreshRequest.createdAt, decoded.createdAt); int addSeconds = (tokenVersion == TokenVersion.V2) ? 60 : 0; //todo: why is there a 60 second buffer in encodeV2() but not in encodeV3()? - assertEquals(refreshTokenRequest.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); - assertTrue(refreshTokenRequest.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); - assertEquals(refreshTokenRequest.privacyBits, decoded.privacyBits); - assertEquals(refreshTokenRequest.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); - assertEquals(refreshTokenRequest.sourcePublisher.siteId, decoded.sourcePublisher.siteId); + assertEquals(tokenRefreshRequest.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); + assertTrue(tokenRefreshRequest.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); + assertEquals(tokenRefreshRequest.privacyBits, decoded.privacyBits); + assertEquals(tokenRefreshRequest.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); + assertEquals(tokenRefreshRequest.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 25 : 2); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 741050dcd..8f32d9625 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -188,26 +188,26 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(identityRequest.establishedAt, advertisingTokenRequest.establishedAt); assertEquals(identityRequest.privacyBits, advertisingTokenRequest.privacyBits); - RefreshTokenRequest refreshTokenRequest = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); - assertEquals(this.now, refreshTokenRequest.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenRequest.expiresAt); - assertEquals(identityRequest.sourcePublisher.siteId, refreshTokenRequest.sourcePublisher.siteId); - assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, refreshTokenRequest.firstLevelHashIdentity); - assertEquals(identityRequest.establishedAt, refreshTokenRequest.firstLevelHashIdentity.establishedAt); + TokenRefreshRequest tokenRefreshRequest = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + assertEquals(this.now, tokenRefreshRequest.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), tokenRefreshRequest.expiresAt); + assertEquals(identityRequest.sourcePublisher.siteId, tokenRefreshRequest.sourcePublisher.siteId); + assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, tokenRefreshRequest.firstLevelHashIdentity); + assertEquals(identityRequest.establishedAt, tokenRefreshRequest.firstLevelHashIdentity.establishedAt); final byte[] firstLevelHash = getFirstLevelHash(identityRequest.hashedDiiIdentity.hashedDii, saltProvider.getSnapshot(this.now).getFirstLevelSalt() ); - assertArrayEquals(firstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); setNow(Instant.now().plusSeconds(200)); reset(shutdownHandler); - final RefreshResponse refreshResponse = uid2Service.refreshIdentity(refreshTokenRequest); + final TokenRefreshResponse refreshResponse = uid2Service.refreshIdentity(tokenRefreshRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(refreshResponse); - assertEquals(RefreshResponse.Status.Refreshed, refreshResponse.getStatus()); + assertEquals(TokenRefreshResponse.Status.Refreshed, refreshResponse.getStatus()); assertNotNull(refreshResponse.getIdentityResponse()); UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); @@ -221,14 +221,14 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { advertisingTokenRequest2.rawUidIdentity.rawUid); assertEquals(identityRequest.privacyBits, advertisingTokenRequest2.privacyBits); - RefreshTokenRequest refreshTokenRequest2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); - assertEquals(this.now, refreshTokenRequest2.createdAt); - assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), refreshTokenRequest2.expiresAt); - assertEquals(refreshTokenRequest.sourcePublisher.siteId, refreshTokenRequest2.sourcePublisher.siteId); - assertIdentityScopeIdentityType(refreshTokenRequest.firstLevelHashIdentity, refreshTokenRequest2.firstLevelHashIdentity); - assertEquals(refreshTokenRequest.firstLevelHashIdentity.establishedAt, refreshTokenRequest2.firstLevelHashIdentity.establishedAt); - assertArrayEquals(refreshTokenRequest.firstLevelHashIdentity.firstLevelHash, refreshTokenRequest2.firstLevelHashIdentity.firstLevelHash); - assertArrayEquals(firstLevelHash, refreshTokenRequest2.firstLevelHashIdentity.firstLevelHash); + TokenRefreshRequest tokenRefreshRequest2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); + assertEquals(this.now, tokenRefreshRequest2.createdAt); + assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), tokenRefreshRequest2.expiresAt); + assertEquals(tokenRefreshRequest.sourcePublisher.siteId, tokenRefreshRequest2.sourcePublisher.siteId); + assertIdentityScopeIdentityType(tokenRefreshRequest.firstLevelHashIdentity, tokenRefreshRequest2.firstLevelHashIdentity); + assertEquals(tokenRefreshRequest.firstLevelHashIdentity.establishedAt, tokenRefreshRequest2.firstLevelHashIdentity.establishedAt); + assertArrayEquals(tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash, tokenRefreshRequest2.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(firstLevelHash, tokenRefreshRequest2.firstLevelHashIdentity.firstLevelHash); } @Test @@ -246,8 +246,8 @@ public void testTestOptOutKey_DoNotRespectOptout() { assertNotNull(identityResponse); assertFalse(identityResponse.isOptedOut()); - final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); - assertEquals(RefreshResponse.Optout, uid2Service.refreshIdentity(refreshTokenRequest)); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + assertEquals(TokenRefreshResponse.Optout, uid2Service.refreshIdentity(tokenRefreshRequest)); } @Test @@ -280,9 +280,9 @@ public void testTestOptOutKeyIdentityScopeMismatch() { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Invalid, uid2Service.refreshIdentity(refreshTokenRequest)); + assertEquals(TokenRefreshResponse.Invalid, uid2Service.refreshIdentity(tokenRefreshRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -446,7 +446,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertEquals(identityResponse, IdentityResponse.OptOutIdentityResponse); + assertEquals(identityResponse, IdentityResponse.OptOutResponse); } @ParameterizedTest @@ -510,14 +510,14 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest)); + assertEquals(TokenRefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -552,14 +552,14 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - assertEquals(RefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest)); + assertEquals(TokenRefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); } @@ -629,7 +629,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); assertNotNull(advertisingTokenRequest.rawUidIdentity); } @@ -690,14 +690,14 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotEquals(identityResponse, IdentityResponse.OptOutIdentityResponse); + assertNotEquals(identityResponse, IdentityResponse.OptOutResponse); assertNotNull(identityResponse); - final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); - RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + TokenRefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest); assertTrue(refreshResponse.isRefreshed()); assertNotNull(refreshResponse.getIdentityResponse()); - assertNotEquals(RefreshResponse.Optout, refreshResponse); + assertNotEquals(TokenRefreshResponse.Optout, refreshResponse); } @ParameterizedTest @@ -756,17 +756,17 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutIdentityResponse, identityResponse); + assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); assertNotNull(advertisingTokenRequest.rawUidIdentity); - final RefreshTokenRequest refreshTokenRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); reset(shutdownHandler); - RefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(refreshTokenRequest); + TokenRefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertTrue(refreshResponse.isRefreshed()); assertNotNull(refreshResponse.getIdentityResponse()); - assertNotEquals(RefreshResponse.Optout, refreshResponse); + assertNotEquals(TokenRefreshResponse.Optout, refreshResponse); final MapRequest mapRequest = new MapRequest( inputVal.toHashedDiiIdentity(scope), diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 6ceeca9be..cdc401ecd 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -848,11 +848,11 @@ public static void validateAdvertisingToken(String advertisingTokenString, Token } } - RefreshTokenRequest decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { - RefreshTokenRequest refreshTokenRequest = encoder.decodeRefreshToken(refreshTokenString); - assertEquals(getIdentityScope(), refreshTokenRequest.firstLevelHashIdentity.identityScope); - assertEquals(identityType, refreshTokenRequest.firstLevelHashIdentity.identityType); - return refreshTokenRequest; + TokenRefreshRequest decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { + TokenRefreshRequest tokenRefreshRequest = encoder.decodeRefreshToken(refreshTokenString); + assertEquals(getIdentityScope(), tokenRefreshRequest.firstLevelHashIdentity.identityScope); + assertEquals(identityType, tokenRefreshRequest.firstLevelHashIdentity.identityType); + return tokenRefreshRequest; } @ParameterizedTest @@ -1165,14 +1165,14 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, identityType); - RefreshTokenRequest refreshTokenRequest = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); + TokenRefreshRequest tokenRefreshRequest = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); final byte[] rawUid = getRawUidFromIdentity(identityType, optOutTokenInput.getNormalized(), firstLevelSalt, rotatingSalt123.getSalt()); final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity(optOutTokenInput.getNormalized(), firstLevelSalt); assertArrayEquals(rawUid, advertisingTokenRequest.rawUidIdentity.rawUid); - assertArrayEquals(firstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); String advertisingTokenString = body.getString("advertising_token"); final Instant now = Instant.now(); @@ -1225,9 +1225,9 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -1239,15 +1239,15 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test }); } - public void assertAdvertisingTokenRefreshTokenRequests(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, + public void assertAdvertisingTokenRefreshTokenRequests(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, int expectedClientSiteId, byte[] expectedRawUidIdentity, PrivacyBits expectedPrivacyBits, JsonObject identityResponse, byte[] firstLevelHashIdentity) { assertEquals(expectedClientSiteId, advertisingTokenRequest.sourcePublisher.siteId); - assertEquals(expectedClientSiteId, refreshTokenRequest.sourcePublisher.siteId); + assertEquals(expectedClientSiteId, tokenRefreshRequest.sourcePublisher.siteId); assertArrayEquals(expectedRawUidIdentity, advertisingTokenRequest.rawUidIdentity.rawUid); - verifyPrivacyBits(expectedPrivacyBits, advertisingTokenRequest, refreshTokenRequest); - verifyFirstLevelHashIdentityAndEstablishedAt(firstLevelHashIdentity, refreshTokenRequest, identityResponse, advertisingTokenRequest.establishedAt); + verifyPrivacyBits(expectedPrivacyBits, advertisingTokenRequest, tokenRefreshRequest); + verifyFirstLevelHashIdentityAndEstablishedAt(firstLevelHashIdentity, tokenRefreshRequest, identityResponse, advertisingTokenRequest.establishedAt); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(identityResponse.getLong("refresh_expires")), 10); @@ -1255,9 +1255,9 @@ public void assertAdvertisingTokenRefreshTokenRequests(AdvertisingTokenRequest a } public void verifyPrivacyBits(PrivacyBits expectedValue, AdvertisingTokenRequest advertisingTokenRequest, - RefreshTokenRequest refreshTokenRequest) { + TokenRefreshRequest tokenRefreshRequest) { assertEquals(advertisingTokenRequest.privacyBits, expectedValue); - assertEquals(advertisingTokenRequest.privacyBits, refreshTokenRequest.privacyBits); + assertEquals(advertisingTokenRequest.privacyBits, tokenRefreshRequest.privacyBits); } @ParameterizedTest @@ -1282,9 +1282,9 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token"), IdentityType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token"), IdentityType.Email); - assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -1314,9 +1314,9 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingTokenRequest firstAdvertisingTokenRequest = validateAndGetToken(encoder, bodyJson, IdentityType.Email); - RefreshTokenRequest firstRefreshTokenRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + TokenRefreshRequest firstTokenRefreshRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertEquals(firstAdvertisingTokenRequest.establishedAt, firstRefreshTokenRequest.firstLevelHashIdentity.establishedAt); + assertEquals(firstAdvertisingTokenRequest.establishedAt, firstTokenRefreshRequest.firstLevelHashIdentity.establishedAt); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -1324,7 +1324,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()); byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt); - assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstRefreshTokenRequest, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstTokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, @@ -1341,12 +1341,12 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Email); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh assertAdvertisingTokenRefreshTokenRequests( advertisingTokenRequest, - firstRefreshTokenRequest, + firstTokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -1354,7 +1354,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t expectedFirstLevelHashIdentity); assertAdvertisingTokenRefreshTokenRequests( firstAdvertisingTokenRequest, - refreshTokenRequest, + tokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -1362,7 +1362,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t expectedFirstLevelHashIdentity); assertAdvertisingTokenRefreshTokenRequests( advertisingTokenRequest, - refreshTokenRequest, + tokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -1420,9 +1420,9 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); - assertEquals(clientSiteId, refreshTokenRequest.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); + assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -1593,9 +1593,9 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertEquals(clientSiteId, refreshTokenRequest.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); testContext.completeNow(); }); @@ -1632,9 +1632,9 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertEquals(clientSiteId, refreshTokenRequest.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2538,9 +2538,9 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Phone); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -2551,15 +2551,15 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test } void verifyFirstLevelHashIdentityAndEstablishedAt(byte[] expectedFirstLevelHash, - RefreshTokenRequest refreshTokenRequest, + TokenRefreshRequest tokenRefreshRequest, JsonObject receivedJsonBody, Instant expectedEstablishedTime) { - assertArrayEquals(expectedFirstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash); - assertEquals(expectedEstablishedTime, refreshTokenRequest.firstLevelHashIdentity.establishedAt); - assertTrue(refreshTokenRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); - assertTrue(refreshTokenRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); - assertTrue(refreshTokenRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); + assertArrayEquals(expectedFirstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); + assertEquals(expectedEstablishedTime, tokenRefreshRequest.firstLevelHashIdentity.establishedAt); + assertTrue(tokenRefreshRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); + assertTrue(tokenRefreshRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); + assertTrue(tokenRefreshRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); } @ParameterizedTest @@ -2583,9 +2583,9 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Phone); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); - assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, @@ -2614,14 +2614,14 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC AdvertisingTokenRequest firstAdvertisingTokenRequest = validateAndGetToken(encoder, bodyJson, IdentityType.Phone); String genRefreshToken = bodyJson.getString("refresh_token"); - RefreshTokenRequest firstRefreshTokenRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + TokenRefreshRequest firstTokenRefreshRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()); byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt); - assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstRefreshTokenRequest, clientSiteId, + assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstTokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, bodyJson, @@ -2637,12 +2637,12 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh assertAdvertisingTokenRefreshTokenRequests( advertisingTokenRequest, - firstRefreshTokenRequest, + firstTokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -2650,7 +2650,7 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC expectedFirstLevelHashIdentity); assertAdvertisingTokenRefreshTokenRequests( firstAdvertisingTokenRequest, - refreshTokenRequest, + tokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -2658,7 +2658,7 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC expectedFirstLevelHashIdentity); assertAdvertisingTokenRefreshTokenRequests( advertisingTokenRequest, - refreshTokenRequest, + tokenRefreshRequest, clientSiteId, expectedRawUidIdentity, PrivacyBits.DEFAULT, @@ -4086,9 +4086,9 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver final JsonObject genBody = response.getJsonObject("body"); final AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, identityType); - final RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); + final TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); - assertAreClientSideGeneratedTokens(advertisingTokenRequest, refreshTokenRequest, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, identityType, id); // When we refresh the token the user has opted out. when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) @@ -4151,7 +4151,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, identityType); - RefreshTokenRequest refreshTokenRequest = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); @@ -4162,13 +4162,13 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id expectedPrivacyBits.setLegacyBit(); expectedPrivacyBits.setClientSideTokenGenerate(); - assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, refreshTokenRequest, + assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, expectedRawUidIdentity, expectedPrivacyBits, genBody, expectedFirstLevelHashIdentity); - assertAreClientSideGeneratedTokens(advertisingTokenRequest, refreshTokenRequest, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, identityType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_from")), 10); @@ -4193,7 +4193,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id String refreshTokenStringNew = refreshBody.getString("decrypted_refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - RefreshTokenRequest refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); + TokenRefreshRequest refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); assertAdvertisingTokenRefreshTokenRequests(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, @@ -4295,18 +4295,18 @@ void cstgInvalidInput(String identityType, String rawUID, Vertx vertx, VertxTest }); } - private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, int siteId, IdentityType identityType, String identity) { + private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, int siteId, IdentityType identityType, String identity) { assertAreClientSideGeneratedTokens(advertisingTokenRequest, - refreshTokenRequest, + tokenRefreshRequest, siteId, identityType, identity, false); } - private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, RefreshTokenRequest refreshTokenRequest, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { + private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { final PrivacyBits advertisingTokenPrivacyBits = advertisingTokenRequest.privacyBits; - final PrivacyBits refreshTokenPrivacyBits = refreshTokenRequest.privacyBits; + final PrivacyBits refreshTokenPrivacyBits = tokenRefreshRequest.privacyBits; final byte[] rawUid = getRawUidFromIdentity(identityType, identity, @@ -4323,10 +4323,10 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertis () -> assertEquals(expectedOptOut, refreshTokenPrivacyBits.isClientSideTokenOptedOut(), "Refresh token privacy bits CSTG optout flag is incorrect"), () -> assertEquals(siteId, advertisingTokenRequest.sourcePublisher.siteId, "Advertising token site ID is incorrect"), - () -> assertEquals(siteId, refreshTokenRequest.sourcePublisher.siteId, "Refresh token site ID is incorrect"), + () -> assertEquals(siteId, tokenRefreshRequest.sourcePublisher.siteId, "Refresh token site ID is incorrect"), () -> assertArrayEquals(rawUid, advertisingTokenRequest.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), - () -> assertArrayEquals(firstLevelHash, refreshTokenRequest.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") + () -> assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") ); } diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 14a650047..5f43c9661 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -8,7 +8,6 @@ import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; -import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -59,7 +58,7 @@ public IdentityResponse TokenGenerationBenchmark() { @Benchmark @BenchmarkMode(Mode.Throughput) - public RefreshResponse TokenRefreshBenchmark() { + public TokenRefreshResponse TokenRefreshBenchmark() { return uidService.refreshIdentity( encoder.decodeRefreshToken( generatedTokens[(idx++) & 65535].getRefreshToken())); diff --git a/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java b/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java index c8ff6feed..ae44a0b94 100644 --- a/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java +++ b/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java @@ -15,8 +15,8 @@ public class IdentityResponseTest { @Test public void doIdentityResponseTest() throws NoSuchAlgorithmException { - assertEquals(IdentityResponse.OptOutIdentityResponse.getAdvertisingToken(), ""); - assertTrue(IdentityResponse.OptOutIdentityResponse.isOptedOut()); + assertEquals(IdentityResponse.OptOutResponse.getAdvertisingToken(), ""); + assertTrue(IdentityResponse.OptOutResponse.isOptedOut()); IdentityResponse nullAdTokenValue = new IdentityResponse(null, TokenVersion.V4, "refreshToken", null,null,null); assertTrue(nullAdTokenValue.isOptedOut()); From ea0b247c1b6a2cd4c996d5a3a505acc01fa1f52a Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 9 Dec 2024 17:14:59 +1100 Subject: [PATCH 58/61] Renamed IdentityRequest/IdentityResponse to TokenGenerateRequest/Response --- ...Request.java => TokenGenerateRequest.java} | 6 +- ...sponse.java => TokenGenerateResponse.java} | 8 +- .../operator/model/TokenRefreshResponse.java | 28 +-- .../service/EncryptedTokenEncoder.java | 4 +- .../uid2/operator/service/ITokenEncoder.java | 4 +- .../operator/service/IUIDOperatorService.java | 2 +- .../operator/service/UIDOperatorService.java | 12 +- .../operator/vertx/UIDOperatorVerticle.java | 30 ++-- .../uid2/operator/UIDOperatorServiceTest.java | 166 +++++++++--------- .../benchmark/TokenEndecBenchmark.java | 14 +- ...st.java => TokenGenerateResponseTest.java} | 12 +- 11 files changed, 143 insertions(+), 143 deletions(-) rename src/main/java/com/uid2/operator/model/{IdentityRequest.java => TokenGenerateRequest.java} (92%) rename src/main/java/com/uid2/operator/model/{IdentityResponse.java => TokenGenerateResponse.java} (85%) rename src/test/java/com/uid2/operator/utilTests/{IdentityResponseTest.java => TokenGenerateResponseTest.java} (78%) diff --git a/src/main/java/com/uid2/operator/model/IdentityRequest.java b/src/main/java/com/uid2/operator/model/TokenGenerateRequest.java similarity index 92% rename from src/main/java/com/uid2/operator/model/IdentityRequest.java rename to src/main/java/com/uid2/operator/model/TokenGenerateRequest.java index c1cca1d75..f482e8d21 100644 --- a/src/main/java/com/uid2/operator/model/IdentityRequest.java +++ b/src/main/java/com/uid2/operator/model/TokenGenerateRequest.java @@ -5,7 +5,7 @@ import java.time.Instant; -public final class IdentityRequest { +public final class TokenGenerateRequest { public final SourcePublisher sourcePublisher; public final HashedDiiIdentity hashedDiiIdentity; public final OptoutCheckPolicy optoutCheckPolicy; @@ -13,7 +13,7 @@ public final class IdentityRequest { public final PrivacyBits privacyBits; public final Instant establishedAt; - public IdentityRequest( + public TokenGenerateRequest( SourcePublisher sourcePublisher, HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy, @@ -26,7 +26,7 @@ public IdentityRequest( this.establishedAt = establishedAt; } - public IdentityRequest( + public TokenGenerateRequest( SourcePublisher sourcePublisher, HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy tokenGeneratePolicy) { diff --git a/src/main/java/com/uid2/operator/model/IdentityResponse.java b/src/main/java/com/uid2/operator/model/TokenGenerateResponse.java similarity index 85% rename from src/main/java/com/uid2/operator/model/IdentityResponse.java rename to src/main/java/com/uid2/operator/model/TokenGenerateResponse.java index 746294064..8c7d273f9 100644 --- a/src/main/java/com/uid2/operator/model/IdentityResponse.java +++ b/src/main/java/com/uid2/operator/model/TokenGenerateResponse.java @@ -8,8 +8,8 @@ // this defines all the fields for the response of the /token/generate and /client/generate endpoints before they are // jsonified // todo: can be converted to record later -public class IdentityResponse { - public static final IdentityResponse OptOutResponse = new IdentityResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); +public class TokenGenerateResponse { + public static final TokenGenerateResponse OptOutResponse = new TokenGenerateResponse("", null, "", Instant.EPOCH, Instant.EPOCH, Instant.EPOCH); //aka UID token private final String advertisingToken; @@ -20,8 +20,8 @@ public class IdentityResponse { private final Instant refreshExpires; private final Instant refreshFrom; - public IdentityResponse(String advertisingToken, TokenVersion advertisingTokenVersion, String refreshToken, - Instant identityExpires, Instant refreshExpires, Instant refreshFrom) { + public TokenGenerateResponse(String advertisingToken, TokenVersion advertisingTokenVersion, String refreshToken, + Instant identityExpires, Instant refreshExpires, Instant refreshFrom) { this.advertisingToken = advertisingToken; this.advertisingTokenVersion = advertisingTokenVersion; this.refreshToken = refreshToken; diff --git a/src/main/java/com/uid2/operator/model/TokenRefreshResponse.java b/src/main/java/com/uid2/operator/model/TokenRefreshResponse.java index 5a52fa571..40e5d73c9 100644 --- a/src/main/java/com/uid2/operator/model/TokenRefreshResponse.java +++ b/src/main/java/com/uid2/operator/model/TokenRefreshResponse.java @@ -5,37 +5,37 @@ public class TokenRefreshResponse { public static final TokenRefreshResponse Invalid = new TokenRefreshResponse(Status.Invalid, - IdentityResponse.OptOutResponse); - public static final TokenRefreshResponse Optout = new TokenRefreshResponse(Status.Optout, IdentityResponse.OptOutResponse); - public static final TokenRefreshResponse Expired = new TokenRefreshResponse(Status.Expired, IdentityResponse.OptOutResponse); - public static final TokenRefreshResponse Deprecated = new TokenRefreshResponse(Status.Deprecated, IdentityResponse.OptOutResponse); - public static final TokenRefreshResponse NoActiveKey = new TokenRefreshResponse(Status.NoActiveKey, IdentityResponse.OptOutResponse); + TokenGenerateResponse.OptOutResponse); + public static final TokenRefreshResponse Optout = new TokenRefreshResponse(Status.Optout, TokenGenerateResponse.OptOutResponse); + public static final TokenRefreshResponse Expired = new TokenRefreshResponse(Status.Expired, TokenGenerateResponse.OptOutResponse); + public static final TokenRefreshResponse Deprecated = new TokenRefreshResponse(Status.Deprecated, TokenGenerateResponse.OptOutResponse); + public static final TokenRefreshResponse NoActiveKey = new TokenRefreshResponse(Status.NoActiveKey, TokenGenerateResponse.OptOutResponse); private final Status status; - private final IdentityResponse identityResponse; + private final TokenGenerateResponse tokenGenerateResponse; private final Duration durationSinceLastRefresh; private final boolean isCstg; - private TokenRefreshResponse(Status status, IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { + private TokenRefreshResponse(Status status, TokenGenerateResponse tokenGenerateResponse, Duration durationSinceLastRefresh, boolean isCstg) { this.status = status; - this.identityResponse = identityResponse; + this.tokenGenerateResponse = tokenGenerateResponse; this.durationSinceLastRefresh = durationSinceLastRefresh; this.isCstg = isCstg; } - private TokenRefreshResponse(Status status, IdentityResponse identityResponse) { - this(status, identityResponse, null, false); + private TokenRefreshResponse(Status status, TokenGenerateResponse tokenGenerateResponse) { + this(status, tokenGenerateResponse, null, false); } - public static TokenRefreshResponse createRefreshedResponse(IdentityResponse identityResponse, Duration durationSinceLastRefresh, boolean isCstg) { - return new TokenRefreshResponse(Status.Refreshed, identityResponse, durationSinceLastRefresh, isCstg); + public static TokenRefreshResponse createRefreshedResponse(TokenGenerateResponse tokenGenerateResponse, Duration durationSinceLastRefresh, boolean isCstg) { + return new TokenRefreshResponse(Status.Refreshed, tokenGenerateResponse, durationSinceLastRefresh, isCstg); } public Status getStatus() { return status; } - public IdentityResponse getIdentityResponse() { - return identityResponse; + public TokenGenerateResponse getIdentityResponse() { + return tokenGenerateResponse; } public Duration getDurationSinceLastRefresh() { diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 26d019795..06570391e 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -351,10 +351,10 @@ public static String bytesToBase64Token(byte[] advertisingTokenBytes, TokenVersi } @Override - public IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, Instant refreshFrom, Instant asOf) { + public TokenGenerateResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, Instant refreshFrom, Instant asOf) { final String advertisingToken = generateAdvertisingTokenString(advertisingTokenRequest, asOf); final String refreshToken = generateRefreshTokenString(tokenRefreshRequest, asOf); - return new IdentityResponse( + return new TokenGenerateResponse( advertisingToken, advertisingTokenRequest.version, refreshToken, diff --git a/src/main/java/com/uid2/operator/service/ITokenEncoder.java b/src/main/java/com/uid2/operator/service/ITokenEncoder.java index c8beddc85..73fe2e70c 100644 --- a/src/main/java/com/uid2/operator/service/ITokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/ITokenEncoder.java @@ -1,13 +1,13 @@ package com.uid2.operator.service; import com.uid2.operator.model.AdvertisingTokenRequest; -import com.uid2.operator.model.IdentityResponse; +import com.uid2.operator.model.TokenGenerateResponse; import com.uid2.operator.model.TokenRefreshRequest; import java.time.Instant; public interface ITokenEncoder { - IdentityResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, Instant refreshFrom, Instant asOf); + TokenGenerateResponse encodeIntoIdentityResponse(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, Instant refreshFrom, Instant asOf); AdvertisingTokenRequest decodeAdvertisingToken(String base64String); diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 879d784bd..6fec9288e 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -12,7 +12,7 @@ public interface IUIDOperatorService { - IdentityResponse generateIdentity(IdentityRequest request); + TokenGenerateResponse generateIdentity(TokenGenerateRequest request); TokenRefreshResponse refreshIdentity(TokenRefreshRequest input); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index ee9685662..b4914c770 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -105,7 +105,7 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv } @Override - public IdentityResponse generateIdentity(IdentityRequest request) { + public TokenGenerateResponse generateIdentity(TokenGenerateRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); final byte[] firstLevelHash = getFirstLevelHash(request.hashedDiiIdentity.hashedDii, now); final FirstLevelHashIdentity firstLevelHashIdentity = new FirstLevelHashIdentity( @@ -113,7 +113,7 @@ public IdentityResponse generateIdentity(IdentityRequest request) { request.establishedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return IdentityResponse.OptOutResponse; + return TokenGenerateResponse.OptOutResponse; } else { return generateIdentity(request.sourcePublisher, firstLevelHashIdentity, request.privacyBits); } @@ -145,11 +145,11 @@ public TokenRefreshResponse refreshIdentity(TokenRefreshRequest input) { final Duration durationSinceLastRefresh = Duration.between(input.createdAt, now); if (!optedOut) { - IdentityResponse identityResponse = this.generateIdentity(input.sourcePublisher, + TokenGenerateResponse tokenGenerateResponse = this.generateIdentity(input.sourcePublisher, input.firstLevelHashIdentity, input.privacyBits); - return TokenRefreshResponse.createRefreshedResponse(identityResponse, durationSinceLastRefresh, isCstg); + return TokenRefreshResponse.createRefreshedResponse(tokenGenerateResponse, durationSinceLastRefresh, isCstg); } else { return TokenRefreshResponse.Optout; } @@ -250,8 +250,8 @@ private RawUidResponse generateRawUid(FirstLevelHashIdentity firstLevelHashIdent rotatingSalt.getHashedId()); } - private IdentityResponse generateIdentity(SourcePublisher sourcePublisher, - FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { + private TokenGenerateResponse generateIdentity(SourcePublisher sourcePublisher, + FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index ecfb9302e..8175cd25e 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -2,7 +2,7 @@ import com.uid2.operator.Const; import com.uid2.operator.model.*; -import com.uid2.operator.model.IdentityResponse; +import com.uid2.operator.model.TokenGenerateResponse; import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.userIdentity.HashedDiiIdentity; import com.uid2.operator.monitoring.IStatsCollectorQueue; @@ -464,10 +464,10 @@ else if(emailHash != null) { privacyBits.setLegacyBit(); privacyBits.setClientSideTokenGenerate(); - IdentityResponse identityResponse; + TokenGenerateResponse tokenGenerateResponse; try { - identityResponse = this.idService.generateIdentity( - new IdentityRequest( + tokenGenerateResponse = this.idService.generateIdentity( + new TokenGenerateRequest( new SourcePublisher(clientSideKeypair.getSiteId()), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.RespectOptOut, privacyBits, Instant.now())); @@ -478,12 +478,12 @@ else if(emailHash != null) { JsonObject response; TokenResponseStatsCollector.ResponseStatus responseStatus = TokenResponseStatsCollector.ResponseStatus.Success; - if (identityResponse.isOptedOut()) { + if (tokenGenerateResponse.isOptedOut()) { response = ResponseUtil.SuccessNoBodyV2(ResponseStatus.OptOut); responseStatus = TokenResponseStatsCollector.ResponseStatus.OptOut; } else { //user not opted out and already generated valid identity token - response = ResponseUtil.SuccessV2(identityResponse.toJsonV1()); + response = ResponseUtil.SuccessV2(tokenGenerateResponse.toJsonV1()); } //if returning an optout token or a successful identity token created originally if (responseStatus == TokenResponseStatsCollector.ResponseStatus.Success) { @@ -491,7 +491,7 @@ else if(emailHash != null) { } final byte[] encryptedResponse = AesGcm.encrypt(response.toBuffer().getBytes(), sharedSecret); rc.response().setStatusCode(200).end(Buffer.buffer(Unpooled.wrappedBuffer(Base64.getEncoder().encode(encryptedResponse)))); - recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, identityResponse.getAdvertisingTokenVersion(), platformType); + recordTokenResponseStats(clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, responseStatus, siteProvider, tokenGenerateResponse.getAdvertisingTokenVersion(), platformType); } private boolean hasValidOriginOrAppName(RoutingContext rc, CstgRequest request, ClientSideKeypair keypair, TokenResponseStatsCollector.PlatformType platformType) { @@ -939,8 +939,8 @@ private void handleTokenGenerateV1(RoutingContext rc) { final InputUtil.InputVal input = this.phoneSupport ? this.getTokenInputV1(rc) : this.getTokenInput(rc); platformType = getPlatformType(rc); if (isTokenInputValid(input, rc)) { - final IdentityResponse response = this.idService.generateIdentity( - new IdentityRequest( + final TokenGenerateResponse response = this.idService.generateIdentity( + new TokenGenerateRequest( new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.defaultPolicy())); @@ -991,8 +991,8 @@ private void handleTokenGenerateV2(RoutingContext rc) { return; } - final IdentityResponse response = this.idService.generateIdentity( - new IdentityRequest( + final TokenGenerateResponse response = this.idService.generateIdentity( + new TokenGenerateRequest( new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.respectOptOut())); @@ -1007,8 +1007,8 @@ private void handleTokenGenerateV2(RoutingContext rc) { pb.setLegacyBit(); pb.setClientSideTokenGenerateOptout(); - final IdentityResponse optOutTokens = this.idService.generateIdentity( - new IdentityRequest( + final TokenGenerateResponse optOutTokens = this.idService.generateIdentity( + new TokenGenerateRequest( new SourcePublisher(siteId), optOutTokenInput.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.DoNotRespect, pb, Instant.now())); @@ -1047,8 +1047,8 @@ else if (!input.isValid()) { try { siteId = AuthMiddleware.getAuthClient(rc).getSiteId(); - final IdentityResponse response = this.idService.generateIdentity( - new IdentityRequest( + final TokenGenerateResponse response = this.idService.generateIdentity( + new TokenGenerateRequest( new SourcePublisher(siteId), input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.defaultPolicy())); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 8f32d9625..4ec802028 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -169,33 +169,33 @@ private void assertIdentityScopeIdentityType(UserIdentity expctedValues, @ParameterizedTest @CsvSource({"123, V2","127, V4","128, V4"}) //site id 127 and 128 is for testing "site_ids_using_v4_tokens" public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(siteId, 124, 125), createHashedDiiIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now.minusSeconds(234) ); - final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); + final TokenGenerateResponse tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identityResponse); + assertNotNull(tokenGenerateResponse); - UIDOperatorVerticleTest.validateAdvertisingToken(identityResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); - AdvertisingTokenRequest advertisingTokenRequest = tokenEncoder.decodeAdvertisingToken(identityResponse.getAdvertisingToken()); + UIDOperatorVerticleTest.validateAdvertisingToken(tokenGenerateResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = tokenEncoder.decodeAdvertisingToken(tokenGenerateResponse.getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenRequest.expiresAt); - assertEquals(identityRequest.sourcePublisher.siteId, advertisingTokenRequest.sourcePublisher.siteId); - assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, advertisingTokenRequest.rawUidIdentity); - assertEquals(identityRequest.establishedAt, advertisingTokenRequest.establishedAt); - assertEquals(identityRequest.privacyBits, advertisingTokenRequest.privacyBits); + assertEquals(tokenGenerateRequest.sourcePublisher.siteId, advertisingTokenRequest.sourcePublisher.siteId); + assertIdentityScopeIdentityType(tokenGenerateRequest.hashedDiiIdentity, advertisingTokenRequest.rawUidIdentity); + assertEquals(tokenGenerateRequest.establishedAt, advertisingTokenRequest.establishedAt); + assertEquals(tokenGenerateRequest.privacyBits, advertisingTokenRequest.privacyBits); - TokenRefreshRequest tokenRefreshRequest = tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + TokenRefreshRequest tokenRefreshRequest = tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); assertEquals(this.now, tokenRefreshRequest.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), tokenRefreshRequest.expiresAt); - assertEquals(identityRequest.sourcePublisher.siteId, tokenRefreshRequest.sourcePublisher.siteId); - assertIdentityScopeIdentityType(identityRequest.hashedDiiIdentity, tokenRefreshRequest.firstLevelHashIdentity); - assertEquals(identityRequest.establishedAt, tokenRefreshRequest.firstLevelHashIdentity.establishedAt); + assertEquals(tokenGenerateRequest.sourcePublisher.siteId, tokenRefreshRequest.sourcePublisher.siteId); + assertIdentityScopeIdentityType(tokenGenerateRequest.hashedDiiIdentity, tokenRefreshRequest.firstLevelHashIdentity); + assertEquals(tokenGenerateRequest.establishedAt, tokenRefreshRequest.firstLevelHashIdentity.establishedAt); - final byte[] firstLevelHash = getFirstLevelHash(identityRequest.hashedDiiIdentity.hashedDii, + final byte[] firstLevelHash = getFirstLevelHash(tokenGenerateRequest.hashedDiiIdentity.hashedDii, saltProvider.getSnapshot(this.now).getFirstLevelSalt() ); assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); @@ -219,7 +219,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(advertisingTokenRequest.establishedAt, advertisingTokenRequest2.establishedAt); assertArrayEquals(advertisingTokenRequest.rawUidIdentity.rawUid, advertisingTokenRequest2.rawUidIdentity.rawUid); - assertEquals(identityRequest.privacyBits, advertisingTokenRequest2.privacyBits); + assertEquals(tokenGenerateRequest.privacyBits, advertisingTokenRequest2.privacyBits); TokenRefreshRequest tokenRefreshRequest2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); assertEquals(this.now, tokenRefreshRequest2.createdAt); @@ -235,18 +235,18 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { public void testTestOptOutKey_DoNotRespectOptout() { final InputUtil.InputVal inputVal = InputUtil.normalizeEmail(IdentityConst.OptOutIdentityForEmail); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.UID2), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); - final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); + final TokenGenerateResponse tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identityResponse); - assertFalse(identityResponse.isOptedOut()); + assertNotNull(tokenGenerateResponse); + assertFalse(tokenGenerateResponse.isOptedOut()); - final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); assertEquals(TokenRefreshResponse.Optout, uid2Service.refreshIdentity(tokenRefreshRequest)); } @@ -254,13 +254,13 @@ public void testTestOptOutKey_DoNotRespectOptout() { public void testTestOptOutKey_RespectOptout() { final InputUtil.InputVal inputVal = InputUtil.normalizeEmail(IdentityConst.OptOutIdentityForEmail); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.UID2), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); - final IdentityResponse identityResponse = uid2Service.generateIdentity(identityRequest); - assertTrue(identityResponse.isOptedOut()); + final TokenGenerateResponse tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); + assertTrue(tokenGenerateResponse.isOptedOut()); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); } @@ -270,17 +270,17 @@ public void testTestOptOutKeyIdentityScopeMismatch() { final String email = "optout@example.com"; final InputUtil.InputVal inputVal = InputUtil.normalizeEmail(email); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(IdentityScope.EUID), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); - final IdentityResponse identityResponse = euidService.generateIdentity(identityRequest); + final TokenGenerateResponse tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identityResponse); + assertNotNull(tokenGenerateResponse); - final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); reset(shutdownHandler); assertEquals(TokenRefreshResponse.Invalid, uid2Service.refreshIdentity(tokenRefreshRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -295,13 +295,13 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(TokenUtils.getIdentityHashString(id), scope, type); - final IdentityRequest identityRequestForceGenerate = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequestForceGenerate = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), hashedDiiIdentity, OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now.minusSeconds(234)); - final IdentityRequest identityRequestRespectOptOut = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequestRespectOptOut = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), hashedDiiIdentity, OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), @@ -311,32 +311,32 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final IdentityResponse identityResponse; + final TokenGenerateResponse tokenGenerateResponse; final AdvertisingTokenRequest advertisingTokenRequest; - final IdentityResponse identityResponseAfterOptOut; + final TokenGenerateResponse tokenGenerateResponseAfterOptOut; if (scope == IdentityScope.UID2) { - identityResponse = uid2Service.generateIdentity(identityRequestForceGenerate); + tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); - identityResponseAfterOptOut = uid2Service.generateIdentity(identityRequestRespectOptOut); + tokenGenerateResponseAfterOptOut = uid2Service.generateIdentity(tokenGenerateRequestRespectOptOut); } else { - identityResponse = euidService.generateIdentity(identityRequestForceGenerate); + tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, identityRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); - identityResponseAfterOptOut = euidService.generateIdentity(identityRequestRespectOptOut); + tokenGenerateResponseAfterOptOut = euidService.generateIdentity(tokenGenerateRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identityResponse); + assertNotNull(tokenGenerateResponse); assertNotNull(advertisingTokenRequest.rawUidIdentity); - assertNotNull(identityResponseAfterOptOut); - assertTrue(identityResponseAfterOptOut.getAdvertisingToken() == null || identityResponseAfterOptOut.getAdvertisingToken().isEmpty()); - assertTrue(identityResponseAfterOptOut.isOptedOut()); + assertNotNull(tokenGenerateResponseAfterOptOut); + assertTrue(tokenGenerateResponseAfterOptOut.getAdvertisingToken() == null || tokenGenerateResponseAfterOptOut.getAdvertisingToken().isEmpty()); + assertTrue(tokenGenerateResponseAfterOptOut.isOptedOut()); } @ParameterizedTest @@ -428,7 +428,7 @@ private InputUtil.InputVal generateInputVal(TestIdentityInputType type, String i void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now @@ -437,16 +437,16 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i // identity has no optout record, ensure generate still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - IdentityResponse identityResponse; + TokenGenerateResponse tokenGenerateResponse; if(scope == IdentityScope.EUID) { - identityResponse = euidService.generateIdentity(identityRequest); + tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); } else { - identityResponse = uid2Service.generateIdentity(identityRequest); + tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertEquals(identityResponse, IdentityResponse.OptOutResponse); + assertEquals(tokenGenerateResponse, TokenGenerateResponse.OptOutResponse); } @ParameterizedTest @@ -494,28 +494,28 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); - IdentityResponse identityResponse; + TokenGenerateResponse tokenGenerateResponse; if(scope == IdentityScope.EUID) { - identityResponse = euidService.generateIdentity(identityRequest); + tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); } else { - identityResponse = uid2Service.generateIdentity(identityRequest); + tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); + assertNotNull(tokenGenerateResponse); + assertNotEquals(TokenGenerateResponse.OptOutResponse, tokenGenerateResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); reset(shutdownHandler); assertEquals(TokenRefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -533,7 +533,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now @@ -542,22 +542,22 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String // identity has optout record, ensure still generates when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - IdentityResponse identityResponse; + TokenGenerateResponse tokenGenerateResponse; if(scope == IdentityScope.EUID) { - identityResponse = euidService.generateIdentity(identityRequest); + tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); } else { - identityResponse = uid2Service.generateIdentity(identityRequest); + tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); + assertNotNull(tokenGenerateResponse); + assertNotEquals(TokenGenerateResponse.OptOutResponse, tokenGenerateResponse); // identity has no optout record, ensure refresh still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); reset(shutdownHandler); assertEquals(TokenRefreshResponse.Optout, (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest)); verify(shutdownHandler, never()).handleSaltRetrievalResponse(anyBoolean()); @@ -608,7 +608,7 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now @@ -617,19 +617,19 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, // all identities have optout records, ensure validate identities still get generated when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - IdentityResponse identityResponse; + TokenGenerateResponse tokenGenerateResponse; AdvertisingTokenRequest advertisingTokenRequest; if (scope == IdentityScope.EUID) { - identityResponse = euidService.generateIdentity(identityRequest); + tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); } else { - identityResponse = uid2Service.generateIdentity(identityRequest); + tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); } - advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), scope, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), scope, tokenGenerateRequest.hashedDiiIdentity.identityType, tokenGenerateRequest.sourcePublisher.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); + assertNotNull(tokenGenerateResponse); + assertNotEquals(TokenGenerateResponse.OptOutResponse, tokenGenerateResponse); assertNotNull(advertisingTokenRequest.rawUidIdentity); } @@ -676,24 +676,24 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i "EmailHash,blah@unifiedid.com,EUID"}) void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.DoNotRespect ); - IdentityResponse identityResponse; + TokenGenerateResponse tokenGenerateResponse; if(scope == IdentityScope.EUID) { - identityResponse = euidService.generateIdentity(identityRequest); + tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); } else { - identityResponse = uid2Service.generateIdentity(identityRequest); + tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotEquals(identityResponse, IdentityResponse.OptOutResponse); - assertNotNull(identityResponse); + assertNotEquals(tokenGenerateResponse, TokenGenerateResponse.OptOutResponse); + assertNotNull(tokenGenerateResponse); - final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); TokenRefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest); assertTrue(refreshResponse.isRefreshed()); assertNotNull(refreshResponse.getIdentityResponse()); @@ -737,29 +737,29 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String InputUtil.InputVal inputVal = generateInputVal(type, id); - final IdentityRequest identityRequest = new IdentityRequest( + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now); - IdentityResponse identityResponse; + TokenGenerateResponse tokenGenerateResponse; AdvertisingTokenRequest advertisingTokenRequest; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - identityResponse = euidService.generateIdentity(identityRequest); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.EUID, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, tokenGenerateRequest.hashedDiiIdentity.identityType, tokenGenerateRequest.sourcePublisher.siteId); } else { - identityResponse = uid2Service.generateIdentity(identityRequest); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, identityResponse.getAdvertisingToken(), IdentityScope.UID2, identityRequest.hashedDiiIdentity.identityType, identityRequest.sourcePublisher.siteId); + tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, tokenGenerateRequest.hashedDiiIdentity.identityType, tokenGenerateRequest.sourcePublisher.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(identityResponse); - assertNotEquals(IdentityResponse.OptOutResponse, identityResponse); + assertNotNull(tokenGenerateResponse); + assertNotEquals(TokenGenerateResponse.OptOutResponse, tokenGenerateResponse); assertNotNull(advertisingTokenRequest.rawUidIdentity); - final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(identityResponse.getRefreshToken()); + final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); reset(shutdownHandler); TokenRefreshResponse refreshResponse = (scope == IdentityScope.EUID? euidService: uid2Service).refreshIdentity(tokenRefreshRequest); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index 5f43c9661..b736c1a44 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -17,7 +17,7 @@ public class TokenEndecBenchmark { private static final HashedDiiIdentity[] hashedDiiIdentities; private static final SourcePublisher publisher; private static final EncryptedTokenEncoder encoder; - private static final IdentityResponse[] generatedTokens; + private static final TokenGenerateResponse[] generatedTokens; private static int idx = 0; static { @@ -35,22 +35,22 @@ public class TokenEndecBenchmark { } } - static IdentityResponse[] createAdvertisingTokens() { - List tokens = new ArrayList<>(); + static TokenGenerateResponse[] createAdvertisingTokens() { + List tokens = new ArrayList<>(); for (int i = 0; i < hashedDiiIdentities.length; i++) { tokens.add( - uidService.generateIdentity(new IdentityRequest( + uidService.generateIdentity(new TokenGenerateRequest( publisher, hashedDiiIdentities[i], OptoutCheckPolicy.DoNotRespect))); } - return tokens.toArray(new IdentityResponse[tokens.size()]); + return tokens.toArray(new TokenGenerateResponse[tokens.size()]); } @Benchmark @BenchmarkMode(Mode.Throughput) - public IdentityResponse TokenGenerationBenchmark() { - return uidService.generateIdentity(new IdentityRequest( + public TokenGenerateResponse TokenGenerationBenchmark() { + return uidService.generateIdentity(new TokenGenerateRequest( publisher, hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.DoNotRespect)); diff --git a/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java b/src/test/java/com/uid2/operator/utilTests/TokenGenerateResponseTest.java similarity index 78% rename from src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java rename to src/test/java/com/uid2/operator/utilTests/TokenGenerateResponseTest.java index ae44a0b94..e659c964b 100644 --- a/src/test/java/com/uid2/operator/utilTests/IdentityResponseTest.java +++ b/src/test/java/com/uid2/operator/utilTests/TokenGenerateResponseTest.java @@ -1,6 +1,6 @@ package com.uid2.operator.utilTests; -import com.uid2.operator.model.IdentityResponse; +import com.uid2.operator.model.TokenGenerateResponse; import com.uid2.shared.model.TokenVersion; import io.vertx.core.json.JsonObject; import org.junit.Test; @@ -12,13 +12,13 @@ import static org.junit.Assert.*; -public class IdentityResponseTest { +public class TokenGenerateResponseTest { @Test public void doIdentityResponseTest() throws NoSuchAlgorithmException { - assertEquals(IdentityResponse.OptOutResponse.getAdvertisingToken(), ""); - assertTrue(IdentityResponse.OptOutResponse.isOptedOut()); + assertEquals(TokenGenerateResponse.OptOutResponse.getAdvertisingToken(), ""); + assertTrue(TokenGenerateResponse.OptOutResponse.isOptedOut()); - IdentityResponse nullAdTokenValue = new IdentityResponse(null, TokenVersion.V4, "refreshToken", null,null,null); + TokenGenerateResponse nullAdTokenValue = new TokenGenerateResponse(null, TokenVersion.V4, "refreshToken", null,null,null); assertTrue(nullAdTokenValue.isOptedOut()); Instant identityExpires = Instant.now(); @@ -27,7 +27,7 @@ public void doIdentityResponseTest() throws NoSuchAlgorithmException { - IdentityResponse response1 = new IdentityResponse("adToken", TokenVersion.V3, "refreshToken", identityExpires + TokenGenerateResponse response1 = new TokenGenerateResponse("adToken", TokenVersion.V3, "refreshToken", identityExpires , refreshExpires, refreshFrom); assertEquals(response1.getAdvertisingToken(), "adToken"); assertEquals(response1.getAdvertisingTokenVersion(), TokenVersion.V3); From 4476ee1ffda688c278594269d17970e30d7c9100 Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 9 Dec 2024 17:20:46 +1100 Subject: [PATCH 59/61] - Renamed RawUidResponse to IdentityMapResponseItem, MapRequest to IdentityMapRequestItem - Renamed IUIDOperatorService.mapHashedDiiIdentity to mapHashedDii --- ...quest.java => IdentityMapRequestItem.java} | 4 +- ...onse.java => IdentityMapResponseItem.java} | 6 +- .../operator/service/IUIDOperatorService.java | 4 +- .../operator/service/UIDOperatorService.java | 22 +++--- .../operator/vertx/UIDOperatorVerticle.java | 20 +++--- .../uid2/operator/UIDOperatorServiceTest.java | 72 +++++++++---------- .../benchmark/IdentityMapBenchmark.java | 6 +- ....java => IdentityMapResponseItemTest.java} | 12 ++-- 8 files changed, 73 insertions(+), 73 deletions(-) rename src/main/java/com/uid2/operator/model/{MapRequest.java => IdentityMapRequestItem.java} (89%) rename src/main/java/com/uid2/operator/model/{RawUidResponse.java => IdentityMapResponseItem.java} (69%) rename src/test/java/com/uid2/operator/utilTests/{RawUidResponseTest.java => IdentityMapResponseItemTest.java} (55%) diff --git a/src/main/java/com/uid2/operator/model/MapRequest.java b/src/main/java/com/uid2/operator/model/IdentityMapRequestItem.java similarity index 89% rename from src/main/java/com/uid2/operator/model/MapRequest.java rename to src/main/java/com/uid2/operator/model/IdentityMapRequestItem.java index 660503041..9d982725e 100644 --- a/src/main/java/com/uid2/operator/model/MapRequest.java +++ b/src/main/java/com/uid2/operator/model/IdentityMapRequestItem.java @@ -4,12 +4,12 @@ import java.time.Instant; -public final class MapRequest { +public final class IdentityMapRequestItem { public final HashedDiiIdentity hashedDiiIdentity; public final OptoutCheckPolicy optoutCheckPolicy; public final Instant asOf; - public MapRequest( + public IdentityMapRequestItem( HashedDiiIdentity hashedDiiIdentity, OptoutCheckPolicy optoutCheckPolicy, Instant asOf) { diff --git a/src/main/java/com/uid2/operator/model/RawUidResponse.java b/src/main/java/com/uid2/operator/model/IdentityMapResponseItem.java similarity index 69% rename from src/main/java/com/uid2/operator/model/RawUidResponse.java rename to src/main/java/com/uid2/operator/model/IdentityMapResponseItem.java index bbd98931f..909596a2f 100644 --- a/src/main/java/com/uid2/operator/model/RawUidResponse.java +++ b/src/main/java/com/uid2/operator/model/IdentityMapResponseItem.java @@ -1,13 +1,13 @@ package com.uid2.operator.model; // Contains the computed raw UID and its bucket ID from identity/map request -public class RawUidResponse { - public static final RawUidResponse OptoutIdentity = new RawUidResponse(new byte[33], ""); +public class IdentityMapResponseItem { + public static final IdentityMapResponseItem OptoutIdentity = new IdentityMapResponseItem(new byte[33], ""); // The raw UID is also known as Advertising Id (historically) public final byte[] rawUid; public final String bucketId; - public RawUidResponse(byte[] rawUid, String bucketId) { + public IdentityMapResponseItem(byte[] rawUid, String bucketId) { this.rawUid = rawUid; this.bucketId = bucketId; } diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 6fec9288e..40636787c 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -16,10 +16,10 @@ public interface IUIDOperatorService { TokenRefreshResponse refreshIdentity(TokenRefreshRequest input); - RawUidResponse mapHashedDiiIdentity(MapRequest request); + IdentityMapResponseItem mapHashedDii(IdentityMapRequestItem request); @Deprecated - RawUidResponse map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + IdentityMapResponseItem map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index b4914c770..2510629ed 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -161,18 +161,18 @@ public TokenRefreshResponse refreshIdentity(TokenRefreshRequest input) { } @Override - public RawUidResponse mapHashedDiiIdentity(MapRequest request) { + public IdentityMapResponseItem mapHashedDii(IdentityMapRequestItem request) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, request.asOf); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { - return RawUidResponse.OptoutIdentity; + return IdentityMapResponseItem.OptoutIdentity; } else { return generateRawUid(firstLevelHashIdentity, request.asOf); } } @Override - public RawUidResponse map(HashedDiiIdentity diiIdentity, Instant asOf) { + public IdentityMapResponseItem map(HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); return generateRawUid(firstLevelHashIdentity, asOf); } @@ -195,9 +195,9 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { @Override public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, asOf); + final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHashIdentity, asOf); - this.optOutStore.addEntry(firstLevelHashIdentity, rawUidResponse.rawUid, r -> { + this.optOutStore.addEntry(firstLevelHashIdentity, identityMapResponseItem.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -209,10 +209,10 @@ public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, H @Override public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, asOf); + final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHashIdentity, asOf); final AdvertisingTokenRequest token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(rawUidResponse.rawUid, token.rawUidIdentity.rawUid); + return Arrays.equals(identityMapResponseItem.rawUid, token.rawUidIdentity.rawUid); } @Override @@ -239,10 +239,10 @@ private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private RawUidResponse generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { + private IdentityMapResponseItem generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); - return new RawUidResponse( + return new IdentityMapResponseItem( this.identityV3Enabled ? TokenUtils.getRawUidV3(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) @@ -254,10 +254,10 @@ private TokenGenerateResponse generateIdentity(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final RawUidResponse rawUidResponse = generateRawUid(firstLevelHashIdentity, nowUtc); + final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHashIdentity, nowUtc); final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, firstLevelHashIdentity.identityType, - rawUidResponse.rawUid); + identityMapResponseItem.rawUid); return this.encoder.encodeIntoIdentityResponse( this.createAdvertisingTokenRequest(sourcePublisher, rawUidIdentity, nowUtc, privacyBits, diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 8175cd25e..f8f1338d4 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -1237,11 +1237,11 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); + final IdentityMapResponseItem identityMapResponseItem = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); - jsonObject.put("advertising_id", EncodingUtils.toBase64String(rawUidResponse.rawUid)); - jsonObject.put("bucket_id", rawUidResponse.bucketId); + jsonObject.put("advertising_id", EncodingUtils.toBase64String(identityMapResponseItem.rawUid)); + jsonObject.put("bucket_id", identityMapResponseItem.bucketId); ResponseUtil.Success(rc, jsonObject); } catch (Exception e) { ResponseUtil.Error(ResponseStatus.UnknownError, 500, rc, "Unknown State", e); @@ -1254,8 +1254,8 @@ private void handleIdentityMap(RoutingContext rc) { try { if (isTokenInputValid(input, rc)) { final Instant now = Instant.now(); - final RawUidResponse rawUidResponse = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); - rc.response().end(EncodingUtils.toBase64String(rawUidResponse.rawUid)); + final IdentityMapResponseItem identityMapResponseItem = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); + rc.response().end(EncodingUtils.toBase64String(identityMapResponseItem.rawUid)); } } catch (Exception ex) { LOGGER.error("Unexpected error while mapping identity", ex); @@ -1450,13 +1450,13 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal for (int i = 0; i < count; ++i) { final InputUtil.InputVal input = inputList[i]; if (input != null && input.isValid()) { - final RawUidResponse rawUidResponse = idService.mapHashedDiiIdentity( - new MapRequest( + final IdentityMapResponseItem identityMapResponseItem = idService.mapHashedDii( + new IdentityMapRequestItem( input.toHashedDiiIdentity(this.identityScope), OptoutCheckPolicy.respectOptOut(), now)); - if (rawUidResponse.isOptedOut()) { + if (identityMapResponseItem.isOptedOut()) { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); resp.put("reason", "optout"); @@ -1465,8 +1465,8 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal } else { final JsonObject resp = new JsonObject(); resp.put("identifier", input.getProvided()); - resp.put("advertising_id", EncodingUtils.toBase64String(rawUidResponse.rawUid)); - resp.put("bucket_id", rawUidResponse.bucketId); + resp.put("advertising_id", EncodingUtils.toBase64String(identityMapResponseItem.rawUid)); + resp.put("bucket_id", identityMapResponseItem.bucketId); mapped.add(resp); } } else { diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 4ec802028..4e21b545d 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -348,12 +348,12 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(identity, scope, type); final Instant now = Instant.now(); - final MapRequest mapRequestForceMap = new MapRequest( + final IdentityMapRequestItem mapRequestForceIdentityMapItem = new IdentityMapRequestItem( hashedDiiIdentity, OptoutCheckPolicy.DoNotRespect, now); - final MapRequest mapRequestRespectOptOut = new MapRequest( + final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( hashedDiiIdentity, OptoutCheckPolicy.RespectOptOut, now); @@ -362,27 +362,27 @@ public void testIdentityMapForOptOutUser(IdentityType type, String identity, Ide when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); - final RawUidResponse rawUidResponse; - final RawUidResponse rawUidResponseShouldBeOptOut; + final IdentityMapResponseItem identityMapResponseItem; + final IdentityMapResponseItem identityMapResponseItemShouldBeOptOut; if (scope == IdentityScope.UID2) { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestForceMap); + identityMapResponseItem = uid2Service.mapHashedDii(mapRequestForceIdentityMapItem); reset(shutdownHandler); - rawUidResponseShouldBeOptOut = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItemShouldBeOptOut = uid2Service.mapHashedDii(identityMapRequestItemRespectOptOut); } else { verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestForceMap); + identityMapResponseItem = euidService.mapHashedDii(mapRequestForceIdentityMapItem); reset(shutdownHandler); - rawUidResponseShouldBeOptOut = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItemShouldBeOptOut = euidService.mapHashedDii(identityMapRequestItemRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResponse); - assertFalse(rawUidResponse.isOptedOut()); - assertNotNull(rawUidResponseShouldBeOptOut); - assertTrue(rawUidResponseShouldBeOptOut.isOptedOut()); + assertNotNull(identityMapResponseItem); + assertFalse(identityMapResponseItem.isOptedOut()); + assertNotNull(identityMapResponseItemShouldBeOptOut); + assertTrue(identityMapResponseItemShouldBeOptOut.isOptedOut()); } private enum TestIdentityInputType { @@ -461,7 +461,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final MapRequest mapRequestRespectOptOut = new MapRequest( + final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -469,17 +469,17 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, // identity has no optout record, ensure map still returns optout when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - final RawUidResponse rawUidResponse; + final IdentityMapResponseItem identityMapResponseItem; if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItem = euidService.mapHashedDii(identityMapRequestItemRespectOptOut); } else { - rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItem = uid2Service.mapHashedDii(identityMapRequestItemRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResponse); - assertTrue(rawUidResponse.isOptedOut()); + assertNotNull(identityMapResponseItem); + assertTrue(identityMapResponseItem.isOptedOut()); } @ParameterizedTest @@ -575,7 +575,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final MapRequest mapRequestRespectOptOut = new MapRequest( + final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -583,17 +583,17 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str // all identities have optout records, ensure refresh-optout identities still map when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUidResponse rawUidResponse; + final IdentityMapResponseItem identityMapResponseItem; if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItem = euidService.mapHashedDii(identityMapRequestItemRespectOptOut); } else { - rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItem = uid2Service.mapHashedDii(identityMapRequestItemRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResponse); - assertFalse(rawUidResponse.isOptedOut()); + assertNotNull(identityMapResponseItem); + assertFalse(identityMapResponseItem.isOptedOut()); } @ParameterizedTest @@ -646,7 +646,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String id, IdentityScope scope) { InputUtil.InputVal inputVal = generateInputVal(type, id); - final MapRequest mapRequestRespectOptOut = new MapRequest( + final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -654,17 +654,17 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i // all identities have optout records, ensure validate identities still get mapped when(this.optOutStore.getLatestEntry(any())).thenReturn(Instant.now()); - final RawUidResponse rawUidResponse; + final IdentityMapResponseItem identityMapResponseItem; if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItem = euidService.mapHashedDii(identityMapRequestItemRespectOptOut); } else { - rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequestRespectOptOut); + identityMapResponseItem = uid2Service.mapHashedDii(identityMapRequestItemRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - assertNotNull(rawUidResponse); - assertFalse(rawUidResponse.isOptedOut()); + assertNotNull(identityMapResponseItem); + assertFalse(identityMapResponseItem.isOptedOut()); } @ParameterizedTest @@ -768,22 +768,22 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String assertNotNull(refreshResponse.getIdentityResponse()); assertNotEquals(TokenRefreshResponse.Optout, refreshResponse); - final MapRequest mapRequest = new MapRequest( + final IdentityMapRequestItem identityMapRequestItem = new IdentityMapRequestItem( inputVal.toHashedDiiIdentity(scope), OptoutCheckPolicy.RespectOptOut, now); - final RawUidResponse rawUidResponse; + final IdentityMapResponseItem identityMapResponseItem; reset(shutdownHandler); if(scope == IdentityScope.EUID) { - rawUidResponse = euidService.mapHashedDiiIdentity(mapRequest); + identityMapResponseItem = euidService.mapHashedDii(identityMapRequestItem); } else { - rawUidResponse = uid2Service.mapHashedDiiIdentity(mapRequest); + identityMapResponseItem = uid2Service.mapHashedDii(identityMapRequestItem); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); - assertNotNull(rawUidResponse); - assertFalse(rawUidResponse.isOptedOut()); + assertNotNull(identityMapResponseItem); + assertFalse(identityMapResponseItem.isOptedOut()); } } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 59b033542..63652ab09 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -25,13 +25,13 @@ public class IdentityMapBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUidResponse IdentityMapRawThroughput() { + public IdentityMapResponseItem IdentityMapRawThroughput() { return uidService.map(hashedDiiIdentities[(idx++) & 65535], Instant.now()); } @Benchmark @BenchmarkMode(Mode.Throughput) - public RawUidResponse IdentityMapWithOptOutThroughput() { - return uidService.mapHashedDiiIdentity(new MapRequest(hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); + public IdentityMapResponseItem IdentityMapWithOptOutThroughput() { + return uidService.mapHashedDii(new IdentityMapRequestItem(hashedDiiIdentities[(idx++) & 65535], OptoutCheckPolicy.RespectOptOut, Instant.now())); } } diff --git a/src/test/java/com/uid2/operator/utilTests/RawUidResponseTest.java b/src/test/java/com/uid2/operator/utilTests/IdentityMapResponseItemTest.java similarity index 55% rename from src/test/java/com/uid2/operator/utilTests/RawUidResponseTest.java rename to src/test/java/com/uid2/operator/utilTests/IdentityMapResponseItemTest.java index 4e759b853..b45b2de6d 100644 --- a/src/test/java/com/uid2/operator/utilTests/RawUidResponseTest.java +++ b/src/test/java/com/uid2/operator/utilTests/IdentityMapResponseItemTest.java @@ -1,6 +1,6 @@ package com.uid2.operator.utilTests; -import com.uid2.operator.model.RawUidResponse; +import com.uid2.operator.model.IdentityMapResponseItem; import org.junit.Test; import java.security.NoSuchAlgorithmException; @@ -9,13 +9,13 @@ import static org.junit.Assert.*; -public class RawUidResponseTest { +public class IdentityMapResponseItemTest { @Test public void doRawUidResponseTest() throws NoSuchAlgorithmException { - assertEquals(RawUidResponse.OptoutIdentity.bucketId, ""); - assertTrue(RawUidResponse.OptoutIdentity.isOptedOut()); + assertEquals(IdentityMapResponseItem.OptoutIdentity.bucketId, ""); + assertTrue(IdentityMapResponseItem.OptoutIdentity.isOptedOut()); - RawUidResponse optoutResponse = new RawUidResponse(new byte[33], null); + IdentityMapResponseItem optoutResponse = new IdentityMapResponseItem(new byte[33], null); assertTrue(optoutResponse.isOptedOut()); byte[] rawUid = new byte[33]; @@ -23,7 +23,7 @@ public void doRawUidResponseTest() throws NoSuchAlgorithmException { rawUid[i] = (byte) i; } - RawUidResponse generatedUid = new RawUidResponse(rawUid, "12345"); + IdentityMapResponseItem generatedUid = new IdentityMapResponseItem(rawUid, "12345"); assertFalse(generatedUid.isOptedOut()); assertTrue(Arrays.equals(rawUid, generatedUid.rawUid)); } From 6bb1fb9fda166dcd37ca488e06e57018cfd4a3ca Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 9 Dec 2024 18:07:00 +1100 Subject: [PATCH 60/61] 1. Renamed FirstLevelHashIdentity/HashedDiiIdentity/RawUidIdentity to FirstLevelHash/HashedDii/RawUid 2. Removed the abstract class UserIdentity 3. fixed a unit test as removing UserIdentity broke it --- .../model/AdvertisingTokenRequest.java | 8 +- .../model/IdentityMapRequestItem.java | 8 +- .../operator/model/TokenGenerateRequest.java | 12 +- .../operator/model/TokenRefreshRequest.java | 8 +- .../model/identities/FirstLevelHash.java | 22 ++++ .../operator/model/identities/HashedDii.java | 9 ++ .../operator/model/identities/RawUid.java | 16 +++ .../userIdentity/FirstLevelHashIdentity.java | 30 ----- .../model/userIdentity/HashedDiiIdentity.java | 17 --- .../model/userIdentity/RawUidIdentity.java | 23 ---- .../model/userIdentity/UserIdentity.java | 16 --- .../service/EncryptedTokenEncoder.java | 42 +++---- .../operator/service/IUIDOperatorService.java | 10 +- .../com/uid2/operator/service/InputUtil.java | 8 +- .../operator/service/UIDOperatorService.java | 118 +++++++++--------- .../operator/store/CloudSyncOptOutStore.java | 10 +- .../com/uid2/operator/store/IOptOutStore.java | 8 +- .../operator/vertx/UIDOperatorVerticle.java | 6 +- .../com/uid2/operator/TokenEncodingTest.java | 14 +-- .../uid2/operator/UIDOperatorServiceTest.java | 99 +++++++++------ .../operator/UIDOperatorVerticleTest.java | 64 +++++----- .../operator/benchmark/BenchmarkCommon.java | 16 +-- .../benchmark/IdentityMapBenchmark.java | 4 +- .../benchmark/TokenEndecBenchmark.java | 4 +- 24 files changed, 276 insertions(+), 296 deletions(-) create mode 100644 src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java create mode 100644 src/main/java/com/uid2/operator/model/identities/HashedDii.java create mode 100644 src/main/java/com/uid2/operator/model/identities/RawUid.java delete mode 100644 src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java delete mode 100644 src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java delete mode 100644 src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java delete mode 100644 src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java diff --git a/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java b/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java index f9a41caf6..d63fa66a8 100644 --- a/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java +++ b/src/main/java/com/uid2/operator/model/AdvertisingTokenRequest.java @@ -2,7 +2,7 @@ import java.time.Instant; -import com.uid2.operator.model.userIdentity.RawUidIdentity; +import com.uid2.operator.model.identities.RawUid; import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.TokenVersion; @@ -10,17 +10,17 @@ public class AdvertisingTokenRequest extends VersionedTokenRequest { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; - public final RawUidIdentity rawUidIdentity; + public final RawUid rawUid; public final PrivacyBits privacyBits; public final Instant establishedAt; public AdvertisingTokenRequest(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, PrivacyBits privacyBits, + SourcePublisher sourcePublisher, RawUid rawUid, PrivacyBits privacyBits, Instant establishedAt) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.sourcePublisher = sourcePublisher; - this.rawUidIdentity = rawUidIdentity; + this.rawUid = rawUid; this.privacyBits = privacyBits; this.establishedAt = establishedAt; } diff --git a/src/main/java/com/uid2/operator/model/IdentityMapRequestItem.java b/src/main/java/com/uid2/operator/model/IdentityMapRequestItem.java index 9d982725e..079af8e76 100644 --- a/src/main/java/com/uid2/operator/model/IdentityMapRequestItem.java +++ b/src/main/java/com/uid2/operator/model/IdentityMapRequestItem.java @@ -1,19 +1,19 @@ package com.uid2.operator.model; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.identities.HashedDii; import java.time.Instant; public final class IdentityMapRequestItem { - public final HashedDiiIdentity hashedDiiIdentity; + public final HashedDii hashedDii; public final OptoutCheckPolicy optoutCheckPolicy; public final Instant asOf; public IdentityMapRequestItem( - HashedDiiIdentity hashedDiiIdentity, + HashedDii hashedDii, OptoutCheckPolicy optoutCheckPolicy, Instant asOf) { - this.hashedDiiIdentity = hashedDiiIdentity; + this.hashedDii = hashedDii; this.optoutCheckPolicy = optoutCheckPolicy; this.asOf = asOf; } diff --git a/src/main/java/com/uid2/operator/model/TokenGenerateRequest.java b/src/main/java/com/uid2/operator/model/TokenGenerateRequest.java index f482e8d21..39f3b56fc 100644 --- a/src/main/java/com/uid2/operator/model/TokenGenerateRequest.java +++ b/src/main/java/com/uid2/operator/model/TokenGenerateRequest.java @@ -1,13 +1,13 @@ package com.uid2.operator.model; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.identities.HashedDii; import com.uid2.operator.util.PrivacyBits; import java.time.Instant; public final class TokenGenerateRequest { public final SourcePublisher sourcePublisher; - public final HashedDiiIdentity hashedDiiIdentity; + public final HashedDii hashedDii; public final OptoutCheckPolicy optoutCheckPolicy; public final PrivacyBits privacyBits; @@ -15,12 +15,12 @@ public final class TokenGenerateRequest { public TokenGenerateRequest( SourcePublisher sourcePublisher, - HashedDiiIdentity hashedDiiIdentity, + HashedDii hashedDii, OptoutCheckPolicy tokenGeneratePolicy, PrivacyBits privacyBits, Instant establishedAt) { this.sourcePublisher = sourcePublisher; - this.hashedDiiIdentity = hashedDiiIdentity; + this.hashedDii = hashedDii; this.optoutCheckPolicy = tokenGeneratePolicy; this.privacyBits = privacyBits; this.establishedAt = establishedAt; @@ -28,9 +28,9 @@ public TokenGenerateRequest( public TokenGenerateRequest( SourcePublisher sourcePublisher, - HashedDiiIdentity hashedDiiIdentity, + HashedDii hashedDii, OptoutCheckPolicy tokenGeneratePolicy) { - this(sourcePublisher, hashedDiiIdentity, tokenGeneratePolicy, PrivacyBits.DEFAULT, Instant.now()); + this(sourcePublisher, hashedDii, tokenGeneratePolicy, PrivacyBits.DEFAULT, Instant.now()); } diff --git a/src/main/java/com/uid2/operator/model/TokenRefreshRequest.java b/src/main/java/com/uid2/operator/model/TokenRefreshRequest.java index f5cc8b6eb..e2e51971a 100644 --- a/src/main/java/com/uid2/operator/model/TokenRefreshRequest.java +++ b/src/main/java/com/uid2/operator/model/TokenRefreshRequest.java @@ -2,7 +2,7 @@ import java.time.Instant; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.TokenVersion; @@ -10,17 +10,17 @@ public class TokenRefreshRequest extends VersionedTokenRequest { public final OperatorIdentity operatorIdentity; public final SourcePublisher sourcePublisher; - public final FirstLevelHashIdentity firstLevelHashIdentity; + public final FirstLevelHash firstLevelHash; // by default, inherited from the previous refresh token's privacy bits public final PrivacyBits privacyBits; public TokenRefreshRequest(TokenVersion version, Instant createdAt, Instant expiresAt, OperatorIdentity operatorIdentity, - SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { + SourcePublisher sourcePublisher, FirstLevelHash firstLevelHash, PrivacyBits privacyBits) { super(version, createdAt, expiresAt); this.operatorIdentity = operatorIdentity; this.sourcePublisher = sourcePublisher; - this.firstLevelHashIdentity = firstLevelHashIdentity; + this.firstLevelHash = firstLevelHash; this.privacyBits = privacyBits; } } diff --git a/src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java b/src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java new file mode 100644 index 000000000..d46cc0ad5 --- /dev/null +++ b/src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java @@ -0,0 +1,22 @@ +package com.uid2.operator.model.identities; + +import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.IdentityType; + +import java.time.Instant; +import java.util.Arrays; + +/** + * Contains a first level salted hash computed from Hashed DII (email/phone number) + * @param establishedAt for brand new token generation, it should be the time it is generated if the first level hash is from token/refresh call, it will be when the raw UID was originally created in the earliest token generation + */ +public record FirstLevelHash(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, + Instant establishedAt) { + + // explicitly not checking establishedAt - this is only for making sure the first level hash matches a new input + public boolean matches(FirstLevelHash that) { + return this.identityScope.equals(that.identityScope) && + this.identityType.equals(that.identityType) && + Arrays.equals(this.firstLevelHash, that.firstLevelHash); + } +} diff --git a/src/main/java/com/uid2/operator/model/identities/HashedDii.java b/src/main/java/com/uid2/operator/model/identities/HashedDii.java new file mode 100644 index 000000000..da040c066 --- /dev/null +++ b/src/main/java/com/uid2/operator/model/identities/HashedDii.java @@ -0,0 +1,9 @@ +package com.uid2.operator.model.identities; + +import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.IdentityType; + +// Contains a hash DII, +// This hash can either be computed from a raw email/phone number DII input or provided by the UID Participant directly +public record HashedDii(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii) { +} diff --git a/src/main/java/com/uid2/operator/model/identities/RawUid.java b/src/main/java/com/uid2/operator/model/identities/RawUid.java new file mode 100644 index 000000000..775c7c46a --- /dev/null +++ b/src/main/java/com/uid2/operator/model/identities/RawUid.java @@ -0,0 +1,16 @@ +package com.uid2.operator.model.identities; + +import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.IdentityType; + +import java.util.Arrays; + +// A raw UID is stored inside +public record RawUid(IdentityScope identityScope, IdentityType identityType, byte[] rawUid) { + + public boolean matches(RawUid that) { + return this.identityScope.equals(that.identityScope) && + this.identityType.equals(that.identityType) && + Arrays.equals(this.rawUid, that.rawUid); + } +} diff --git a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java deleted file mode 100644 index 4df2b1c6c..000000000 --- a/src/main/java/com/uid2/operator/model/userIdentity/FirstLevelHashIdentity.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.uid2.operator.model.userIdentity; - -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; - -import java.time.Instant; -import java.util.Arrays; - -// Contains a first level salted hash computed from Hashed DII (email/phone number) -public class FirstLevelHashIdentity extends UserIdentity { - public final byte[] firstLevelHash; - - // for brand new token generation, it should be the time it is generated - // if the first level hash is from token/refresh call, it will be when the raw UID was originally created in the earliest token generation - public final Instant establishedAt; - - public FirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, - Instant establishedAt) { - super(identityScope, identityType); - this.firstLevelHash = firstLevelHash; - this.establishedAt = establishedAt; - } - - // explicitly not checking establishedAt - this is only for making sure the first level hash matches a new input - public boolean matches(FirstLevelHashIdentity that) { - return this.identityScope.equals(that.identityScope) && - this.identityType.equals(that.identityType) && - Arrays.equals(this.firstLevelHash, that.firstLevelHash); - } -} diff --git a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java deleted file mode 100644 index a9a6efe0a..000000000 --- a/src/main/java/com/uid2/operator/model/userIdentity/HashedDiiIdentity.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.uid2.operator.model.userIdentity; - -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; - -import java.time.Instant; - -// Contains a hash DII, -// This hash can either be computed from a raw email/phone number DII input or provided by the UID Participant directly -public class HashedDiiIdentity extends UserIdentity { - public final byte[] hashedDii; - - public HashedDiiIdentity(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii) { - super(identityScope, identityType); - this.hashedDii = hashedDii; - } -} diff --git a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java deleted file mode 100644 index b86740a05..000000000 --- a/src/main/java/com/uid2/operator/model/userIdentity/RawUidIdentity.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.uid2.operator.model.userIdentity; - -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; - -import java.time.Instant; -import java.util.Arrays; - -// A raw UID is stored inside -public class RawUidIdentity extends UserIdentity { - public final byte[] rawUid; - - public RawUidIdentity(IdentityScope identityScope, IdentityType identityType, byte[] rawUid) { - super(identityScope, identityType); - this.rawUid = rawUid; - } - - public boolean matches(RawUidIdentity that) { - return this.identityScope.equals(that.identityScope) && - this.identityType.equals(that.identityType) && - Arrays.equals(this.rawUid, that.rawUid); - } -} diff --git a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java b/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java deleted file mode 100644 index 8b6c042c5..000000000 --- a/src/main/java/com/uid2/operator/model/userIdentity/UserIdentity.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.uid2.operator.model.userIdentity; - -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; - -//base class for all other HashedDii/FirstLevelHash/RawUIDIdentity class and define the basic common fields -public abstract class UserIdentity { - - public final IdentityScope identityScope; - public final IdentityType identityType; - - public UserIdentity(IdentityScope identityScope, IdentityType identityType) { - this.identityScope = identityScope; - this.identityType = identityType; - } -} diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 06570391e..87f86b244 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -1,8 +1,8 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; -import com.uid2.operator.model.userIdentity.RawUidIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; +import com.uid2.operator.model.identities.RawUid; import com.uid2.operator.util.PrivacyBits; import com.uid2.operator.vertx.ClientInputValidationException; import com.uid2.shared.Const.Data; @@ -42,7 +42,7 @@ private byte[] encodeIntoAdvertisingTokenV2(AdvertisingTokenRequest t, KeysetKey Buffer b2 = Buffer.buffer(); b2.appendLong(t.expiresAt.toEpochMilli()); - encodeSiteIdentityV2(b2, t.sourcePublisher, t.rawUidIdentity, siteKey, t.privacyBits, t.establishedAt); + encodeSiteIdentityV2(b2, t.sourcePublisher, t.rawUid, siteKey, t.privacyBits, t.establishedAt); final byte[] encryptedId = AesCbc.encrypt(b2.getBytes(), masterKey).getPayload(); @@ -59,7 +59,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenRequest t, KeysetKey // this is the refreshedAt field in the spec - but effectively it is the time this advertising token is generated // this is a redundant field as it is stored in master payload again, can consider dropping this field in future token version sitePayload.appendLong(t.createdAt.toEpochMilli()); - sitePayload.appendBytes(t.rawUidIdentity.rawUid); // 32 or 33 bytes + sitePayload.appendBytes(t.rawUid.rawUid()); // 32 or 33 bytes final Buffer masterPayload = Buffer.buffer(130); masterPayload.appendLong(t.expiresAt.toEpochMilli()); @@ -69,7 +69,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenRequest t, KeysetKey masterPayload.appendBytes(AesGcm.encrypt(sitePayload.getBytes(), siteKey).getPayload()); final Buffer b = Buffer.buffer(164); - b.appendByte(encodeIdentityTypeV3(t.rawUidIdentity.identityScope, t.rawUidIdentity.identityType)); + b.appendByte(encodeIdentityTypeV3(t.rawUid.identityScope(), t.rawUid.identityType())); b.appendByte((byte) t.version.rawVersion); b.appendInt(masterKey.getId()); b.appendBytes(AesGcm.encrypt(masterPayload.getBytes(), masterKey).getPayload()); @@ -129,7 +129,7 @@ private TokenRefreshRequest decodeRefreshTokenV2(Buffer b) { TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), new SourcePublisher(siteId), - new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, identity, + new FirstLevelHash(IdentityScope.UID2, IdentityType.Email, identity, Instant.ofEpochMilli(establishedMillis)), privacyBits); } @@ -164,7 +164,7 @@ private TokenRefreshRequest decodeRefreshTokenV3(Buffer b, byte[] bytes) { return new TokenRefreshRequest( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, establishedAt), + new FirstLevelHash(identityScope, identityType, firstLevelHash, establishedAt), privacyBits); } @@ -233,7 +233,7 @@ public AdvertisingTokenRequest decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new SourcePublisher(siteId, siteKeyId, 0), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid), + new RawUid(IdentityScope.UID2, IdentityType.Email, rawUid), privacyBits, Instant.ofEpochMilli(establishedMillis) ); @@ -276,7 +276,7 @@ public AdvertisingTokenRequest decodeAdvertisingTokenV3orV4(Buffer b, byte[] byt return new AdvertisingTokenRequest( tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new RawUidIdentity(identityScope, identityType, rawUid), + new RawUid(identityScope, identityType, rawUid), privacyBits, establishedAt ); } @@ -312,7 +312,7 @@ public byte[] encodeIntoRefreshTokenV2(TokenRefreshRequest t, KeysetKey serviceK // give an extra minute for clients which are trying to refresh tokens close to or at the refresh expiry timestamp b.appendLong(t.expiresAt.plusSeconds(60).toEpochMilli()); b.appendInt(serviceKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(t.sourcePublisher, t.firstLevelHashIdentity, serviceKey, + final byte[] encryptedIdentity = encryptIdentityV2(t.sourcePublisher, t.firstLevelHash, serviceKey, t.privacyBits); b.appendBytes(encryptedIdentity); return b.getBytes(); @@ -325,12 +325,12 @@ public byte[] encodeIntoRefreshTokenV3(TokenRefreshRequest t, KeysetKey serviceK encodeOperatorIdentityV3(refreshPayload, t.operatorIdentity); encodePublisherRequesterV3(refreshPayload, t.sourcePublisher); refreshPayload.appendInt(t.privacyBits.getAsInt()); - refreshPayload.appendLong(t.firstLevelHashIdentity.establishedAt.toEpochMilli()); - refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHashIdentity.identityScope, t.firstLevelHashIdentity.identityType)); - refreshPayload.appendBytes(t.firstLevelHashIdentity.firstLevelHash); + refreshPayload.appendLong(t.firstLevelHash.establishedAt().toEpochMilli()); + refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHash.identityScope(), t.firstLevelHash.identityType())); + refreshPayload.appendBytes(t.firstLevelHash.firstLevelHash()); final Buffer b = Buffer.buffer(124); - b.appendByte(encodeIdentityTypeV3(t.firstLevelHashIdentity.identityScope, t.firstLevelHashIdentity.identityType)); + b.appendByte(encodeIdentityTypeV3(t.firstLevelHash.identityScope(), t.firstLevelHash.identityType())); b.appendByte((byte) t.version.rawVersion); b.appendInt(serviceKey.getId()); b.appendBytes(AesGcm.encrypt(refreshPayload.getBytes(), serviceKey).getPayload()); @@ -338,10 +338,10 @@ public byte[] encodeIntoRefreshTokenV3(TokenRefreshRequest t, KeysetKey serviceK return b.getBytes(); } - private void encodeSiteIdentityV2(Buffer b, SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, + private void encodeSiteIdentityV2(Buffer b, SourcePublisher sourcePublisher, RawUid rawUid, KeysetKey siteEncryptionKey, PrivacyBits privacyBits, Instant establishedAt) { b.appendInt(siteEncryptionKey.getId()); - final byte[] encryptedIdentity = encryptIdentityV2(sourcePublisher, rawUidIdentity, siteEncryptionKey, privacyBits, establishedAt); + final byte[] encryptedIdentity = encryptIdentityV2(sourcePublisher, rawUid, siteEncryptionKey, privacyBits, establishedAt); b.appendBytes(encryptedIdentity); } @@ -373,15 +373,15 @@ private String generateAdvertisingTokenString(AdvertisingTokenRequest advertisin return bytesToBase64Token(advertisingTokenBytes, advertisingTokenRequest.version); } - private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHashIdentity firstLevelHashIdentity, + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, FirstLevelHash firstLevelHash, KeysetKey key, PrivacyBits privacyBits) { - return encryptIdentityV2(sourcePublisher, firstLevelHashIdentity.firstLevelHash, privacyBits, - firstLevelHashIdentity.establishedAt, key); + return encryptIdentityV2(sourcePublisher, firstLevelHash.firstLevelHash(), privacyBits, + firstLevelHash.establishedAt(), key); } - private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, + private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, RawUid rawUid, KeysetKey key, PrivacyBits privacyBits, Instant establishedAt) { - return encryptIdentityV2(sourcePublisher, rawUidIdentity.rawUid, privacyBits, + return encryptIdentityV2(sourcePublisher, rawUid.rawUid(), privacyBits, establishedAt, key); } diff --git a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java index 40636787c..c53e66057 100644 --- a/src/main/java/com/uid2/operator/service/IUIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/IUIDOperatorService.java @@ -1,7 +1,7 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.identities.HashedDii; import com.uid2.shared.model.SaltEntry; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; @@ -19,15 +19,15 @@ public interface IUIDOperatorService { IdentityMapResponseItem mapHashedDii(IdentityMapRequestItem request); @Deprecated - IdentityMapResponseItem map(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + IdentityMapResponseItem map(HashedDii hashedDii, Instant asOf); List getModifiedBuckets(Instant sinceTimestamp); - void invalidateTokensAsync(HashedDiiIdentity hashedDiiIdentity, Instant asOf, Handler> handler); + void invalidateTokensAsync(HashedDii hashedDii, Instant asOf, Handler> handler); - boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity hashedDiiIdentity, Instant asOf); + boolean advertisingTokenMatches(String advertisingToken, HashedDii hashedDii, Instant asOf); - Instant getLatestOptoutEntry(HashedDiiIdentity hashedDiiIdentity, Instant asOf); + Instant getLatestOptoutEntry(HashedDii hashedDii, Instant asOf); Duration getIdentityExpiryDuration(); } diff --git a/src/main/java/com/uid2/operator/service/InputUtil.java b/src/main/java/com/uid2/operator/service/InputUtil.java index 8e44e5717..9610d20f3 100644 --- a/src/main/java/com/uid2/operator/service/InputUtil.java +++ b/src/main/java/com/uid2/operator/service/InputUtil.java @@ -2,9 +2,7 @@ import com.uid2.operator.model.IdentityScope; import com.uid2.operator.model.IdentityType; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; - -import java.time.Instant; +import com.uid2.operator.model.identities.HashedDii; public class InputUtil { @@ -261,8 +259,8 @@ public boolean isValid() { return valid; } - public HashedDiiIdentity toHashedDiiIdentity(IdentityScope identityScope) { - return new HashedDiiIdentity( + public HashedDii toHashedDiiIdentity(IdentityScope identityScope) { + return new HashedDii( identityScope, this.identityType, getIdentityInput()); diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 2510629ed..703735e49 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -1,9 +1,9 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; -import com.uid2.operator.model.userIdentity.RawUidIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; +import com.uid2.operator.model.identities.HashedDii; +import com.uid2.operator.model.identities.RawUid; import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.SaltEntry; import com.uid2.operator.store.IOptOutStore; @@ -39,12 +39,12 @@ public class UIDOperatorService implements IUIDOperatorService { private final EncryptedTokenEncoder encoder; private final Clock clock; private final IdentityScope identityScope; - private final FirstLevelHashIdentity testOptOutIdentityForEmail; - private final FirstLevelHashIdentity testOptOutIdentityForPhone; - private final FirstLevelHashIdentity testValidateIdentityForEmail; - private final FirstLevelHashIdentity testValidateIdentityForPhone; - private final FirstLevelHashIdentity testRefreshOptOutIdentityForEmail; - private final FirstLevelHashIdentity testRefreshOptOutIdentityForPhone; + private final FirstLevelHash testOptOutIdentityForEmail; + private final FirstLevelHash testOptOutIdentityForPhone; + private final FirstLevelHash testValidateIdentityForEmail; + private final FirstLevelHash testValidateIdentityForPhone; + private final FirstLevelHash testRefreshOptOutIdentityForEmail; + private final FirstLevelHash testRefreshOptOutIdentityForPhone; private final Duration identityExpiresAfter; private final Duration refreshExpiresAfter; private final Duration refreshIdentityAfter; @@ -107,9 +107,9 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv @Override public TokenGenerateResponse generateIdentity(TokenGenerateRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); - final byte[] firstLevelHash = getFirstLevelHash(request.hashedDiiIdentity.hashedDii, now); - final FirstLevelHashIdentity firstLevelHashIdentity = new FirstLevelHashIdentity( - request.hashedDiiIdentity.identityScope, request.hashedDiiIdentity.identityType, firstLevelHash, + final byte[] firstLevelHash = getFirstLevelHash(request.hashedDii.hashedDii(), now); + final FirstLevelHash firstLevelHashIdentity = new FirstLevelHash( + request.hashedDii.identityScope(), request.hashedDii.identityType(), firstLevelHash, request.establishedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { @@ -122,11 +122,11 @@ public TokenGenerateResponse generateIdentity(TokenGenerateRequest request) { @Override public TokenRefreshResponse refreshIdentity(TokenRefreshRequest input) { // should not be possible as different scopes should be using different keys, but just in case - if (input.firstLevelHashIdentity.identityScope != this.identityScope) { + if (input.firstLevelHash.identityScope() != this.identityScope) { return TokenRefreshResponse.Invalid; } - if (input.firstLevelHashIdentity.establishedAt.isBefore(RefreshCutoff)) { + if (input.firstLevelHash.establishedAt().isBefore(RefreshCutoff)) { return TokenRefreshResponse.Deprecated; } @@ -139,14 +139,14 @@ public TokenRefreshResponse refreshIdentity(TokenRefreshRequest input) { final boolean isCstg = input.privacyBits.isClientSideTokenGenerated(); try { - final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(input.firstLevelHashIdentity, true); + final GlobalOptoutResult logoutEntry = getGlobalOptOutResult(input.firstLevelHash, true); final boolean optedOut = logoutEntry.isOptedOut(); final Duration durationSinceLastRefresh = Duration.between(input.createdAt, now); if (!optedOut) { TokenGenerateResponse tokenGenerateResponse = this.generateIdentity(input.sourcePublisher, - input.firstLevelHashIdentity, + input.firstLevelHash, input.privacyBits); return TokenRefreshResponse.createRefreshedResponse(tokenGenerateResponse, durationSinceLastRefresh, isCstg); @@ -162,19 +162,19 @@ public TokenRefreshResponse refreshIdentity(TokenRefreshRequest input) { @Override public IdentityMapResponseItem mapHashedDii(IdentityMapRequestItem request) { - final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(request.hashedDiiIdentity, + final FirstLevelHash firstLevelHash = getFirstLevelHashIdentity(request.hashedDii, request.asOf); - if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { + if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHash, false).isOptedOut()) { return IdentityMapResponseItem.OptoutIdentity; } else { - return generateRawUid(firstLevelHashIdentity, request.asOf); + return generateRawUid(firstLevelHash, request.asOf); } } @Override - public IdentityMapResponseItem map(HashedDiiIdentity diiIdentity, Instant asOf) { - final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - return generateRawUid(firstLevelHashIdentity, asOf); + public IdentityMapResponseItem map(HashedDii diiIdentity, Instant asOf) { + final FirstLevelHash firstLevelHash = getFirstLevelHashIdentity(diiIdentity, asOf); + return generateRawUid(firstLevelHash, asOf); } @Override @@ -193,11 +193,11 @@ private ISaltProvider.ISaltSnapshot getSaltProviderSnapshot(Instant asOf) { } @Override - public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, Handler> handler) { - final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHashIdentity, asOf); + public void invalidateTokensAsync(HashedDii diiIdentity, Instant asOf, Handler> handler) { + final FirstLevelHash firstLevelHash = getFirstLevelHashIdentity(diiIdentity, asOf); + final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHash, asOf); - this.optOutStore.addEntry(firstLevelHashIdentity, identityMapResponseItem.rawUid, r -> { + this.optOutStore.addEntry(firstLevelHash, identityMapResponseItem.rawUid, r -> { if (r.succeeded()) { handler.handle(Future.succeededFuture(r.result())); } else { @@ -207,18 +207,18 @@ public void invalidateTokensAsync(HashedDiiIdentity diiIdentity, Instant asOf, H } @Override - public boolean advertisingTokenMatches(String advertisingToken, HashedDiiIdentity diiIdentity, Instant asOf) { - final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(diiIdentity, asOf); - final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHashIdentity, asOf); + public boolean advertisingTokenMatches(String advertisingToken, HashedDii diiIdentity, Instant asOf) { + final FirstLevelHash firstLevelHash = getFirstLevelHashIdentity(diiIdentity, asOf); + final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHash, asOf); final AdvertisingTokenRequest token = this.encoder.decodeAdvertisingToken(advertisingToken); - return Arrays.equals(identityMapResponseItem.rawUid, token.rawUidIdentity.rawUid); + return Arrays.equals(identityMapResponseItem.rawUid, token.rawUid.rawUid()); } @Override - public Instant getLatestOptoutEntry(HashedDiiIdentity hashedDiiIdentity, Instant asOf) { - final FirstLevelHashIdentity firstLevelHashIdentity = getFirstLevelHashIdentity(hashedDiiIdentity, asOf); - return this.optOutStore.getLatestEntry(firstLevelHashIdentity); + public Instant getLatestOptoutEntry(HashedDii hashedDii, Instant asOf) { + final FirstLevelHash firstLevelHash = getFirstLevelHashIdentity(hashedDii, asOf); + return this.optOutStore.getLatestEntry(firstLevelHash); } @Override @@ -226,50 +226,50 @@ public Duration getIdentityExpiryDuration() { return this.identityExpiresAfter; } - private FirstLevelHashIdentity getFirstLevelHashIdentity(HashedDiiIdentity hashedDiiIdentity, Instant asOf) { - return getFirstLevelHashIdentity(hashedDiiIdentity.identityScope, hashedDiiIdentity.identityType, hashedDiiIdentity.hashedDii, asOf); + private FirstLevelHash getFirstLevelHashIdentity(HashedDii hashedDii, Instant asOf) { + return getFirstLevelHashIdentity(hashedDii.identityScope(), hashedDii.identityType(), hashedDii.hashedDii(), asOf); } - private FirstLevelHashIdentity getFirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] identityHash, Instant asOf) { + private FirstLevelHash getFirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] identityHash, Instant asOf) { final byte[] firstLevelHash = getFirstLevelHash(identityHash, asOf); - return new FirstLevelHashIdentity(identityScope, identityType, firstLevelHash, null); + return new FirstLevelHash(identityScope, identityType, firstLevelHash, null); } private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { return TokenUtils.getFirstLevelHash(identityHash, getSaltProviderSnapshot(asOf).getFirstLevelSalt()); } - private IdentityMapResponseItem generateRawUid(FirstLevelHashIdentity firstLevelHashIdentity, Instant asOf) { - final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHashIdentity.firstLevelHash); + private IdentityMapResponseItem generateRawUid(FirstLevelHash firstLevelHash, Instant asOf) { + final SaltEntry rotatingSalt = getSaltProviderSnapshot(asOf).getRotatingSalt(firstLevelHash.firstLevelHash()); return new IdentityMapResponseItem( this.identityV3Enabled - ? TokenUtils.getRawUidV3(firstLevelHashIdentity.identityScope, - firstLevelHashIdentity.identityType, firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()) - : TokenUtils.getRawUidV2(firstLevelHashIdentity.firstLevelHash, rotatingSalt.getSalt()), + ? TokenUtils.getRawUidV3(firstLevelHash.identityScope(), + firstLevelHash.identityType(), firstLevelHash.firstLevelHash(), rotatingSalt.getSalt()) + : TokenUtils.getRawUidV2(firstLevelHash.firstLevelHash(), rotatingSalt.getSalt()), rotatingSalt.getHashedId()); } private TokenGenerateResponse generateIdentity(SourcePublisher sourcePublisher, - FirstLevelHashIdentity firstLevelHashIdentity, PrivacyBits privacyBits) { + FirstLevelHash firstLevelHash, PrivacyBits privacyBits) { final Instant nowUtc = EncodingUtils.NowUTCMillis(this.clock); - final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHashIdentity, nowUtc); - final RawUidIdentity rawUidIdentity = new RawUidIdentity(firstLevelHashIdentity.identityScope, - firstLevelHashIdentity.identityType, + final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHash, nowUtc); + final RawUid rawUid = new RawUid(firstLevelHash.identityScope(), + firstLevelHash.identityType(), identityMapResponseItem.rawUid); return this.encoder.encodeIntoIdentityResponse( - this.createAdvertisingTokenRequest(sourcePublisher, rawUidIdentity, nowUtc, privacyBits, - firstLevelHashIdentity.establishedAt), - this.createTokenRefreshRequest(sourcePublisher, firstLevelHashIdentity, nowUtc, privacyBits), + this.createAdvertisingTokenRequest(sourcePublisher, rawUid, nowUtc, privacyBits, + firstLevelHash.establishedAt()), + this.createTokenRefreshRequest(sourcePublisher, firstLevelHash, nowUtc, privacyBits), nowUtc.plusMillis(refreshIdentityAfter.toMillis()), nowUtc ); } private TokenRefreshRequest createTokenRefreshRequest(SourcePublisher sourcePublisher, - FirstLevelHashIdentity firstLevelHashIdentity, + FirstLevelHash firstLevelHash, Instant now, PrivacyBits privacyBits) { return new TokenRefreshRequest( @@ -278,18 +278,18 @@ private TokenRefreshRequest createTokenRefreshRequest(SourcePublisher sourcePubl now.plusMillis(refreshExpiresAfter.toMillis()), this.operatorIdentity, sourcePublisher, - firstLevelHashIdentity, + firstLevelHash, privacyBits); } - private AdvertisingTokenRequest createAdvertisingTokenRequest(SourcePublisher sourcePublisher, RawUidIdentity rawUidIdentity, + private AdvertisingTokenRequest createAdvertisingTokenRequest(SourcePublisher sourcePublisher, RawUid rawUidIdentity, Instant now, PrivacyBits privacyBits, Instant establishedAt) { TokenVersion tokenVersion; if (siteIdsUsingV4Tokens.contains(sourcePublisher.siteId)) { tokenVersion = TokenVersion.V4; } else { int pseudoRandomNumber = 1; - final var rawUid = rawUidIdentity.rawUid; + final var rawUid = rawUidIdentity.rawUid(); 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 @@ -322,16 +322,16 @@ public Instant getTime() { } } - private GlobalOptoutResult getGlobalOptOutResult(FirstLevelHashIdentity firstLevelHashIdentity, boolean forRefresh) { - if (forRefresh && (firstLevelHashIdentity.matches(testRefreshOptOutIdentityForEmail) || firstLevelHashIdentity.matches(testRefreshOptOutIdentityForPhone))) { + private GlobalOptoutResult getGlobalOptOutResult(FirstLevelHash firstLevelHash, boolean forRefresh) { + if (forRefresh && (firstLevelHash.matches(testRefreshOptOutIdentityForEmail) || firstLevelHash.matches(testRefreshOptOutIdentityForPhone))) { return new GlobalOptoutResult(Instant.now()); - } else if (firstLevelHashIdentity.matches(testValidateIdentityForEmail) || firstLevelHashIdentity.matches(testValidateIdentityForPhone) - || firstLevelHashIdentity.matches(testRefreshOptOutIdentityForEmail) || firstLevelHashIdentity.matches(testRefreshOptOutIdentityForPhone)) { + } else if (firstLevelHash.matches(testValidateIdentityForEmail) || firstLevelHash.matches(testValidateIdentityForPhone) + || firstLevelHash.matches(testRefreshOptOutIdentityForEmail) || firstLevelHash.matches(testRefreshOptOutIdentityForPhone)) { return new GlobalOptoutResult(null); - } else if (firstLevelHashIdentity.matches(testOptOutIdentityForEmail) || firstLevelHashIdentity.matches(testOptOutIdentityForPhone)) { + } else if (firstLevelHash.matches(testOptOutIdentityForEmail) || firstLevelHash.matches(testOptOutIdentityForPhone)) { return new GlobalOptoutResult(Instant.now()); } - Instant result = this.optOutStore.getLatestEntry(firstLevelHashIdentity); + Instant result = this.optOutStore.getLatestEntry(firstLevelHash); return new GlobalOptoutResult(result); } } diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index de52a6c75..cf2655984 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.uid2.operator.Const; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; import com.uid2.operator.service.EncodingUtils; import com.uid2.shared.Utils; import com.uid2.shared.cloud.CloudStorageException; @@ -74,8 +74,8 @@ public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonC } @Override - public Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity) { - long epochSecond = this.snapshot.get().getOptOutTimestamp(firstLevelHashIdentity.firstLevelHash); + public Instant getLatestEntry(FirstLevelHash firstLevelHash) { + long epochSecond = this.snapshot.get().getOptOutTimestamp(firstLevelHash.firstLevelHash()); Instant instant = epochSecond > 0 ? Instant.ofEpochSecond(epochSecond) : null; return instant; } @@ -86,14 +86,14 @@ public long getOptOutTimestampByAdId(String adId) { } @Override - public void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { + public void addEntry(FirstLevelHash firstLevelHash, byte[] advertisingId, Handler> handler) { if (remoteApiHost == null) { handler.handle(Future.failedFuture("remote api not set")); return; } this.webClient.get(remoteApiPort, remoteApiHost, remoteApiPath) - .addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHashIdentity.firstLevelHash)) + .addQueryParam("identity_hash", EncodingUtils.toBase64String(firstLevelHash.firstLevelHash())) .addQueryParam("advertising_id", EncodingUtils.toBase64String(advertisingId)) // advertising id aka raw UID .putHeader("Authorization", remoteApiBearerToken) .as(BodyCodec.string()) diff --git a/src/main/java/com/uid2/operator/store/IOptOutStore.java b/src/main/java/com/uid2/operator/store/IOptOutStore.java index 995939c70..09ba19e28 100644 --- a/src/main/java/com/uid2/operator/store/IOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/IOptOutStore.java @@ -1,6 +1,6 @@ package com.uid2.operator.store; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; @@ -11,12 +11,12 @@ public interface IOptOutStore { /** * Get latest opt-out record * - * @param firstLevelHashIdentity The first level hash of a DII Hash + * @param firstLevelHash The first level hash of a DII Hash * @return The timestamp of latest opt-out record. NULL if no record. */ - Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity); + Instant getLatestEntry(FirstLevelHash firstLevelHash); long getOptOutTimestampByAdId(String adId); - void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler); + void addEntry(FirstLevelHash firstLevelHash, byte[] advertisingId, Handler> handler); } diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index f8f1338d4..a61af9790 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -4,7 +4,7 @@ import com.uid2.operator.model.*; import com.uid2.operator.model.TokenGenerateResponse; import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.identities.HashedDii; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.StatsCollectorHandler; import com.uid2.operator.monitoring.TokenResponseStatsCollector; @@ -1152,8 +1152,8 @@ private void handleOptOutGet(RoutingContext rc) { if (input.isValid()) { try { final Instant now = Instant.now(); - final HashedDiiIdentity hashedDiiIdentity = input.toHashedDiiIdentity(this.identityScope); - final Instant result = this.idService.getLatestOptoutEntry(hashedDiiIdentity, now); + final HashedDii hashedDii = input.toHashedDiiIdentity(this.identityScope); + final Instant result = this.idService.getLatestOptoutEntry(hashedDii, now); long timestamp = result == null ? -1 : result.getEpochSecond(); rc.response().setStatusCode(200) .setChunked(true) diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 0b0009ef7..039ebd17f 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -1,8 +1,8 @@ package com.uid2.operator; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; -import com.uid2.operator.model.userIdentity.RawUidIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; +import com.uid2.operator.model.identities.RawUid; import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.TokenUtils; @@ -60,7 +60,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new FirstLevelHashIdentity(IdentityScope.UID2, IdentityType.Email, firstLevelHash, now), + new FirstLevelHash(IdentityScope.UID2, IdentityType.Email, firstLevelHash, now), PrivacyBits.fromInt(121) ); @@ -75,9 +75,9 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { assertEquals(tokenRefreshRequest.createdAt, decoded.createdAt); int addSeconds = (tokenVersion == TokenVersion.V2) ? 60 : 0; //todo: why is there a 60 second buffer in encodeV2() but not in encodeV3()? assertEquals(tokenRefreshRequest.expiresAt.plusSeconds(addSeconds), decoded.expiresAt); - assertTrue(tokenRefreshRequest.firstLevelHashIdentity.matches(decoded.firstLevelHashIdentity)); + assertTrue(tokenRefreshRequest.firstLevelHash.matches(decoded.firstLevelHash)); assertEquals(tokenRefreshRequest.privacyBits, decoded.privacyBits); - assertEquals(tokenRefreshRequest.firstLevelHashIdentity.establishedAt, decoded.firstLevelHashIdentity.establishedAt); + assertEquals(tokenRefreshRequest.firstLevelHash.establishedAt(), decoded.firstLevelHash.establishedAt()); assertEquals(tokenRefreshRequest.sourcePublisher.siteId, decoded.sourcePublisher.siteId); Buffer b = Buffer.buffer(encodedBytes); @@ -103,7 +103,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { now.plusSeconds(60), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new RawUidIdentity(IdentityScope.UID2, IdentityType.Email, rawUid), + new RawUid(IdentityScope.UID2, IdentityType.Email, rawUid), PrivacyBits.fromInt(121), now ); @@ -114,7 +114,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { assertEquals(tokenVersion, decoded.version); assertEquals(adTokenRequest.createdAt, decoded.createdAt); assertEquals(adTokenRequest.expiresAt, decoded.expiresAt); - assertTrue(adTokenRequest.rawUidIdentity.matches(decoded.rawUidIdentity)); + assertTrue(adTokenRequest.rawUid.matches(decoded.rawUid)); assertEquals(adTokenRequest.privacyBits, decoded.privacyBits); assertEquals(adTokenRequest.establishedAt, decoded.establishedAt); assertEquals(adTokenRequest.sourcePublisher.siteId, decoded.sourcePublisher.siteId); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index 4e21b545d..bd4874c6e 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -1,9 +1,9 @@ package com.uid2.operator; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; -import com.uid2.operator.model.userIdentity.UserIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; +import com.uid2.operator.model.identities.HashedDii; +import com.uid2.operator.model.identities.RawUid; import com.uid2.operator.service.*; import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; @@ -146,8 +146,8 @@ private void setNow(Instant now) { when(clock.instant()).thenAnswer(i -> this.now); } - private HashedDiiIdentity createHashedDiiIdentity(String rawIdentityHash, IdentityScope scope, IdentityType type) { - return new HashedDiiIdentity( + private HashedDii createHashedDiiIdentity(String rawIdentityHash, IdentityScope scope, IdentityType type) { + return new HashedDii( scope, type, rawIdentityHash.getBytes(StandardCharsets.UTF_8) @@ -160,18 +160,38 @@ private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder tokenE return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); } - private void assertIdentityScopeIdentityType(UserIdentity expctedValues, - UserIdentity actualValues) { - assertEquals(expctedValues.identityScope, actualValues.identityScope); - assertEquals(expctedValues.identityType, actualValues.identityType); + private void assertIdentityScopeIdentityType(IdentityScope expectedScope, IdentityType expectedIdentityType, + HashedDii hashedDii) { + assertEquals(expectedScope, hashedDii.identityScope()); + assertEquals(expectedIdentityType, hashedDii.identityType()); } + private void assertIdentityScopeIdentityType(IdentityScope expectedScope, IdentityType expectedIdentityType, + RawUid rawUid) { + assertEquals(expectedScope, rawUid.identityScope()); + assertEquals(expectedIdentityType, rawUid.identityType()); + } + + private void assertIdentityScopeIdentityType(IdentityScope expectedScope, IdentityType expectedIdentityType, + FirstLevelHash firstLevelHash) { + assertEquals(expectedScope, firstLevelHash.identityScope()); + assertEquals(expectedIdentityType, firstLevelHash.identityType()); + } + + + + + @ParameterizedTest @CsvSource({"123, V2","127, V4","128, V4"}) //site id 127 and 128 is for testing "site_ids_using_v4_tokens" public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { + IdentityScope expectedIdentityScope = IdentityScope.UID2; + IdentityType expectedIdentityType = IdentityType.Email; + + final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(siteId, 124, 125), - createHashedDiiIdentity("test-email-hash", IdentityScope.UID2, IdentityType.Email), + createHashedDiiIdentity("test-email-hash", expectedIdentityScope, expectedIdentityType), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now.minusSeconds(234) ); @@ -184,7 +204,8 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { AdvertisingTokenRequest advertisingTokenRequest = tokenEncoder.decodeAdvertisingToken(tokenGenerateResponse.getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenRequest.expiresAt); assertEquals(tokenGenerateRequest.sourcePublisher.siteId, advertisingTokenRequest.sourcePublisher.siteId); - assertIdentityScopeIdentityType(tokenGenerateRequest.hashedDiiIdentity, advertisingTokenRequest.rawUidIdentity); + assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, + advertisingTokenRequest.rawUid); assertEquals(tokenGenerateRequest.establishedAt, advertisingTokenRequest.establishedAt); assertEquals(tokenGenerateRequest.privacyBits, advertisingTokenRequest.privacyBits); @@ -192,12 +213,12 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(this.now, tokenRefreshRequest.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), tokenRefreshRequest.expiresAt); assertEquals(tokenGenerateRequest.sourcePublisher.siteId, tokenRefreshRequest.sourcePublisher.siteId); - assertIdentityScopeIdentityType(tokenGenerateRequest.hashedDiiIdentity, tokenRefreshRequest.firstLevelHashIdentity); - assertEquals(tokenGenerateRequest.establishedAt, tokenRefreshRequest.firstLevelHashIdentity.establishedAt); + assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, tokenRefreshRequest.firstLevelHash); + assertEquals(tokenGenerateRequest.establishedAt, tokenRefreshRequest.firstLevelHash.establishedAt()); - final byte[] firstLevelHash = getFirstLevelHash(tokenGenerateRequest.hashedDiiIdentity.hashedDii, + final byte[] firstLevelHash = getFirstLevelHash(tokenGenerateRequest.hashedDii.hashedDii(), saltProvider.getSnapshot(this.now).getFirstLevelSalt() ); - assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHash.firstLevelHash()); setNow(Instant.now().plusSeconds(200)); @@ -214,21 +235,21 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { AdvertisingTokenRequest advertisingTokenRequest2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenRequest2.expiresAt); assertEquals(advertisingTokenRequest.sourcePublisher.siteId, advertisingTokenRequest2.sourcePublisher.siteId); - assertIdentityScopeIdentityType(advertisingTokenRequest.rawUidIdentity, - advertisingTokenRequest2.rawUidIdentity); + assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, + advertisingTokenRequest2.rawUid); assertEquals(advertisingTokenRequest.establishedAt, advertisingTokenRequest2.establishedAt); - assertArrayEquals(advertisingTokenRequest.rawUidIdentity.rawUid, - advertisingTokenRequest2.rawUidIdentity.rawUid); + assertArrayEquals(advertisingTokenRequest.rawUid.rawUid(), + advertisingTokenRequest2.rawUid.rawUid()); assertEquals(tokenGenerateRequest.privacyBits, advertisingTokenRequest2.privacyBits); TokenRefreshRequest tokenRefreshRequest2 = tokenEncoder.decodeRefreshToken(refreshResponse.getIdentityResponse().getRefreshToken()); assertEquals(this.now, tokenRefreshRequest2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), tokenRefreshRequest2.expiresAt); assertEquals(tokenRefreshRequest.sourcePublisher.siteId, tokenRefreshRequest2.sourcePublisher.siteId); - assertIdentityScopeIdentityType(tokenRefreshRequest.firstLevelHashIdentity, tokenRefreshRequest2.firstLevelHashIdentity); - assertEquals(tokenRefreshRequest.firstLevelHashIdentity.establishedAt, tokenRefreshRequest2.firstLevelHashIdentity.establishedAt); - assertArrayEquals(tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash, tokenRefreshRequest2.firstLevelHashIdentity.firstLevelHash); - assertArrayEquals(firstLevelHash, tokenRefreshRequest2.firstLevelHashIdentity.firstLevelHash); + assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, tokenRefreshRequest2.firstLevelHash); + assertEquals(tokenRefreshRequest.firstLevelHash.establishedAt(), tokenRefreshRequest2.firstLevelHash.establishedAt()); + assertArrayEquals(tokenRefreshRequest.firstLevelHash.firstLevelHash(), tokenRefreshRequest2.firstLevelHash.firstLevelHash()); + assertArrayEquals(firstLevelHash, tokenRefreshRequest2.firstLevelHash.firstLevelHash()); } @Test @@ -292,23 +313,23 @@ public void testTestOptOutKeyIdentityScopeMismatch() { "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) public void testGenerateTokenForOptOutUser(IdentityType type, String id, IdentityScope scope) { - final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(TokenUtils.getIdentityHashString(id), + final HashedDii hashedDii = createHashedDiiIdentity(TokenUtils.getIdentityHashString(id), scope, type); final TokenGenerateRequest tokenGenerateRequestForceGenerate = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - hashedDiiIdentity, + hashedDii, OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now.minusSeconds(234)); final TokenGenerateRequest tokenGenerateRequestRespectOptOut = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - hashedDiiIdentity, + hashedDii, OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now.minusSeconds(234)); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); final TokenGenerateResponse tokenGenerateResponse; @@ -318,7 +339,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDiiIdentity.identityType, tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDii.identityType(), tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); tokenGenerateResponseAfterOptOut = uid2Service.generateIdentity(tokenGenerateRequestRespectOptOut); @@ -326,14 +347,14 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDiiIdentity.identityType, tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDii.identityType(), tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); tokenGenerateResponseAfterOptOut = euidService.generateIdentity(tokenGenerateRequestRespectOptOut); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokenGenerateResponse); - assertNotNull(advertisingTokenRequest.rawUidIdentity); + assertNotNull(advertisingTokenRequest.rawUid); assertNotNull(tokenGenerateResponseAfterOptOut); assertTrue(tokenGenerateResponseAfterOptOut.getAdvertisingToken() == null || tokenGenerateResponseAfterOptOut.getAdvertisingToken().isEmpty()); assertTrue(tokenGenerateResponseAfterOptOut.isOptedOut()); @@ -345,21 +366,21 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) public void testIdentityMapForOptOutUser(IdentityType type, String identity, IdentityScope scope) { - final HashedDiiIdentity hashedDiiIdentity = createHashedDiiIdentity(identity, scope, type); + final HashedDii hashedDii = createHashedDiiIdentity(identity, scope, type); final Instant now = Instant.now(); final IdentityMapRequestItem mapRequestForceIdentityMapItem = new IdentityMapRequestItem( - hashedDiiIdentity, + hashedDii, OptoutCheckPolicy.DoNotRespect, now); final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( - hashedDiiIdentity, + hashedDii, OptoutCheckPolicy.RespectOptOut, now); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); final IdentityMapResponseItem identityMapResponseItem; @@ -625,12 +646,12 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, else { tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); } - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), scope, tokenGenerateRequest.hashedDiiIdentity.identityType, tokenGenerateRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), scope, tokenGenerateRequest.hashedDii.identityType(), tokenGenerateRequest.sourcePublisher.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokenGenerateResponse); assertNotEquals(TokenGenerateResponse.OptOutResponse, tokenGenerateResponse); - assertNotNull(advertisingTokenRequest.rawUidIdentity); + assertNotNull(advertisingTokenRequest.rawUid); } @@ -747,17 +768,17 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String reset(shutdownHandler); if(scope == IdentityScope.EUID) { tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, tokenGenerateRequest.hashedDiiIdentity.identityType, tokenGenerateRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, tokenGenerateRequest.hashedDii.identityType(), tokenGenerateRequest.sourcePublisher.siteId); } else { tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, tokenGenerateRequest.hashedDiiIdentity.identityType, tokenGenerateRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, tokenGenerateRequest.hashedDii.identityType(), tokenGenerateRequest.sourcePublisher.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); assertNotNull(tokenGenerateResponse); assertNotEquals(TokenGenerateResponse.OptOutResponse, tokenGenerateResponse); - assertNotNull(advertisingTokenRequest.rawUidIdentity); + assertNotNull(advertisingTokenRequest.rawUid); final TokenRefreshRequest tokenRefreshRequest = this.tokenEncoder.decodeRefreshToken(tokenGenerateResponse.getRefreshToken()); reset(shutdownHandler); diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index cdc401ecd..6ee61fe3c 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -5,7 +5,7 @@ import ch.qos.logback.core.read.ListAppender; import com.uid2.operator.model.*; import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.TokenResponseStatsCollector; import com.uid2.operator.service.*; @@ -818,7 +818,7 @@ private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder encode validateAdvertisingToken(advertisingTokenString, getTokenVersion(), getIdentityScope(), identityType); AdvertisingTokenRequest advertisingTokenRequest = encoder.decodeAdvertisingToken(advertisingTokenString); if (getTokenVersion() == TokenVersion.V4) { - assertEquals(identityType, advertisingTokenRequest.rawUidIdentity.identityType); + assertEquals(identityType, advertisingTokenRequest.rawUid.identityType()); } return advertisingTokenRequest; } @@ -850,8 +850,8 @@ public static void validateAdvertisingToken(String advertisingTokenString, Token TokenRefreshRequest decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { TokenRefreshRequest tokenRefreshRequest = encoder.decodeRefreshToken(refreshTokenString); - assertEquals(getIdentityScope(), tokenRefreshRequest.firstLevelHashIdentity.identityScope); - assertEquals(identityType, tokenRefreshRequest.firstLevelHashIdentity.identityType); + assertEquals(getIdentityScope(), tokenRefreshRequest.firstLevelHash.identityScope()); + assertEquals(identityType, tokenRefreshRequest.firstLevelHash.identityType()); return tokenRefreshRequest; } @@ -864,7 +864,7 @@ void identityMapNewClientNoPolicySpecified(String apiVersion, Vertx vertx, Vertx setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -891,7 +891,7 @@ void identityMapNewClientWrongPolicySpecified(String apiVersion, String policyPa setupSalts(); setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); JsonArray emails = new JsonArray(); @@ -1171,8 +1171,8 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi firstLevelSalt, rotatingSalt123.getSalt()); final byte[] firstLevelHash = TokenUtils.getFirstLevelHashFromIdentity(optOutTokenInput.getNormalized(), firstLevelSalt); - assertArrayEquals(rawUid, advertisingTokenRequest.rawUidIdentity.rawUid); - assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(rawUid, advertisingTokenRequest.rawUid.rawUid()); + assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHash.firstLevelHash()); String advertisingTokenString = body.getString("advertising_token"); final Instant now = Instant.now(); @@ -1244,7 +1244,7 @@ public void assertAdvertisingTokenRefreshTokenRequests(AdvertisingTokenRequest a assertEquals(expectedClientSiteId, advertisingTokenRequest.sourcePublisher.siteId); assertEquals(expectedClientSiteId, tokenRefreshRequest.sourcePublisher.siteId); - assertArrayEquals(expectedRawUidIdentity, advertisingTokenRequest.rawUidIdentity.rawUid); + assertArrayEquals(expectedRawUidIdentity, advertisingTokenRequest.rawUid.rawUid()); verifyPrivacyBits(expectedPrivacyBits, advertisingTokenRequest, tokenRefreshRequest); verifyFirstLevelHashIdentityAndEstablishedAt(firstLevelHashIdentity, tokenRefreshRequest, identityResponse, advertisingTokenRequest.establishedAt); @@ -1316,7 +1316,7 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t TokenRefreshRequest firstTokenRefreshRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); - assertEquals(firstAdvertisingTokenRequest.establishedAt, firstTokenRefreshRequest.firstLevelHashIdentity.establishedAt); + assertEquals(firstAdvertisingTokenRequest.establishedAt, firstTokenRefreshRequest.firstLevelHash.establishedAt()); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); @@ -1416,13 +1416,13 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHash.firstLevelHash()); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); @@ -1591,11 +1591,11 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHash.firstLevelHash()); testContext.completeNow(); }); @@ -1630,11 +1630,11 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUidIdentity.rawUid); + assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); - assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); + assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHash.firstLevelHash()); assertEqualsClose(now.plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("identity_expires")), 10); assertEqualsClose(now.plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(body.getLong("refresh_expires")), 10); @@ -2555,11 +2555,11 @@ void verifyFirstLevelHashIdentityAndEstablishedAt(byte[] expectedFirstLevelHash, JsonObject receivedJsonBody, Instant expectedEstablishedTime) { - assertArrayEquals(expectedFirstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash); - assertEquals(expectedEstablishedTime, tokenRefreshRequest.firstLevelHashIdentity.establishedAt); - assertTrue(tokenRefreshRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); - assertTrue(tokenRefreshRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); - assertTrue(tokenRefreshRequest.firstLevelHashIdentity.establishedAt.toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); + assertArrayEquals(expectedFirstLevelHash, tokenRefreshRequest.firstLevelHash.firstLevelHash()); + assertEquals(expectedEstablishedTime, tokenRefreshRequest.firstLevelHash.establishedAt()); + assertTrue(tokenRefreshRequest.firstLevelHash.establishedAt().toEpochMilli() < receivedJsonBody.getLong("identity_expires") ); + assertTrue(tokenRefreshRequest.firstLevelHash.establishedAt().toEpochMilli() < receivedJsonBody.getLong("refresh_expires") ); + assertTrue(tokenRefreshRequest.firstLevelHash.establishedAt().toEpochMilli() < receivedJsonBody.getLong("refresh_from") ); } @ParameterizedTest @@ -3101,7 +3101,7 @@ void tokenGenerateRespectOptOutOption(String policyParameterKey, Vertx vertx, Ve setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -3132,7 +3132,7 @@ void identityMapDefaultOption(String apiVersion, Vertx vertx, VertxTestContext t setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -3173,7 +3173,7 @@ void identityMapRespectOptOutOption(String apiVersion, String policyParameterKey setupKeys(); // the clock value shouldn't matter here - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(now.minus(1, ChronoUnit.HOURS)); JsonObject req = new JsonObject(); @@ -4064,11 +4064,11 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver final Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli()); // When we generate the token the user hasn't opted out. - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(null); final EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(FirstLevelHashIdentity.class); + final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(FirstLevelHash.class); sendCstg(vertx, "v2/token/client-generate", @@ -4080,7 +4080,7 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver response -> { verify(optOutStore, times(1)).getLatestEntry(argumentCaptor.capture()); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt), - argumentCaptor.getValue().firstLevelHash); + argumentCaptor.getValue().firstLevelHash()); assertEquals("success", response.getString("status")); final JsonObject genBody = response.getJsonObject("body"); @@ -4091,7 +4091,7 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, identityType, id); // When we refresh the token the user has opted out. - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(advertisingTokenRequest.establishedAt.plusSeconds(1)); sendTokenRefresh("v2", vertx, testContext, genBody.getString("refresh_token"), genBody.getString("refresh_response_key"), 200, refreshRespJson -> { @@ -4120,11 +4120,11 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id if(optOutExpected) { - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); } else { //not expectedOptedOut - when(optOutStore.getLatestEntry(any(FirstLevelHashIdentity.class))) + when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) .thenReturn(null); } @@ -4325,8 +4325,8 @@ private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertis () -> assertEquals(siteId, advertisingTokenRequest.sourcePublisher.siteId, "Advertising token site ID is incorrect"), () -> assertEquals(siteId, tokenRefreshRequest.sourcePublisher.siteId, "Refresh token site ID is incorrect"), - () -> assertArrayEquals(rawUid, advertisingTokenRequest.rawUidIdentity.rawUid, "Advertising token ID is incorrect"), - () -> assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHashIdentity.firstLevelHash, "Refresh token ID is incorrect") + () -> assertArrayEquals(rawUid, advertisingTokenRequest.rawUid.rawUid(), "Advertising token ID is incorrect"), + () -> assertArrayEquals(firstLevelHash, tokenRefreshRequest.firstLevelHash.firstLevelHash(), "Refresh token ID is incorrect") ); } diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index c5b062ad8..6ab2447e7 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -3,8 +3,8 @@ import com.uid2.operator.Const; import com.uid2.operator.Main; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.FirstLevelHashIdentity; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.identities.FirstLevelHash; +import com.uid2.operator.model.identities.HashedDii; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.IUIDOperatorService; import com.uid2.operator.service.UIDOperatorService; @@ -150,12 +150,12 @@ static ICloudStorage make1mOptOutEntryStorage(String salt, List out_gene return storage; } - static HashedDiiIdentity[] createHashedDiiIdentities() { - HashedDiiIdentity[] arr = new HashedDiiIdentity[65536]; + static HashedDii[] createHashedDiiIdentities() { + HashedDii[] arr = new HashedDii[65536]; for (int i = 0; i < 65536; i++) { final byte[] diiHash = new byte[33]; new Random().nextBytes(diiHash); - arr[i] = new HashedDiiIdentity(IdentityScope.UID2, IdentityType.Email, diiHash); + arr[i] = new HashedDii(IdentityScope.UID2, IdentityType.Email, diiHash); } return arr; } @@ -188,14 +188,14 @@ public StaticOptOutStore(ICloudStorage storage, JsonObject jsonConfig, Collectio } @Override - public Instant getLatestEntry(FirstLevelHashIdentity firstLevelHashIdentity) { - long epochSecond = this.snapshot.getOptOutTimestamp(firstLevelHashIdentity.firstLevelHash); + public Instant getLatestEntry(FirstLevelHash firstLevelHash) { + long epochSecond = this.snapshot.getOptOutTimestamp(firstLevelHash.firstLevelHash()); Instant instant = epochSecond > 0 ? Instant.ofEpochSecond(epochSecond) : null; return instant; } @Override - public void addEntry(FirstLevelHashIdentity firstLevelHashIdentity, byte[] advertisingId, Handler> handler) { + public void addEntry(FirstLevelHash firstLevelHash, byte[] advertisingId, Handler> handler) { // noop } diff --git a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java index 63652ab09..7151d8c7e 100644 --- a/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/IdentityMapBenchmark.java @@ -1,7 +1,7 @@ package com.uid2.operator.benchmark; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.identities.HashedDii; import com.uid2.operator.service.IUIDOperatorService; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -11,7 +11,7 @@ public class IdentityMapBenchmark { private static final IUIDOperatorService uidService; - private static final HashedDiiIdentity[] hashedDiiIdentities; + private static final HashedDii[] hashedDiiIdentities; private static int idx = 0; static { diff --git a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java index b736c1a44..6b7e2c01c 100644 --- a/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java +++ b/src/test/java/com/uid2/operator/benchmark/TokenEndecBenchmark.java @@ -1,7 +1,7 @@ package com.uid2.operator.benchmark; import com.uid2.operator.model.*; -import com.uid2.operator.model.userIdentity.HashedDiiIdentity; +import com.uid2.operator.model.identities.HashedDii; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.IUIDOperatorService; import org.openjdk.jmh.annotations.Benchmark; @@ -14,7 +14,7 @@ public class TokenEndecBenchmark { private static final IUIDOperatorService uidService; - private static final HashedDiiIdentity[] hashedDiiIdentities; + private static final HashedDii[] hashedDiiIdentities; private static final SourcePublisher publisher; private static final EncryptedTokenEncoder encoder; private static final TokenGenerateResponse[] generatedTokens; From a8f0915b2c65bf043ee5a7b0787d29e04c6f086b Mon Sep 17 00:00:00 2001 From: Sunny Wu Date: Mon, 9 Dec 2024 19:04:22 +1100 Subject: [PATCH 61/61] 1. Renamed IdentityType to DiiType 2. In InputUtil, renamed Identity* member variable/methods to Dii* to indicate it's Dii 3. Change TokenUtils class getIdentityHash to getDiiHash and same for getDiiHashString --- .../DiiType.java} | 8 +- .../model/identities/FirstLevelHash.java | 7 +- .../operator/model/identities/HashedDii.java | 8 +- .../{ => model/identities}/IdentityConst.java | 2 +- .../model/{ => identities}/IdentityScope.java | 2 +- .../operator/model/identities/RawUid.java | 7 +- .../service/EncryptedTokenEncoder.java | 32 +-- .../com/uid2/operator/service/InputUtil.java | 57 ++--- .../com/uid2/operator/service/TokenUtils.java | 22 +- .../operator/service/UIDOperatorService.java | 44 ++-- .../uid2/operator/service/V2RequestUtil.java | 4 +- .../operator/vertx/UIDOperatorVerticle.java | 79 +++---- .../uid2/operator/vertx/V2PayloadHandler.java | 2 +- .../operator/EUIDOperatorVerticleTest.java | 2 +- .../uid2/operator/InputNormalizationTest.java | 4 +- .../com/uid2/operator/TokenEncodingTest.java | 8 +- .../uid2/operator/UIDOperatorServiceTest.java | 78 +++---- .../operator/UIDOperatorVerticleTest.java | 219 +++++++++--------- .../com/uid2/operator/V2RequestUtilTest.java | 2 +- .../operator/benchmark/BenchmarkCommon.java | 4 +- 20 files changed, 293 insertions(+), 298 deletions(-) rename src/main/java/com/uid2/operator/model/{IdentityType.java => identities/DiiType.java} (67%) rename src/main/java/com/uid2/operator/{ => model/identities}/IdentityConst.java (97%) rename src/main/java/com/uid2/operator/model/{ => identities}/IdentityScope.java (94%) diff --git a/src/main/java/com/uid2/operator/model/IdentityType.java b/src/main/java/com/uid2/operator/model/identities/DiiType.java similarity index 67% rename from src/main/java/com/uid2/operator/model/IdentityType.java rename to src/main/java/com/uid2/operator/model/identities/DiiType.java index b64817df5..062b55d35 100644 --- a/src/main/java/com/uid2/operator/model/IdentityType.java +++ b/src/main/java/com/uid2/operator/model/identities/DiiType.java @@ -1,15 +1,15 @@ -package com.uid2.operator.model; +package com.uid2.operator.model.identities; import com.uid2.operator.vertx.ClientInputValidationException; -public enum IdentityType { +public enum DiiType { Email(0), Phone(1); public final int value; - IdentityType(int value) { this.value = value; } + DiiType(int value) { this.value = value; } - public static IdentityType fromValue(int value) { + public static DiiType fromValue(int value) { switch (value) { case 0: return Email; case 1: return Phone; diff --git a/src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java b/src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java index d46cc0ad5..49b2728f4 100644 --- a/src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java +++ b/src/main/java/com/uid2/operator/model/identities/FirstLevelHash.java @@ -1,8 +1,5 @@ package com.uid2.operator.model.identities; -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; - import java.time.Instant; import java.util.Arrays; @@ -10,13 +7,13 @@ * Contains a first level salted hash computed from Hashed DII (email/phone number) * @param establishedAt for brand new token generation, it should be the time it is generated if the first level hash is from token/refresh call, it will be when the raw UID was originally created in the earliest token generation */ -public record FirstLevelHash(IdentityScope identityScope, IdentityType identityType, byte[] firstLevelHash, +public record FirstLevelHash(IdentityScope identityScope, DiiType diiType, byte[] firstLevelHash, Instant establishedAt) { // explicitly not checking establishedAt - this is only for making sure the first level hash matches a new input public boolean matches(FirstLevelHash that) { return this.identityScope.equals(that.identityScope) && - this.identityType.equals(that.identityType) && + this.diiType.equals(that.diiType) && Arrays.equals(this.firstLevelHash, that.firstLevelHash); } } diff --git a/src/main/java/com/uid2/operator/model/identities/HashedDii.java b/src/main/java/com/uid2/operator/model/identities/HashedDii.java index da040c066..64c7bbf0f 100644 --- a/src/main/java/com/uid2/operator/model/identities/HashedDii.java +++ b/src/main/java/com/uid2/operator/model/identities/HashedDii.java @@ -1,9 +1,7 @@ package com.uid2.operator.model.identities; -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; - -// Contains a hash DII, +// Contains a hash Directly Identifying Information (DII) (email or phone) see https://unifiedid.com/docs/ref-info/glossary-uid#gl-dii // This hash can either be computed from a raw email/phone number DII input or provided by the UID Participant directly -public record HashedDii(IdentityScope identityScope, IdentityType identityType, byte[] hashedDii) { +// +public record HashedDii(IdentityScope identityScope, DiiType diiType, byte[] hashedDii) { } diff --git a/src/main/java/com/uid2/operator/IdentityConst.java b/src/main/java/com/uid2/operator/model/identities/IdentityConst.java similarity index 97% rename from src/main/java/com/uid2/operator/IdentityConst.java rename to src/main/java/com/uid2/operator/model/identities/IdentityConst.java index 402a99d88..63fa62f96 100644 --- a/src/main/java/com/uid2/operator/IdentityConst.java +++ b/src/main/java/com/uid2/operator/model/identities/IdentityConst.java @@ -1,4 +1,4 @@ -package com.uid2.operator; +package com.uid2.operator.model.identities; import com.uid2.operator.service.EncodingUtils; diff --git a/src/main/java/com/uid2/operator/model/IdentityScope.java b/src/main/java/com/uid2/operator/model/identities/IdentityScope.java similarity index 94% rename from src/main/java/com/uid2/operator/model/IdentityScope.java rename to src/main/java/com/uid2/operator/model/identities/IdentityScope.java index 0bff1edc1..3dc19a764 100644 --- a/src/main/java/com/uid2/operator/model/IdentityScope.java +++ b/src/main/java/com/uid2/operator/model/identities/IdentityScope.java @@ -1,4 +1,4 @@ -package com.uid2.operator.model; +package com.uid2.operator.model.identities; import com.uid2.operator.vertx.ClientInputValidationException; diff --git a/src/main/java/com/uid2/operator/model/identities/RawUid.java b/src/main/java/com/uid2/operator/model/identities/RawUid.java index 775c7c46a..4ae619d00 100644 --- a/src/main/java/com/uid2/operator/model/identities/RawUid.java +++ b/src/main/java/com/uid2/operator/model/identities/RawUid.java @@ -1,16 +1,13 @@ package com.uid2.operator.model.identities; -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; - import java.util.Arrays; // A raw UID is stored inside -public record RawUid(IdentityScope identityScope, IdentityType identityType, byte[] rawUid) { +public record RawUid(IdentityScope identityScope, DiiType diiType, byte[] rawUid) { public boolean matches(RawUid that) { return this.identityScope.equals(that.identityScope) && - this.identityType.equals(that.identityType) && + this.diiType.equals(that.diiType) && Arrays.equals(this.rawUid, that.rawUid); } } diff --git a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java index 87f86b244..d3f6ad9cf 100644 --- a/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java +++ b/src/main/java/com/uid2/operator/service/EncryptedTokenEncoder.java @@ -1,7 +1,9 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; +import com.uid2.operator.model.identities.DiiType; import com.uid2.operator.model.identities.FirstLevelHash; +import com.uid2.operator.model.identities.IdentityScope; import com.uid2.operator.model.identities.RawUid; import com.uid2.operator.util.PrivacyBits; import com.uid2.operator.vertx.ClientInputValidationException; @@ -69,7 +71,7 @@ private byte[] encodeIntoAdvertisingTokenV3(AdvertisingTokenRequest t, KeysetKey masterPayload.appendBytes(AesGcm.encrypt(sitePayload.getBytes(), siteKey).getPayload()); final Buffer b = Buffer.buffer(164); - b.appendByte(encodeIdentityTypeV3(t.rawUid.identityScope(), t.rawUid.identityType())); + b.appendByte(encodeIdentityTypeV3(t.rawUid.identityScope(), t.rawUid.diiType())); b.appendByte((byte) t.version.rawVersion); b.appendInt(masterKey.getId()); b.appendBytes(AesGcm.encrypt(masterPayload.getBytes(), masterKey).getPayload()); @@ -129,7 +131,7 @@ private TokenRefreshRequest decodeRefreshTokenV2(Buffer b) { TokenVersion.V2, createdAt, validTill, new OperatorIdentity(0, OperatorType.Service, 0, 0), new SourcePublisher(siteId), - new FirstLevelHash(IdentityScope.UID2, IdentityType.Email, identity, + new FirstLevelHash(IdentityScope.UID2, DiiType.Email, identity, Instant.ofEpochMilli(establishedMillis)), privacyBits); } @@ -152,19 +154,19 @@ private TokenRefreshRequest decodeRefreshTokenV3(Buffer b, byte[] bytes) { final PrivacyBits privacyBits = PrivacyBits.fromInt(b2.getInt(45)); final Instant establishedAt = Instant.ofEpochMilli(b2.getLong(49)); final IdentityScope identityScope = decodeIdentityScopeV3(b2.getByte(57)); - final IdentityType identityType = decodeIdentityTypeV3(b2.getByte(57)); + final DiiType diiType = decodeIdentityTypeV3(b2.getByte(57)); final byte[] firstLevelHash = b2.getBytes(58, 90); if (identityScope != decodeIdentityScopeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed to decode refreshTokenV3: Identity scope mismatch"); } - if (identityType != decodeIdentityTypeV3(b.getByte(0))) { + if (diiType != decodeIdentityTypeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed to decode refreshTokenV3: Identity type mismatch"); } return new TokenRefreshRequest( TokenVersion.V3, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new FirstLevelHash(identityScope, identityType, firstLevelHash, establishedAt), + new FirstLevelHash(identityScope, diiType, firstLevelHash, establishedAt), privacyBits); } @@ -233,7 +235,7 @@ public AdvertisingTokenRequest decodeAdvertisingTokenV2(Buffer b) { Instant.ofEpochMilli(expiresMillis), new OperatorIdentity(0, OperatorType.Service, 0, masterKeyId), new SourcePublisher(siteId, siteKeyId, 0), - new RawUid(IdentityScope.UID2, IdentityType.Email, rawUid), + new RawUid(IdentityScope.UID2, DiiType.Email, rawUid), privacyBits, Instant.ofEpochMilli(establishedMillis) ); @@ -262,21 +264,21 @@ public AdvertisingTokenRequest decodeAdvertisingTokenV3orV4(Buffer b, byte[] byt final Instant refreshedAt = Instant.ofEpochMilli(sitePayload.getLong(28)); final byte[] rawUid = sitePayload.slice(36, sitePayload.length()).getBytes(); final IdentityScope identityScope = rawUid.length == 32 ? IdentityScope.UID2 : decodeIdentityScopeV3(rawUid[0]); - final IdentityType identityType = rawUid.length == 32 ? IdentityType.Email : decodeIdentityTypeV3(rawUid[0]); + final DiiType diiType = rawUid.length == 32 ? DiiType.Email : decodeIdentityTypeV3(rawUid[0]); if (rawUid.length > 32) { if (identityScope != decodeIdentityScopeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed decoding advertisingTokenV3: Identity scope mismatch"); } - if (identityType != decodeIdentityTypeV3(b.getByte(0))) { + if (diiType != decodeIdentityTypeV3(b.getByte(0))) { throw new ClientInputValidationException("Failed decoding advertisingTokenV3: Identity type mismatch"); } } return new AdvertisingTokenRequest( tokenVersion, createdAt, expiresAt, operatorIdentity, sourcePublisher, - new RawUid(identityScope, identityType, rawUid), + new RawUid(identityScope, diiType, rawUid), privacyBits, establishedAt ); } @@ -326,11 +328,11 @@ public byte[] encodeIntoRefreshTokenV3(TokenRefreshRequest t, KeysetKey serviceK encodePublisherRequesterV3(refreshPayload, t.sourcePublisher); refreshPayload.appendInt(t.privacyBits.getAsInt()); refreshPayload.appendLong(t.firstLevelHash.establishedAt().toEpochMilli()); - refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHash.identityScope(), t.firstLevelHash.identityType())); + refreshPayload.appendByte(encodeIdentityTypeV3(t.firstLevelHash.identityScope(), t.firstLevelHash.diiType())); refreshPayload.appendBytes(t.firstLevelHash.firstLevelHash()); final Buffer b = Buffer.buffer(124); - b.appendByte(encodeIdentityTypeV3(t.firstLevelHash.identityScope(), t.firstLevelHash.identityType())); + b.appendByte(encodeIdentityTypeV3(t.firstLevelHash.identityScope(), t.firstLevelHash.diiType())); b.appendByte((byte) t.version.rawVersion); b.appendInt(serviceKey.getId()); b.appendBytes(AesGcm.encrypt(refreshPayload.getBytes(), serviceKey).getPayload()); @@ -402,8 +404,8 @@ private byte[] encryptIdentityV2(SourcePublisher sourcePublisher, byte[] id, Pri } } - static private byte encodeIdentityTypeV3(IdentityScope identityScope, IdentityType identityType) { - return (byte) (TokenUtils.encodeIdentityScope(identityScope) | (identityType.value << 2) | 3); + static private byte encodeIdentityTypeV3(IdentityScope identityScope, DiiType diiType) { + return (byte) (TokenUtils.encodeIdentityScope(identityScope) | (diiType.value << 2) | 3); // "| 3" is used so that the 2nd char matches the version when V3 or higher. Eg "3" for V3 and "4" for V4 } @@ -411,8 +413,8 @@ static private IdentityScope decodeIdentityScopeV3(byte value) { return IdentityScope.fromValue((value & 0x10) >> 4); } - static private IdentityType decodeIdentityTypeV3(byte value) { - return IdentityType.fromValue((value & 0xf) >> 2); + static private DiiType decodeIdentityTypeV3(byte value) { + return DiiType.fromValue((value & 0xf) >> 2); } static void encodePublisherRequesterV3(Buffer b, SourcePublisher sourcePublisher) { diff --git a/src/main/java/com/uid2/operator/service/InputUtil.java b/src/main/java/com/uid2/operator/service/InputUtil.java index 9610d20f3..ab2b573b5 100644 --- a/src/main/java/com/uid2/operator/service/InputUtil.java +++ b/src/main/java/com/uid2/operator/service/InputUtil.java @@ -1,7 +1,7 @@ package com.uid2.operator.service; -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; +import com.uid2.operator.model.identities.IdentityScope; +import com.uid2.operator.model.identities.DiiType; import com.uid2.operator.model.identities.HashedDii; public class InputUtil { @@ -167,7 +167,7 @@ public static String normalizeEmailString(String email) { return addressPartToUse.append('@').append(domainPart).toString(); } - public enum IdentityInputType { + public enum DiiInputType { Raw, Hash } @@ -183,62 +183,63 @@ private static enum EmailParsingState { public static class InputVal { private final String provided; private final String normalized; - private final IdentityType identityType; - private final IdentityInputType inputType; + //Directly Identifying Information (DII) (email or phone) see https://unifiedid.com/docs/ref-info/glossary-uid#gl-dii + private final DiiType diiType; + private final DiiInputType inputType; private final boolean valid; - private final byte[] identityInput; + private final byte[] diiInput; - public InputVal(String provided, String normalized, IdentityType identityType, IdentityInputType inputType, boolean valid) { + public InputVal(String provided, String normalized, DiiType diiType, DiiInputType inputType, boolean valid) { this.provided = provided; this.normalized = normalized; - this.identityType = identityType; + this.diiType = diiType; this.inputType = inputType; this.valid = valid; if (valid) { - if (this.inputType == IdentityInputType.Raw) { - this.identityInput = TokenUtils.getIdentityHash(this.normalized); + if (this.inputType == DiiInputType.Raw) { + this.diiInput = TokenUtils.getDiiHash(this.normalized); } else { - this.identityInput = EncodingUtils.fromBase64(this.normalized); + this.diiInput = EncodingUtils.fromBase64(this.normalized); } } else { - this.identityInput = null; + this.diiInput = null; } } public static InputVal validEmail(String input, String normalized) { - return new InputVal(input, normalized, IdentityType.Email, IdentityInputType.Raw, true); + return new InputVal(input, normalized, DiiType.Email, DiiInputType.Raw, true); } public static InputVal invalidEmail(String input) { - return new InputVal(input, null, IdentityType.Email, IdentityInputType.Raw, false); + return new InputVal(input, null, DiiType.Email, DiiInputType.Raw, false); } public static InputVal validEmailHash(String input, String normalized) { - return new InputVal(input, normalized, IdentityType.Email, IdentityInputType.Hash, true); + return new InputVal(input, normalized, DiiType.Email, DiiInputType.Hash, true); } public static InputVal invalidEmailHash(String input) { - return new InputVal(input, null, IdentityType.Email, IdentityInputType.Hash, false); + return new InputVal(input, null, DiiType.Email, DiiInputType.Hash, false); } public static InputVal validPhone(String input, String normalized) { - return new InputVal(input, normalized, IdentityType.Phone, IdentityInputType.Raw, true); + return new InputVal(input, normalized, DiiType.Phone, DiiInputType.Raw, true); } public static InputVal invalidPhone(String input) { - return new InputVal(input, null, IdentityType.Phone, IdentityInputType.Raw, false); + return new InputVal(input, null, DiiType.Phone, DiiInputType.Raw, false); } public static InputVal validPhoneHash(String input, String normalized) { - return new InputVal(input, normalized, IdentityType.Phone, IdentityInputType.Hash, true); + return new InputVal(input, normalized, DiiType.Phone, DiiInputType.Hash, true); } public static InputVal invalidPhoneHash(String input) { - return new InputVal(input, null, IdentityType.Phone, IdentityInputType.Hash, false); + return new InputVal(input, null, DiiType.Phone, DiiInputType.Hash, false); } - public byte[] getIdentityInput() { - return this.identityInput; + public byte[] getHashedDiiInput() { + return this.diiInput; } public String getProvided() { @@ -249,21 +250,21 @@ public String getNormalized() { return normalized; } - public IdentityType getIdentityType() { - return identityType; + public DiiType getDiiType() { + return diiType; } - public IdentityInputType getInputType() { return inputType; } + public DiiInputType getInputType() { return inputType; } public boolean isValid() { return valid; } - public HashedDii toHashedDiiIdentity(IdentityScope identityScope) { + public HashedDii toHashedDii(IdentityScope identityScope) { return new HashedDii( identityScope, - this.identityType, - getIdentityInput()); + this.diiType, + getHashedDiiInput()); } } diff --git a/src/main/java/com/uid2/operator/service/TokenUtils.java b/src/main/java/com/uid2/operator/service/TokenUtils.java index ef532e578..0860db016 100644 --- a/src/main/java/com/uid2/operator/service/TokenUtils.java +++ b/src/main/java/com/uid2/operator/service/TokenUtils.java @@ -1,18 +1,18 @@ package com.uid2.operator.service; -import com.uid2.operator.model.IdentityScope; -import com.uid2.operator.model.IdentityType; +import com.uid2.operator.model.identities.IdentityScope; +import com.uid2.operator.model.identities.DiiType; import java.util.HashSet; import java.util.Set; public class TokenUtils { - public static byte[] getIdentityHash(String identityString) { + public static byte[] getDiiHash(String identityString) { return EncodingUtils.getSha256Bytes(identityString); } - public static String getIdentityHashString(String identityString) { - return EncodingUtils.toBase64String(getIdentityHash(identityString)); + public static String getDiiHashString(String identityString) { + return EncodingUtils.toBase64String(getDiiHash(identityString)); } public static byte[] getFirstLevelHash(byte[] identityHash, String firstLevelSalt) { @@ -20,7 +20,7 @@ public static byte[] getFirstLevelHash(byte[] identityHash, String firstLevelSal } public static byte[] getFirstLevelHashFromIdentity(String identityString, String firstLevelSalt) { - return getFirstLevelHash(getIdentityHash(identityString), firstLevelSalt); + return getFirstLevelHash(getDiiHash(identityString), firstLevelSalt); } public static byte[] getFirstLevelHashFromIdentityHash(String identityHash, String firstLevelSalt) { @@ -39,7 +39,7 @@ public static byte[] getRawUidV2FromIdentityHash(String identityString, String f return getRawUidV2(getFirstLevelHashFromIdentityHash(identityString, firstLevelSalt), rotatingSalt); } - public static byte[] getRawUidV3(IdentityScope scope, IdentityType type, byte[] firstLevelHash, String rotatingSalt) { + public static byte[] getRawUidV3(IdentityScope scope, DiiType type, byte[] firstLevelHash, String rotatingSalt) { final byte[] sha = EncodingUtils.getSha256Bytes(EncodingUtils.toBase64String(firstLevelHash), rotatingSalt); final byte[] rawUid = new byte[33]; rawUid[0] = (byte)(encodeIdentityScope(scope) | encodeIdentityType(type)); @@ -47,11 +47,11 @@ public static byte[] getRawUidV3(IdentityScope scope, IdentityType type, byte[] return rawUid; } - public static byte[] getRawUidV3FromIdentity(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { + public static byte[] getRawUidV3FromIdentity(IdentityScope scope, DiiType type, String identityString, String firstLevelSalt, String rotatingSalt) { return getRawUidV3(scope, type, getFirstLevelHashFromIdentity(identityString, firstLevelSalt), rotatingSalt); } - public static byte[] getRawUidV3FromIdentityHash(IdentityScope scope, IdentityType type, String identityString, String firstLevelSalt, String rotatingSalt) { + public static byte[] getRawUidV3FromIdentityHash(IdentityScope scope, DiiType type, String identityString, String firstLevelSalt, String rotatingSalt) { return getRawUidV3(scope, type, getFirstLevelHashFromIdentityHash(identityString, firstLevelSalt), rotatingSalt); } @@ -59,8 +59,8 @@ public static byte encodeIdentityScope(IdentityScope identityScope) { return (byte) (identityScope.value << 4); } - public static byte encodeIdentityType(IdentityType identityType) { - return (byte) (identityType.value << 2); + public static byte encodeIdentityType(DiiType diiType) { + return (byte) (diiType.value << 2); } public static Set getSiteIdsUsingV4Tokens(String siteIdsUsingV4TokensInString) { diff --git a/src/main/java/com/uid2/operator/service/UIDOperatorService.java b/src/main/java/com/uid2/operator/service/UIDOperatorService.java index 703735e49..c42bde293 100644 --- a/src/main/java/com/uid2/operator/service/UIDOperatorService.java +++ b/src/main/java/com/uid2/operator/service/UIDOperatorService.java @@ -1,9 +1,7 @@ package com.uid2.operator.service; import com.uid2.operator.model.*; -import com.uid2.operator.model.identities.FirstLevelHash; -import com.uid2.operator.model.identities.HashedDii; -import com.uid2.operator.model.identities.RawUid; +import com.uid2.operator.model.identities.*; import com.uid2.operator.util.PrivacyBits; import com.uid2.shared.model.SaltEntry; import com.uid2.operator.store.IOptOutStore; @@ -24,7 +22,7 @@ import java.time.format.DateTimeFormatter; import java.util.*; -import static com.uid2.operator.IdentityConst.*; +import static com.uid2.operator.model.identities.IdentityConst.*; import static com.uid2.operator.service.TokenUtils.getSiteIdsUsingV4Tokens; public class UIDOperatorService implements IUIDOperatorService { @@ -67,18 +65,18 @@ public UIDOperatorService(JsonObject config, IOptOutStore optOutStore, ISaltProv this.identityScope = identityScope; this.saltRetrievalResponseHandler = saltRetrievalResponseHandler; - this.testOptOutIdentityForEmail = getFirstLevelHashIdentity(identityScope, IdentityType.Email, - InputUtil.normalizeEmail(OptOutIdentityForEmail).getIdentityInput(), Instant.now()); - this.testOptOutIdentityForPhone = getFirstLevelHashIdentity(identityScope, IdentityType.Phone, - InputUtil.normalizePhone(OptOutIdentityForPhone).getIdentityInput(), Instant.now()); - this.testValidateIdentityForEmail = getFirstLevelHashIdentity(identityScope, IdentityType.Email, - InputUtil.normalizeEmail(ValidateIdentityForEmail).getIdentityInput(), Instant.now()); - this.testValidateIdentityForPhone = getFirstLevelHashIdentity(identityScope, IdentityType.Phone, - InputUtil.normalizePhone(ValidateIdentityForPhone).getIdentityInput(), Instant.now()); - this.testRefreshOptOutIdentityForEmail = getFirstLevelHashIdentity(identityScope, IdentityType.Email, - InputUtil.normalizeEmail(RefreshOptOutIdentityForEmail).getIdentityInput(), Instant.now()); - this.testRefreshOptOutIdentityForPhone = getFirstLevelHashIdentity(identityScope, IdentityType.Phone, - InputUtil.normalizePhone(RefreshOptOutIdentityForPhone).getIdentityInput(), Instant.now()); + this.testOptOutIdentityForEmail = getFirstLevelHashIdentity(identityScope, DiiType.Email, + InputUtil.normalizeEmail(OptOutIdentityForEmail).getHashedDiiInput(), Instant.now()); + this.testOptOutIdentityForPhone = getFirstLevelHashIdentity(identityScope, DiiType.Phone, + InputUtil.normalizePhone(OptOutIdentityForPhone).getHashedDiiInput(), Instant.now()); + this.testValidateIdentityForEmail = getFirstLevelHashIdentity(identityScope, DiiType.Email, + InputUtil.normalizeEmail(ValidateIdentityForEmail).getHashedDiiInput(), Instant.now()); + this.testValidateIdentityForPhone = getFirstLevelHashIdentity(identityScope, DiiType.Phone, + InputUtil.normalizePhone(ValidateIdentityForPhone).getHashedDiiInput(), Instant.now()); + this.testRefreshOptOutIdentityForEmail = getFirstLevelHashIdentity(identityScope, DiiType.Email, + InputUtil.normalizeEmail(RefreshOptOutIdentityForEmail).getHashedDiiInput(), Instant.now()); + this.testRefreshOptOutIdentityForPhone = getFirstLevelHashIdentity(identityScope, DiiType.Phone, + InputUtil.normalizePhone(RefreshOptOutIdentityForPhone).getHashedDiiInput(), Instant.now()); this.operatorIdentity = new OperatorIdentity(0, OperatorType.Service, 0, 0); @@ -109,7 +107,7 @@ public TokenGenerateResponse generateIdentity(TokenGenerateRequest request) { final Instant now = EncodingUtils.NowUTCMillis(this.clock); final byte[] firstLevelHash = getFirstLevelHash(request.hashedDii.hashedDii(), now); final FirstLevelHash firstLevelHashIdentity = new FirstLevelHash( - request.hashedDii.identityScope(), request.hashedDii.identityType(), firstLevelHash, + request.hashedDii.identityScope(), request.hashedDii.diiType(), firstLevelHash, request.establishedAt); if (request.shouldCheckOptOut() && getGlobalOptOutResult(firstLevelHashIdentity, false).isOptedOut()) { @@ -227,12 +225,12 @@ public Duration getIdentityExpiryDuration() { } private FirstLevelHash getFirstLevelHashIdentity(HashedDii hashedDii, Instant asOf) { - return getFirstLevelHashIdentity(hashedDii.identityScope(), hashedDii.identityType(), hashedDii.hashedDii(), asOf); + return getFirstLevelHashIdentity(hashedDii.identityScope(), hashedDii.diiType(), hashedDii.hashedDii(), asOf); } - private FirstLevelHash getFirstLevelHashIdentity(IdentityScope identityScope, IdentityType identityType, byte[] identityHash, Instant asOf) { - final byte[] firstLevelHash = getFirstLevelHash(identityHash, asOf); - return new FirstLevelHash(identityScope, identityType, firstLevelHash, null); + private FirstLevelHash getFirstLevelHashIdentity(IdentityScope identityScope, DiiType diiType, byte[] hashedDii, Instant asOf) { + final byte[] firstLevelHash = getFirstLevelHash(hashedDii, asOf); + return new FirstLevelHash(identityScope, diiType, firstLevelHash, null); } private byte[] getFirstLevelHash(byte[] identityHash, Instant asOf) { @@ -245,7 +243,7 @@ private IdentityMapResponseItem generateRawUid(FirstLevelHash firstLevelHash, In return new IdentityMapResponseItem( this.identityV3Enabled ? TokenUtils.getRawUidV3(firstLevelHash.identityScope(), - firstLevelHash.identityType(), firstLevelHash.firstLevelHash(), rotatingSalt.getSalt()) + firstLevelHash.diiType(), firstLevelHash.firstLevelHash(), rotatingSalt.getSalt()) : TokenUtils.getRawUidV2(firstLevelHash.firstLevelHash(), rotatingSalt.getSalt()), rotatingSalt.getHashedId()); } @@ -256,7 +254,7 @@ private TokenGenerateResponse generateIdentity(SourcePublisher sourcePublisher, final IdentityMapResponseItem identityMapResponseItem = generateRawUid(firstLevelHash, nowUtc); final RawUid rawUid = new RawUid(firstLevelHash.identityScope(), - firstLevelHash.identityType(), + firstLevelHash.diiType(), identityMapResponseItem.rawUid); return this.encoder.encodeIntoIdentityResponse( diff --git a/src/main/java/com/uid2/operator/service/V2RequestUtil.java b/src/main/java/com/uid2/operator/service/V2RequestUtil.java index cd4983865..a83849e79 100644 --- a/src/main/java/com/uid2/operator/service/V2RequestUtil.java +++ b/src/main/java/com/uid2/operator/service/V2RequestUtil.java @@ -1,8 +1,7 @@ package com.uid2.operator.service; -import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.identities.IdentityScope; import com.uid2.operator.model.KeyManager; -import com.uid2.operator.vertx.ClientInputValidationException; import com.uid2.shared.IClock; import com.uid2.shared.Utils; import com.uid2.shared.auth.ClientKey; @@ -15,7 +14,6 @@ import org.slf4j.LoggerFactory; import java.nio.charset.StandardCharsets; -import java.time.Clock; import java.time.Duration; import java.time.Instant; diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index a61af9790..045a58484 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -3,7 +3,8 @@ import com.uid2.operator.Const; import com.uid2.operator.model.*; import com.uid2.operator.model.TokenGenerateResponse; -import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.identities.IdentityScope; +import com.uid2.operator.model.identities.DiiType; import com.uid2.operator.model.identities.HashedDii; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.StatsCollectorHandler; @@ -69,7 +70,7 @@ import java.util.function.Supplier; import java.util.stream.Collectors; -import static com.uid2.operator.IdentityConst.*; +import static com.uid2.operator.model.identities.IdentityConst.*; import static com.uid2.operator.service.ResponseUtil.*; import static com.uid2.operator.vertx.Endpoints.*; @@ -469,7 +470,7 @@ else if(emailHash != null) { tokenGenerateResponse = this.idService.generateIdentity( new TokenGenerateRequest( new SourcePublisher(clientSideKeypair.getSiteId()), - input.toHashedDiiIdentity(this.identityScope), + input.toHashedDii(this.identityScope), OptoutCheckPolicy.RespectOptOut, privacyBits, Instant.now())); } catch (KeyManager.NoActiveKeyException e){ SendServerErrorResponseAndRecordStats(rc, "No active encryption key available", clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.NoActiveKey, siteProvider, e, platformType); @@ -878,11 +879,11 @@ private void handleTokenValidateV1(RoutingContext rc) { if (!isTokenInputValid(input, rc)) { return; } - if ((Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput()) && input.getIdentityType() == IdentityType.Email) - || (Arrays.equals(ValidateIdentityForPhoneHash, input.getIdentityInput()) && input.getIdentityType() == IdentityType.Phone)) { + if ((Arrays.equals(ValidateIdentityForEmailHash, input.getHashedDiiInput()) && input.getDiiType() == DiiType.Email) + || (Arrays.equals(ValidateIdentityForPhoneHash, input.getHashedDiiInput()) && input.getDiiType() == DiiType.Phone)) { try { final Instant now = Instant.now(); - if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope), now)) { + if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDii(this.identityScope), now)) { ResponseUtil.Success(rc, Boolean.TRUE); } else { ResponseUtil.Success(rc, Boolean.FALSE); @@ -909,13 +910,13 @@ private void handleTokenValidateV2(RoutingContext rc) { if (!isTokenInputValid(input, rc)) { return; } - if ((input.getIdentityType() == IdentityType.Email && Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput())) - || (input.getIdentityType() == IdentityType.Phone && Arrays.equals(ValidateIdentityForPhoneHash, input.getIdentityInput()))) { + if ((input.getDiiType() == DiiType.Email && Arrays.equals(ValidateIdentityForEmailHash, input.getHashedDiiInput())) + || (input.getDiiType() == DiiType.Phone && Arrays.equals(ValidateIdentityForPhoneHash, input.getHashedDiiInput()))) { try { final Instant now = Instant.now(); final String token = req.getString("token"); - if (this.idService.advertisingTokenMatches(token, input.toHashedDiiIdentity(this.identityScope), now)) { + if (this.idService.advertisingTokenMatches(token, input.toHashedDii(this.identityScope), now)) { ResponseUtil.SuccessV2(rc, Boolean.TRUE); } else { ResponseUtil.SuccessV2(rc, Boolean.FALSE); @@ -942,7 +943,7 @@ private void handleTokenGenerateV1(RoutingContext rc) { final TokenGenerateResponse response = this.idService.generateIdentity( new TokenGenerateRequest( new SourcePublisher(siteId), - input.toHashedDiiIdentity(this.identityScope), + input.toHashedDii(this.identityScope), OptoutCheckPolicy.defaultPolicy())); ResponseUtil.Success(rc, response.toJsonV1()); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV1, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, response.getAdvertisingTokenVersion(), platformType); @@ -994,12 +995,12 @@ private void handleTokenGenerateV2(RoutingContext rc) { final TokenGenerateResponse response = this.idService.generateIdentity( new TokenGenerateRequest( new SourcePublisher(siteId), - input.toHashedDiiIdentity(this.identityScope), + input.toHashedDii(this.identityScope), OptoutCheckPolicy.respectOptOut())); if (response.isOptedOut()) { if (optoutCheckPolicy.getItem1() == OptoutCheckPolicy.DoNotRespect) { // only legacy can use this policy - final InputUtil.InputVal optOutTokenInput = input.getIdentityType() == IdentityType.Email + final InputUtil.InputVal optOutTokenInput = input.getDiiType() == DiiType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) : InputUtil.InputVal.validPhone(OptOutTokenIdentityForPhone, OptOutTokenIdentityForPhone); @@ -1010,7 +1011,7 @@ private void handleTokenGenerateV2(RoutingContext rc) { final TokenGenerateResponse optOutTokens = this.idService.generateIdentity( new TokenGenerateRequest( new SourcePublisher(siteId), - optOutTokenInput.toHashedDiiIdentity(this.identityScope), + optOutTokenInput.toHashedDii(this.identityScope), OptoutCheckPolicy.DoNotRespect, pb, Instant.now())); ResponseUtil.SuccessV2(rc, optOutTokens.toJsonV1()); @@ -1050,7 +1051,7 @@ else if (!input.isValid()) { final TokenGenerateResponse response = this.idService.generateIdentity( new TokenGenerateRequest( new SourcePublisher(siteId), - input.toHashedDiiIdentity(this.identityScope), + input.toHashedDii(this.identityScope), OptoutCheckPolicy.defaultPolicy())); recordTokenResponseStats(siteId, TokenResponseStatsCollector.Endpoint.GenerateV0, TokenResponseStatsCollector.ResponseStatus.Success, siteProvider, response.getAdvertisingTokenVersion(), TokenResponseStatsCollector.PlatformType.Other); @@ -1087,10 +1088,10 @@ private void handleTokenRefresh(RoutingContext rc) { private void handleValidate(RoutingContext rc) { try { final InputUtil.InputVal input = getTokenInput(rc); - if (input != null && input.isValid() && Arrays.equals(ValidateIdentityForEmailHash, input.getIdentityInput())) { + if (input != null && input.isValid() && Arrays.equals(ValidateIdentityForEmailHash, input.getHashedDiiInput())) { try { final Instant now = Instant.now(); - if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDiiIdentity(this.identityScope), now)) { + if (this.idService.advertisingTokenMatches(rc.queryParam("token").get(0), input.toHashedDii(this.identityScope), now)) { rc.response().end("true"); } else { rc.response().end("false"); @@ -1111,7 +1112,7 @@ private void handleLogoutAsync(RoutingContext rc) { final InputUtil.InputVal input = this.phoneSupport ? getTokenInputV1(rc) : getTokenInput(rc); if (input.isValid()) { final Instant now = Instant.now(); - this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope), now, ar -> { + this.idService.invalidateTokensAsync(input.toHashedDii(this.identityScope), now, ar -> { if (ar.succeeded()) { rc.response().end("OK"); } else { @@ -1130,7 +1131,7 @@ private Future handleLogoutAsyncV2(RoutingContext rc) { final Instant now = Instant.now(); Promise promise = Promise.promise(); - this.idService.invalidateTokensAsync(input.toHashedDiiIdentity(this.identityScope), now, ar -> { + this.idService.invalidateTokensAsync(input.toHashedDii(this.identityScope), now, ar -> { if (ar.succeeded()) { JsonObject body = new JsonObject(); body.put("optout", "OK"); @@ -1152,7 +1153,7 @@ private void handleOptOutGet(RoutingContext rc) { if (input.isValid()) { try { final Instant now = Instant.now(); - final HashedDii hashedDii = input.toHashedDiiIdentity(this.identityScope); + final HashedDii hashedDii = input.toHashedDii(this.identityScope); final Instant result = this.idService.getLatestOptoutEntry(hashedDii, now); long timestamp = result == null ? -1 : result.getEpochSecond(); rc.response().setStatusCode(200) @@ -1237,7 +1238,7 @@ private void handleIdentityMapV1(RoutingContext rc) { } try { final Instant now = Instant.now(); - final IdentityMapResponseItem identityMapResponseItem = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); + final IdentityMapResponseItem identityMapResponseItem = this.idService.map(input.toHashedDii(this.identityScope), now); final JsonObject jsonObject = new JsonObject(); jsonObject.put("identifier", input.getProvided()); jsonObject.put("advertising_id", EncodingUtils.toBase64String(identityMapResponseItem.rawUid)); @@ -1254,7 +1255,7 @@ private void handleIdentityMap(RoutingContext rc) { try { if (isTokenInputValid(input, rc)) { final Instant now = Instant.now(); - final IdentityMapResponseItem identityMapResponseItem = this.idService.map(input.toHashedDiiIdentity(this.identityScope), now); + final IdentityMapResponseItem identityMapResponseItem = this.idService.map(input.toHashedDii(this.identityScope), now); rc.response().end(EncodingUtils.toBase64String(identityMapResponseItem.rawUid)); } } catch (Exception ex) { @@ -1427,16 +1428,16 @@ private InputUtil.InputVal[] getIdentityBulkInputV1(RoutingContext rc) { } if (emails != null && !emails.isEmpty()) { - return createInputListV1(emails, IdentityType.Email, InputUtil.IdentityInputType.Raw); + return createInputListV1(emails, DiiType.Email, InputUtil.DiiInputType.Raw); } else if (emailHashes != null && !emailHashes.isEmpty()) { - return createInputListV1(emailHashes, IdentityType.Email, InputUtil.IdentityInputType.Hash); + return createInputListV1(emailHashes, DiiType.Email, InputUtil.DiiInputType.Hash); } else if (phones != null && !phones.isEmpty()) { - return createInputListV1(phones, IdentityType.Phone, InputUtil.IdentityInputType.Raw); + return createInputListV1(phones, DiiType.Phone, InputUtil.DiiInputType.Raw); } else if (phoneHashes != null && !phoneHashes.isEmpty()) { - return createInputListV1(phoneHashes, IdentityType.Phone, InputUtil.IdentityInputType.Hash); + return createInputListV1(phoneHashes, DiiType.Phone, InputUtil.DiiInputType.Hash); } else { // handle empty array - return createInputListV1(null, IdentityType.Email, InputUtil.IdentityInputType.Raw); + return createInputListV1(null, DiiType.Email, InputUtil.DiiInputType.Raw); } } @@ -1452,7 +1453,7 @@ private JsonObject handleIdentityMapCommon(RoutingContext rc, InputUtil.InputVal if (input != null && input.isValid()) { final IdentityMapResponseItem identityMapResponseItem = idService.mapHashedDii( new IdentityMapRequestItem( - input.toHashedDiiIdentity(this.identityScope), + input.toHashedDii(this.identityScope), OptoutCheckPolicy.respectOptOut(), now)); @@ -1528,7 +1529,7 @@ private InputUtil.InputVal[] getIdentityMapV2Input(RoutingContext rc) { Supplier getInputList = null; final JsonArray emails = JsonParseUtils.parseArray(obj, "email", rc); if (emails != null && !emails.isEmpty()) { - getInputList = () -> createInputListV1(emails, IdentityType.Email, InputUtil.IdentityInputType.Raw); + getInputList = () -> createInputListV1(emails, DiiType.Email, InputUtil.DiiInputType.Raw); } final JsonArray emailHashes = JsonParseUtils.parseArray(obj, "email_hash", rc); @@ -1536,7 +1537,7 @@ private InputUtil.InputVal[] getIdentityMapV2Input(RoutingContext rc) { if (getInputList != null) { return null; // only one type of input is allowed } - getInputList = () -> createInputListV1(emailHashes, IdentityType.Email, InputUtil.IdentityInputType.Hash); + getInputList = () -> createInputListV1(emailHashes, DiiType.Email, InputUtil.DiiInputType.Hash); } final JsonArray phones = this.phoneSupport ? JsonParseUtils.parseArray(obj,"phone", rc) : null; @@ -1544,7 +1545,7 @@ private InputUtil.InputVal[] getIdentityMapV2Input(RoutingContext rc) { if (getInputList != null) { return null; // only one type of input is allowed } - getInputList = () -> createInputListV1(phones, IdentityType.Phone, InputUtil.IdentityInputType.Raw); + getInputList = () -> createInputListV1(phones, DiiType.Phone, InputUtil.DiiInputType.Raw); } final JsonArray phoneHashes = this.phoneSupport ? JsonParseUtils.parseArray(obj,"phone_hash", rc) : null; @@ -1552,7 +1553,7 @@ private InputUtil.InputVal[] getIdentityMapV2Input(RoutingContext rc) { if (getInputList != null) { return null; // only one type of input is allowed } - getInputList = () -> createInputListV1(phoneHashes, IdentityType.Phone, InputUtil.IdentityInputType.Hash); + getInputList = () -> createInputListV1(phoneHashes, DiiType.Phone, InputUtil.DiiInputType.Hash); } if (emails == null && emailHashes == null && phones == null && phoneHashes == null) { @@ -1560,7 +1561,7 @@ private InputUtil.InputVal[] getIdentityMapV2Input(RoutingContext rc) { } return getInputList == null ? - createInputListV1(null, IdentityType.Email, InputUtil.IdentityInputType.Raw) : // handle empty array + createInputListV1(null, DiiType.Email, InputUtil.DiiInputType.Raw) : // handle empty array getInputList.get(); } @@ -1854,31 +1855,31 @@ private InputUtil.InputVal[] createInputList(JsonArray a, boolean inputAsHash) { } - private InputUtil.InputVal[] createInputListV1(JsonArray a, IdentityType identityType, InputUtil.IdentityInputType inputType) { + private InputUtil.InputVal[] createInputListV1(JsonArray a, DiiType diiType, InputUtil.DiiInputType inputType) { if (a == null || a.isEmpty()) { return new InputUtil.InputVal[0]; } final int size = a.size(); final InputUtil.InputVal[] resp = new InputUtil.InputVal[size]; - if (identityType == IdentityType.Email) { - if (inputType == InputUtil.IdentityInputType.Raw) { + if (diiType == DiiType.Email) { + if (inputType == InputUtil.DiiInputType.Raw) { for (int i = 0; i < size; ++i) { resp[i] = InputUtil.normalizeEmail(a.getString(i)); } - } else if (inputType == InputUtil.IdentityInputType.Hash) { + } else if (inputType == InputUtil.DiiInputType.Hash) { for (int i = 0; i < size; ++i) { resp[i] = InputUtil.normalizeEmailHash(a.getString(i)); } } else { throw new IllegalStateException("inputType"); } - } else if (identityType == IdentityType.Phone) { - if (inputType == InputUtil.IdentityInputType.Raw) { + } else if (diiType == DiiType.Phone) { + if (inputType == InputUtil.DiiInputType.Raw) { for (int i = 0; i < size; ++i) { resp[i] = InputUtil.normalizePhone(a.getString(i)); } - } else if (inputType == InputUtil.IdentityInputType.Hash) { + } else if (inputType == InputUtil.DiiInputType.Hash) { for (int i = 0; i < size; ++i) { resp[i] = InputUtil.normalizePhoneHash(a.getString(i)); } diff --git a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java index 07ab3ff58..b55fca5a3 100644 --- a/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java +++ b/src/main/java/com/uid2/operator/vertx/V2PayloadHandler.java @@ -1,6 +1,6 @@ package com.uid2.operator.vertx; -import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.identities.IdentityScope; import com.uid2.operator.model.KeyManager; import com.uid2.operator.monitoring.TokenResponseStatsCollector; import com.uid2.operator.service.EncodingUtils; diff --git a/src/test/java/com/uid2/operator/EUIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/EUIDOperatorVerticleTest.java index 8d168d42e..c4a765179 100644 --- a/src/test/java/com/uid2/operator/EUIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/EUIDOperatorVerticleTest.java @@ -3,7 +3,7 @@ import com.uid2.shared.model.TokenVersion; import org.junit.jupiter.api.Test; -import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.identities.IdentityScope; import com.uid2.shared.auth.Role; import io.vertx.core.Vertx; diff --git a/src/test/java/com/uid2/operator/InputNormalizationTest.java b/src/test/java/com/uid2/operator/InputNormalizationTest.java index adbefbeae..6f825608a 100644 --- a/src/test/java/com/uid2/operator/InputNormalizationTest.java +++ b/src/test/java/com/uid2/operator/InputNormalizationTest.java @@ -71,7 +71,7 @@ public void testValidEmailNormalization() { Assert.assertEquals(normalization.getProvided(), testCase[0]); Assert.assertTrue(normalization.isValid()); Assert.assertEquals(testCase[1], normalization.getNormalized()); - Assert.assertEquals(testCase[2], EncodingUtils.toBase64String(normalization.getIdentityInput())); + Assert.assertEquals(testCase[2], EncodingUtils.toBase64String(normalization.getHashedDiiInput())); } } @@ -90,7 +90,7 @@ public void testValidHashNormalization() { Assert.assertEquals(s, normalization.getProvided()); Assert.assertTrue(normalization.isValid()); Assert.assertEquals(masterHash, normalization.getNormalized()); - Assert.assertEquals(masterHash, EncodingUtils.toBase64String(normalization.getIdentityInput())); + Assert.assertEquals(masterHash, EncodingUtils.toBase64String(normalization.getHashedDiiInput())); } } diff --git a/src/test/java/com/uid2/operator/TokenEncodingTest.java b/src/test/java/com/uid2/operator/TokenEncodingTest.java index 039ebd17f..d216ad04b 100644 --- a/src/test/java/com/uid2/operator/TokenEncodingTest.java +++ b/src/test/java/com/uid2/operator/TokenEncodingTest.java @@ -1,7 +1,9 @@ package com.uid2.operator; import com.uid2.operator.model.*; +import com.uid2.operator.model.identities.DiiType; import com.uid2.operator.model.identities.FirstLevelHash; +import com.uid2.operator.model.identities.IdentityScope; import com.uid2.operator.model.identities.RawUid; import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; @@ -60,7 +62,7 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) { now.plusSeconds(360), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new FirstLevelHash(IdentityScope.UID2, IdentityType.Email, firstLevelHash, now), + new FirstLevelHash(IdentityScope.UID2, DiiType.Email, firstLevelHash, now), PrivacyBits.fromInt(121) ); @@ -95,7 +97,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { final EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(this.keyManager); final Instant now = EncodingUtils.NowUTCMillis(); - final byte[] rawUid = UIDOperatorVerticleTest.getRawUid(IdentityType.Email, "test@example.com", IdentityScope.UID2, tokenVersion != TokenVersion.V2); + final byte[] rawUid = UIDOperatorVerticleTest.getRawUid(DiiType.Email, "test@example.com", IdentityScope.UID2, tokenVersion != TokenVersion.V2); final AdvertisingTokenRequest adTokenRequest = new AdvertisingTokenRequest( tokenVersion, @@ -103,7 +105,7 @@ public void testAdvertisingTokenEncodings(TokenVersion tokenVersion) { now.plusSeconds(60), new OperatorIdentity(101, OperatorType.Service, 102, 103), new SourcePublisher(111, 112, 113), - new RawUid(IdentityScope.UID2, IdentityType.Email, rawUid), + new RawUid(IdentityScope.UID2, DiiType.Email, rawUid), PrivacyBits.fromInt(121), now ); diff --git a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java index bd4874c6e..5c2e24e86 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorServiceTest.java @@ -1,9 +1,7 @@ package com.uid2.operator; import com.uid2.operator.model.*; -import com.uid2.operator.model.identities.FirstLevelHash; -import com.uid2.operator.model.identities.HashedDii; -import com.uid2.operator.model.identities.RawUid; +import com.uid2.operator.model.identities.*; import com.uid2.operator.service.*; import com.uid2.operator.service.EncodingUtils; import com.uid2.operator.service.EncryptedTokenEncoder; @@ -146,7 +144,7 @@ private void setNow(Instant now) { when(clock.instant()).thenAnswer(i -> this.now); } - private HashedDii createHashedDiiIdentity(String rawIdentityHash, IdentityScope scope, IdentityType type) { + private HashedDii createHashedDiiIdentity(String rawIdentityHash, IdentityScope scope, DiiType type) { return new HashedDii( scope, type, @@ -154,28 +152,28 @@ private HashedDii createHashedDiiIdentity(String rawIdentityHash, IdentityScope ); } - private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, IdentityType type, int siteId) { + private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder tokenEncoder, String advertisingTokenString, IdentityScope scope, DiiType type, int siteId) { TokenVersion tokenVersion = (scope == IdentityScope.UID2) ? uid2Service.getAdvertisingTokenVersionForTests(siteId) : euidService.getAdvertisingTokenVersionForTests(siteId); UIDOperatorVerticleTest.validateAdvertisingToken(advertisingTokenString, tokenVersion, scope, type); return tokenEncoder.decodeAdvertisingToken(advertisingTokenString); } - private void assertIdentityScopeIdentityType(IdentityScope expectedScope, IdentityType expectedIdentityType, + private void assertIdentityScopeIdentityType(IdentityScope expectedScope, DiiType expectedDiiType, HashedDii hashedDii) { assertEquals(expectedScope, hashedDii.identityScope()); - assertEquals(expectedIdentityType, hashedDii.identityType()); + assertEquals(expectedDiiType, hashedDii.diiType()); } - private void assertIdentityScopeIdentityType(IdentityScope expectedScope, IdentityType expectedIdentityType, + private void assertIdentityScopeIdentityType(IdentityScope expectedScope, DiiType expectedDiiType, RawUid rawUid) { assertEquals(expectedScope, rawUid.identityScope()); - assertEquals(expectedIdentityType, rawUid.identityType()); + assertEquals(expectedDiiType, rawUid.diiType()); } - private void assertIdentityScopeIdentityType(IdentityScope expectedScope, IdentityType expectedIdentityType, + private void assertIdentityScopeIdentityType(IdentityScope expectedScope, DiiType expectedDiiType, FirstLevelHash firstLevelHash) { assertEquals(expectedScope, firstLevelHash.identityScope()); - assertEquals(expectedIdentityType, firstLevelHash.identityType()); + assertEquals(expectedDiiType, firstLevelHash.diiType()); } @@ -186,12 +184,12 @@ private void assertIdentityScopeIdentityType(IdentityScope expectedScope, Identi @CsvSource({"123, V2","127, V4","128, V4"}) //site id 127 and 128 is for testing "site_ids_using_v4_tokens" public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { IdentityScope expectedIdentityScope = IdentityScope.UID2; - IdentityType expectedIdentityType = IdentityType.Email; + DiiType expectedDiiType = DiiType.Email; final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(siteId, 124, 125), - createHashedDiiIdentity("test-email-hash", expectedIdentityScope, expectedIdentityType), + createHashedDiiIdentity("test-email-hash", expectedIdentityScope, expectedDiiType), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now.minusSeconds(234) ); @@ -200,11 +198,11 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokenGenerateResponse); - UIDOperatorVerticleTest.validateAdvertisingToken(tokenGenerateResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + UIDOperatorVerticleTest.validateAdvertisingToken(tokenGenerateResponse.getAdvertisingToken(), tokenVersion, IdentityScope.UID2, DiiType.Email); AdvertisingTokenRequest advertisingTokenRequest = tokenEncoder.decodeAdvertisingToken(tokenGenerateResponse.getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenRequest.expiresAt); assertEquals(tokenGenerateRequest.sourcePublisher.siteId, advertisingTokenRequest.sourcePublisher.siteId); - assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, + assertIdentityScopeIdentityType(expectedIdentityScope, expectedDiiType, advertisingTokenRequest.rawUid); assertEquals(tokenGenerateRequest.establishedAt, advertisingTokenRequest.establishedAt); assertEquals(tokenGenerateRequest.privacyBits, advertisingTokenRequest.privacyBits); @@ -213,7 +211,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(this.now, tokenRefreshRequest.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), tokenRefreshRequest.expiresAt); assertEquals(tokenGenerateRequest.sourcePublisher.siteId, tokenRefreshRequest.sourcePublisher.siteId); - assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, tokenRefreshRequest.firstLevelHash); + assertIdentityScopeIdentityType(expectedIdentityScope, expectedDiiType, tokenRefreshRequest.firstLevelHash); assertEquals(tokenGenerateRequest.establishedAt, tokenRefreshRequest.firstLevelHash.establishedAt()); final byte[] firstLevelHash = getFirstLevelHash(tokenGenerateRequest.hashedDii.hashedDii(), @@ -231,11 +229,11 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(TokenRefreshResponse.Status.Refreshed, refreshResponse.getStatus()); assertNotNull(refreshResponse.getIdentityResponse()); - UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, IdentityType.Email); + UIDOperatorVerticleTest.validateAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken(), tokenVersion, IdentityScope.UID2, DiiType.Email); AdvertisingTokenRequest advertisingTokenRequest2 = tokenEncoder.decodeAdvertisingToken(refreshResponse.getIdentityResponse().getAdvertisingToken()); assertEquals(this.now.plusSeconds(IDENTITY_TOKEN_EXPIRES_AFTER_SECONDS), advertisingTokenRequest2.expiresAt); assertEquals(advertisingTokenRequest.sourcePublisher.siteId, advertisingTokenRequest2.sourcePublisher.siteId); - assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, + assertIdentityScopeIdentityType(expectedIdentityScope, expectedDiiType, advertisingTokenRequest2.rawUid); assertEquals(advertisingTokenRequest.establishedAt, advertisingTokenRequest2.establishedAt); assertArrayEquals(advertisingTokenRequest.rawUid.rawUid(), @@ -246,7 +244,7 @@ public void testGenerateAndRefresh(int siteId, TokenVersion tokenVersion) { assertEquals(this.now, tokenRefreshRequest2.createdAt); assertEquals(this.now.plusSeconds(REFRESH_TOKEN_EXPIRES_AFTER_SECONDS), tokenRefreshRequest2.expiresAt); assertEquals(tokenRefreshRequest.sourcePublisher.siteId, tokenRefreshRequest2.sourcePublisher.siteId); - assertIdentityScopeIdentityType(expectedIdentityScope, expectedIdentityType, tokenRefreshRequest2.firstLevelHash); + assertIdentityScopeIdentityType(expectedIdentityScope, expectedDiiType, tokenRefreshRequest2.firstLevelHash); assertEquals(tokenRefreshRequest.firstLevelHash.establishedAt(), tokenRefreshRequest2.firstLevelHash.establishedAt()); assertArrayEquals(tokenRefreshRequest.firstLevelHash.firstLevelHash(), tokenRefreshRequest2.firstLevelHash.firstLevelHash()); assertArrayEquals(firstLevelHash, tokenRefreshRequest2.firstLevelHash.firstLevelHash()); @@ -258,7 +256,7 @@ public void testTestOptOutKey_DoNotRespectOptout() { final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(IdentityScope.UID2), + inputVal.toHashedDii(IdentityScope.UID2), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); final TokenGenerateResponse tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); @@ -277,7 +275,7 @@ public void testTestOptOutKey_RespectOptout() { final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(IdentityScope.UID2), + inputVal.toHashedDii(IdentityScope.UID2), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); final TokenGenerateResponse tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); @@ -293,7 +291,7 @@ public void testTestOptOutKeyIdentityScopeMismatch() { final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(IdentityScope.EUID), + inputVal.toHashedDii(IdentityScope.EUID), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); final TokenGenerateResponse tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); @@ -312,8 +310,8 @@ public void testTestOptOutKeyIdentityScopeMismatch() { "Email,test@example.com,EUID", "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) - public void testGenerateTokenForOptOutUser(IdentityType type, String id, IdentityScope scope) { - final HashedDii hashedDii = createHashedDiiIdentity(TokenUtils.getIdentityHashString(id), + public void testGenerateTokenForOptOutUser(DiiType type, String id, IdentityScope scope) { + final HashedDii hashedDii = createHashedDiiIdentity(TokenUtils.getDiiHashString(id), scope, type); final TokenGenerateRequest tokenGenerateRequestForceGenerate = new TokenGenerateRequest( @@ -339,7 +337,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDii.identityType(), tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, hashedDii.diiType(), tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); tokenGenerateResponseAfterOptOut = uid2Service.generateIdentity(tokenGenerateRequestRespectOptOut); @@ -347,7 +345,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequestForceGenerate); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDii.identityType(), tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, hashedDii.diiType(), tokenGenerateRequestRespectOptOut.sourcePublisher.siteId); reset(shutdownHandler); tokenGenerateResponseAfterOptOut = euidService.generateIdentity(tokenGenerateRequestRespectOptOut); } @@ -365,7 +363,7 @@ public void testGenerateTokenForOptOutUser(IdentityType type, String id, Identit "Email,test@example.com,EUID", "Phone,+01010101010,UID2", "Phone,+01010101010,EUID"}) - public void testIdentityMapForOptOutUser(IdentityType type, String identity, IdentityScope scope) { + public void testIdentityMapForOptOutUser(DiiType type, String identity, IdentityScope scope) { final HashedDii hashedDii = createHashedDiiIdentity(identity, scope, type); final Instant now = Instant.now(); @@ -451,7 +449,7 @@ void testSpecialIdentityOptOutTokenGenerate(TestIdentityInputType type, String i final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); @@ -483,7 +481,7 @@ void testSpecialIdentityOptOutIdentityMap(TestIdentityInputType type, String id, InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -517,7 +515,7 @@ void testSpecialIdentityOptOutTokenRefresh(TestIdentityInputType type, String id final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.DoNotRespect, PrivacyBits.fromInt(0), this.now ); @@ -556,7 +554,7 @@ void testSpecialIdentityRefreshOptOutGenerate(TestIdentityInputType type, String final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); @@ -597,7 +595,7 @@ void testSpecialIdentityRefreshOptOutIdentityMap(TestIdentityInputType type, Str InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -631,7 +629,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now ); @@ -646,7 +644,7 @@ void testSpecialIdentityValidateGenerate(TestIdentityInputType type, String id, else { tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); } - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), scope, tokenGenerateRequest.hashedDii.identityType(), tokenGenerateRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), scope, tokenGenerateRequest.hashedDii.diiType(), tokenGenerateRequest.sourcePublisher.siteId); verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(false); verify(shutdownHandler, never()).handleSaltRetrievalResponse(true); assertNotNull(tokenGenerateResponse); @@ -668,7 +666,7 @@ void testSpecialIdentityValidateIdentityMap(TestIdentityInputType type, String i InputUtil.InputVal inputVal = generateInputVal(type, id); final IdentityMapRequestItem identityMapRequestItemRespectOptOut = new IdentityMapRequestItem( - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, now); @@ -699,7 +697,7 @@ void testNormalIdentityOptIn(TestIdentityInputType type, String id, IdentityScop InputUtil.InputVal inputVal = generateInputVal(type, id); final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.DoNotRespect ); TokenGenerateResponse tokenGenerateResponse; @@ -760,7 +758,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String final TokenGenerateRequest tokenGenerateRequest = new TokenGenerateRequest( new SourcePublisher(123, 124, 125), - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, PrivacyBits.fromInt(0), this.now); TokenGenerateResponse tokenGenerateResponse; @@ -768,11 +766,11 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String reset(shutdownHandler); if(scope == IdentityScope.EUID) { tokenGenerateResponse = euidService.generateIdentity(tokenGenerateRequest); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, tokenGenerateRequest.hashedDii.identityType(), tokenGenerateRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.EUID, tokenGenerateRequest.hashedDii.diiType(), tokenGenerateRequest.sourcePublisher.siteId); } else { tokenGenerateResponse = uid2Service.generateIdentity(tokenGenerateRequest); - advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, tokenGenerateRequest.hashedDii.identityType(), tokenGenerateRequest.sourcePublisher.siteId); + advertisingTokenRequest = validateAndGetToken(tokenEncoder, tokenGenerateResponse.getAdvertisingToken(), IdentityScope.UID2, tokenGenerateRequest.hashedDii.diiType(), tokenGenerateRequest.sourcePublisher.siteId); } verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); verify(shutdownHandler, never()).handleSaltRetrievalResponse(false); @@ -790,7 +788,7 @@ void testExpiredSaltsNotifiesShutdownHandler(TestIdentityInputType type, String assertNotEquals(TokenRefreshResponse.Optout, refreshResponse); final IdentityMapRequestItem identityMapRequestItem = new IdentityMapRequestItem( - inputVal.toHashedDiiIdentity(scope), + inputVal.toHashedDii(scope), OptoutCheckPolicy.RespectOptOut, now); final IdentityMapResponseItem identityMapResponseItem; diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 6ee61fe3c..5e19ddbcd 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -4,7 +4,8 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; import com.uid2.operator.model.*; -import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.identities.IdentityScope; +import com.uid2.operator.model.identities.DiiType; import com.uid2.operator.model.identities.FirstLevelHash; import com.uid2.operator.monitoring.IStatsCollectorQueue; import com.uid2.operator.monitoring.TokenResponseStatsCollector; @@ -69,7 +70,7 @@ import java.util.stream.Stream; import static com.uid2.operator.ClientSideTokenGenerateTestUtil.decrypt; -import static com.uid2.operator.IdentityConst.*; +import static com.uid2.operator.model.identities.IdentityConst.*; import static com.uid2.operator.service.EncodingUtils.getSha256; import static com.uid2.operator.vertx.UIDOperatorVerticle.*; import static com.uid2.shared.Const.Data.*; @@ -622,26 +623,26 @@ private void assertTokenStatusMetrics(Integer siteId, TokenResponseStatsCollecto assertEquals(1, actual); } - private byte[] getRawUidFromIdentity(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt) { - return getRawUid(identityType, identityString, firstLevelSalt, rotatingSalt, getIdentityScope(), useIdentityV3()); + private byte[] getRawUidFromIdentity(DiiType diiType, String identityString, String firstLevelSalt, String rotatingSalt) { + return getRawUid(diiType, identityString, firstLevelSalt, rotatingSalt, getIdentityScope(), useIdentityV3()); } - private static byte[] getRawUid(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt, IdentityScope identityScope, boolean useIdentityV3) { + private static byte[] getRawUid(DiiType diiType, String identityString, String firstLevelSalt, String rotatingSalt, IdentityScope identityScope, boolean useIdentityV3) { return !useIdentityV3 ? TokenUtils.getRawUidV2FromIdentity(identityString, firstLevelSalt, rotatingSalt) - : TokenUtils.getRawUidV3FromIdentity(identityScope, identityType, identityString, firstLevelSalt, rotatingSalt); + : TokenUtils.getRawUidV3FromIdentity(identityScope, diiType, identityString, firstLevelSalt, rotatingSalt); } - public static byte[] getRawUid(IdentityType identityType, String identityString, IdentityScope identityScope, boolean useIdentityV3) { + public static byte[] getRawUid(DiiType diiType, String identityString, IdentityScope identityScope, boolean useIdentityV3) { return !useIdentityV3 ? TokenUtils.getRawUidV2FromIdentity(identityString, firstLevelSalt, rotatingSalt123.getSalt()) - : TokenUtils.getRawUidV3FromIdentity(identityScope, identityType, identityString, firstLevelSalt, rotatingSalt123.getSalt()); + : TokenUtils.getRawUidV3FromIdentity(identityScope, diiType, identityString, firstLevelSalt, rotatingSalt123.getSalt()); } - private byte[] getRawUidFromIdentityHash(IdentityType identityType, String identityString, String firstLevelSalt, String rotatingSalt) { + private byte[] getRawUidFromIdentityHash(DiiType diiType, String identityString, String firstLevelSalt, String rotatingSalt) { return !useIdentityV3() ? TokenUtils.getRawUidV2FromIdentityHash(identityString, firstLevelSalt, rotatingSalt) - : TokenUtils.getRawUidV3FromIdentityHash(getIdentityScope(), identityType, identityString, firstLevelSalt, rotatingSalt); + : TokenUtils.getRawUidV3FromIdentityHash(getIdentityScope(), diiType, identityString, firstLevelSalt, rotatingSalt); } private JsonObject createBatchEmailsRequestPayload() { @@ -765,7 +766,7 @@ void keyLatestHideRefreshKey(String apiVersion, Vertx vertx, VertxTestContext te void tokenGenerateBothEmailAndHashSpecified(String apiVersion, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; final String emailAddress = "test@uid2.com"; - final String emailHash = TokenUtils.getIdentityHashString(emailAddress); + final String emailHash = TokenUtils.getDiiHashString(emailAddress); fakeAuth(clientSiteId, Role.GENERATOR); setupSalts(); setupKeys(); @@ -813,25 +814,25 @@ private void assertStatsCollector(String path, String referer, String apiContact assertEquals(siteId, messageItem.getSiteId()); } - private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder encoder, JsonObject body, IdentityType identityType) { //See UID2-79+Token+and+ID+format+v3 + private AdvertisingTokenRequest validateAndGetToken(EncryptedTokenEncoder encoder, JsonObject body, DiiType diiType) { //See UID2-79+Token+and+ID+format+v3 final String advertisingTokenString = body.getString("advertising_token"); - validateAdvertisingToken(advertisingTokenString, getTokenVersion(), getIdentityScope(), identityType); + validateAdvertisingToken(advertisingTokenString, getTokenVersion(), getIdentityScope(), diiType); AdvertisingTokenRequest advertisingTokenRequest = encoder.decodeAdvertisingToken(advertisingTokenString); if (getTokenVersion() == TokenVersion.V4) { - assertEquals(identityType, advertisingTokenRequest.rawUid.identityType()); + assertEquals(diiType, advertisingTokenRequest.rawUid.diiType()); } return advertisingTokenRequest; } - public static void validateAdvertisingToken(String advertisingTokenString, TokenVersion tokenVersion, IdentityScope identityScope, IdentityType identityType) { + public static void validateAdvertisingToken(String advertisingTokenString, TokenVersion tokenVersion, IdentityScope identityScope, DiiType diiType) { if (tokenVersion == TokenVersion.V2) { assertEquals("Ag", advertisingTokenString.substring(0, 2)); } else { String firstChar = advertisingTokenString.substring(0, 1); if (identityScope == IdentityScope.UID2) { - assertEquals(identityType == IdentityType.Email ? "A" : "B", firstChar); + assertEquals(diiType == DiiType.Email ? "A" : "B", firstChar); } else { - assertEquals(identityType == IdentityType.Email ? "E" : "F", firstChar); + assertEquals(diiType == DiiType.Email ? "E" : "F", firstChar); } String secondChar = advertisingTokenString.substring(1, 2); @@ -848,10 +849,10 @@ public static void validateAdvertisingToken(String advertisingTokenString, Token } } - TokenRefreshRequest decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, IdentityType identityType) { + TokenRefreshRequest decodeRefreshToken(EncryptedTokenEncoder encoder, String refreshTokenString, DiiType diiType) { TokenRefreshRequest tokenRefreshRequest = encoder.decodeRefreshToken(refreshTokenString); assertEquals(getIdentityScope(), tokenRefreshRequest.firstLevelHash.identityScope()); - assertEquals(identityType, tokenRefreshRequest.firstLevelHash.identityType()); + assertEquals(diiType, tokenRefreshRequest.firstLevelHash.diiType()); return tokenRefreshRequest; } @@ -1125,7 +1126,7 @@ void tokenGenerateNewClientWrongPolicySpecifiedOlderKeySuccessful(String policyP "policy,+01234567890,Phone", "optout_check,someoptout@example.com,Email", "optout_check,+01234567890,Phone"}) - void tokenGenerateOptOutToken(String policyParameterKey, String identity, IdentityType identityType, + void tokenGenerateOptOutToken(String policyParameterKey, String identity, DiiType diiType, Vertx vertx, VertxTestContext testContext) { ClientKey oldClientKey = new ClientKey( null, @@ -1145,13 +1146,13 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi setupKeys(); JsonObject v2Payload = new JsonObject(); - v2Payload.put(identityType.name().toLowerCase(), identity); + v2Payload.put(diiType.name().toLowerCase(), identity); v2Payload.put(policyParameterKey, OptoutCheckPolicy.DoNotRespect.policy); sendTokenGenerate("v2", vertx, "", v2Payload, 200, json -> { - InputUtil.InputVal optOutTokenInput = identityType == IdentityType.Email ? + InputUtil.InputVal optOutTokenInput = diiType == DiiType.Email ? InputUtil.InputVal.validEmail(OptOutTokenIdentityForEmail, OptOutTokenIdentityForEmail) : InputUtil.InputVal.validPhone(OptOutIdentityForPhone, OptOutTokenIdentityForPhone); @@ -1164,9 +1165,9 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, identityType); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, diiType); TokenRefreshRequest tokenRefreshRequest = encoder.decodeRefreshToken(body.getString("decrypted_refresh_token")); - final byte[] rawUid = getRawUidFromIdentity(identityType, + final byte[] rawUid = getRawUidFromIdentity(diiType, optOutTokenInput.getNormalized(), firstLevelSalt, rotatingSalt123.getSalt()); @@ -1177,7 +1178,7 @@ void tokenGenerateOptOutToken(String policyParameterKey, String identity, Identi String advertisingTokenString = body.getString("advertising_token"); final Instant now = Instant.now(); final String token = advertisingTokenString; - final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDiiIdentity(getIdentityScope()), now); + final boolean matchedOptedOutIdentity = this.uidOperatorVerticle.getIdService().advertisingTokenMatches(token, optOutTokenInput.toHashedDii(getIdentityScope()), now); assertTrue(matchedOptedOutIdentity); assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); assertTrue(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); @@ -1224,11 +1225,11 @@ void tokenGenerateForEmail(String apiVersion, Vertx vertx, VertxTestContext test assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, DiiType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), DiiType.Email); assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, - getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), + getRawUidFromIdentity(DiiType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt)); @@ -1264,7 +1265,7 @@ public void verifyPrivacyBits(PrivacyBits expectedValue, AdvertisingTokenRequest @ValueSource(strings = {"v1", "v2"}) void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; - final String emailHash = TokenUtils.getIdentityHashString("test@uid2.com"); + final String emailHash = TokenUtils.getDiiHashString("test@uid2.com"); fakeAuth(clientSiteId, Role.GENERATOR); setupSalts(); setupKeys(); @@ -1281,11 +1282,11 @@ void tokenGenerateForEmailHash(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token"), IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, DiiType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, apiVersion.equals("v2") ? body.getString("decrypted_refresh_token") : body.getString("refresh_token"), DiiType.Email); assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, - getRawUidFromIdentityHash(IdentityType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), + getRawUidFromIdentityHash(DiiType.Email, emailHash, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, TokenUtils.getFirstLevelHashFromIdentityHash(emailHash, firstLevelSalt)); @@ -1312,16 +1313,16 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenRequest firstAdvertisingTokenRequest = validateAndGetToken(encoder, bodyJson, - IdentityType.Email); + DiiType.Email); - TokenRefreshRequest firstTokenRefreshRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + TokenRefreshRequest firstTokenRefreshRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), DiiType.Email); assertEquals(firstAdvertisingTokenRequest.establishedAt, firstTokenRefreshRequest.firstLevelHash.establishedAt()); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()); + byte[] expectedRawUidIdentity = getRawUidFromIdentity(DiiType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()); byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt); assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstTokenRefreshRequest, clientSiteId, @@ -1338,10 +1339,10 @@ void tokenGenerateThenRefresh(String apiVersion, Vertx vertx, VertxTestContext t assertNotNull(refreshBody); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, DiiType.Email); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, DiiType.Email); // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh assertAdvertisingTokenRefreshTokenRequests( @@ -1411,16 +1412,16 @@ void tokenGenerateThenRefreshSaltsExpired(String apiVersion, Vertx vertx, VertxT assertNotNull(refreshBody); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, DiiType.Email); assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); + assertArrayEquals(getRawUidFromIdentity(DiiType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, DiiType.Email); assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHash.firstLevelHash()); @@ -1589,11 +1590,11 @@ void tokenGenerateUsingCustomSiteKey(String apiVersion, Vertx vertx, VertxTestCo assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, DiiType.Email); assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); + assertArrayEquals(getRawUidFromIdentity(DiiType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), DiiType.Email); assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHash.firstLevelHash()); @@ -1623,16 +1624,16 @@ void tokenGenerateSaltsExpired(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, DiiType.Email); assertTrue(advertisingTokenRequest.privacyBits.isLegacyBitSet()); assertEquals(advertisingTokenRequest.privacyBits, PrivacyBits.DEFAULT); assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenGenerated()); assertFalse(advertisingTokenRequest.privacyBits.isClientSideTokenOptedOut()); assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); - assertArrayEquals(getRawUidFromIdentity(IdentityType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); + assertArrayEquals(getRawUidFromIdentity(DiiType.Email, emailAddress, firstLevelSalt, rotatingSalt123.getSalt()), advertisingTokenRequest.rawUid.rawUid()); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Email); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), DiiType.Email); assertEquals(clientSiteId, tokenRefreshRequest.sourcePublisher.siteId); assertArrayEquals(TokenUtils.getFirstLevelHashFromIdentity(emailAddress, firstLevelSalt), tokenRefreshRequest.firstLevelHash.firstLevelHash()); @@ -1941,7 +1942,7 @@ void tokenValidateWithEmailHash_Mismatch(String apiVersion, Vertx vertx, VertxTe void identityMapBothEmailAndHashSpecified(Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; final String emailAddress = "test@uid2.com"; - final String emailHash = TokenUtils.getIdentityHashString(emailAddress); + final String emailHash = TokenUtils.getDiiHashString(emailAddress); fakeAuth(clientSiteId, Role.MAPPER); setupSalts(); setupKeys(); @@ -2029,7 +2030,7 @@ void identityMapForSaltsExpired(Vertx vertx, VertxTestContext testContext) { @Test void identityMapForEmailHash(Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; - final String emailHash = TokenUtils.getIdentityHashString("test@uid2.com"); + final String emailHash = TokenUtils.getDiiHashString("test@uid2.com"); fakeAuth(clientSiteId, Role.MAPPER); setupSalts(); setupKeys(); @@ -2085,7 +2086,7 @@ void identityMapBatchBothEmailAndHashSpecified(String apiVersion, Vertx vertx, V req.put("email_hash", emailHashes); emails.add("test1@uid2.com"); - emailHashes.add(TokenUtils.getIdentityHashString("test2@uid2.com")); + emailHashes.add(TokenUtils.getDiiHashString("test2@uid2.com")); send(apiVersion, vertx, apiVersion + "/identity/map", false, null, req, 400, respJson -> { assertFalse(respJson.containsKey("body")); @@ -2224,8 +2225,8 @@ void identityMapBatchEmailHashes(String apiVersion, Vertx vertx, VertxTestContex JsonArray hashes = new JsonArray(); req.put("email_hash", hashes); final String[] email_hashes = { - TokenUtils.getIdentityHashString("test1@uid2.com"), - TokenUtils.getIdentityHashString("test2@uid2.com"), + TokenUtils.getDiiHashString("test1@uid2.com"), + TokenUtils.getDiiHashString("test2@uid2.com"), }; for (String email_hash : email_hashes) { @@ -2452,7 +2453,7 @@ void LogoutV2SaltsExpired(Vertx vertx, VertxTestContext testContext) { void tokenGenerateBothPhoneAndHashSpecified(String apiVersion, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; final String phone = "+15555555555"; - final String phoneHash = TokenUtils.getIdentityHashString(phone); + final String phoneHash = TokenUtils.getDiiHashString(phone); fakeAuth(clientSiteId, Role.GENERATOR); setupSalts(); setupKeys(); @@ -2498,9 +2499,9 @@ void tokenGenerateBothPhoneAndEmailSpecified(String apiVersion, Vertx vertx, Ver void tokenGenerateBothPhoneHashAndEmailHashSpecified(String apiVersion, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; final String phone = "+15555555555"; - final String phoneHash = TokenUtils.getIdentityHashString(phone); + final String phoneHash = TokenUtils.getDiiHashString(phone); final String emailAddress = "test@uid2.com"; - final String emailHash = TokenUtils.getIdentityHashString(emailAddress); + final String emailHash = TokenUtils.getDiiHashString(emailAddress); fakeAuth(clientSiteId, Role.GENERATOR); setupSalts(); setupKeys(); @@ -2537,11 +2538,11 @@ void tokenGenerateForPhone(String apiVersion, Vertx vertx, VertxTestContext test assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Phone); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, DiiType.Phone); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), DiiType.Phone); assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, - getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), + getRawUidFromIdentity(DiiType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt)); @@ -2567,7 +2568,7 @@ void verifyFirstLevelHashIdentityAndEstablishedAt(byte[] expectedFirstLevelHash, void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; final String phone = "+15555555555"; - final String phoneHash = TokenUtils.getIdentityHashString(phone); + final String phoneHash = TokenUtils.getDiiHashString(phone); fakeAuth(clientSiteId, Role.GENERATOR); setupSalts(); setupKeys(); @@ -2582,11 +2583,11 @@ void tokenGenerateForPhoneHash(String apiVersion, Vertx vertx, VertxTestContext assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Phone); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, DiiType.Phone); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, body.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), DiiType.Phone); assertAdvertisingTokenRefreshTokenRequests(advertisingTokenRequest, tokenRefreshRequest, clientSiteId, - getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), + getRawUidFromIdentity(DiiType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()), PrivacyBits.DEFAULT, body, TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt)); @@ -2612,13 +2613,13 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); AdvertisingTokenRequest firstAdvertisingTokenRequest = validateAndGetToken(encoder, bodyJson, - IdentityType.Phone); + DiiType.Phone); String genRefreshToken = bodyJson.getString("refresh_token"); - TokenRefreshRequest firstTokenRefreshRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), IdentityType.Phone); + TokenRefreshRequest firstTokenRefreshRequest = decodeRefreshToken(encoder, bodyJson.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"), DiiType.Phone); when(this.optOutStore.getLatestEntry(any())).thenReturn(null); - byte[] expectedRawUidIdentity = getRawUidFromIdentity(IdentityType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()); + byte[] expectedRawUidIdentity = getRawUidFromIdentity(DiiType.Phone, phone, firstLevelSalt, rotatingSalt123.getSalt()); byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(phone, firstLevelSalt); assertAdvertisingTokenRefreshTokenRequests(firstAdvertisingTokenRequest, firstTokenRefreshRequest, clientSiteId, @@ -2634,10 +2635,10 @@ void tokenGenerateThenRefreshForPhone(String apiVersion, Vertx vertx, VertxTestC assertNotNull(refreshBody); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, IdentityType.Phone); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, refreshBody, DiiType.Phone); String refreshTokenStringNew = refreshBody.getString(apiVersion.equals("v2") ? "decrypted_refresh_token" : "refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, IdentityType.Phone); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, refreshTokenStringNew, DiiType.Phone); // assert if the ad/refresh tokens from original token/generate is same as the ad/refresh tokens from token/refresh assertAdvertisingTokenRefreshTokenRequests( @@ -2858,7 +2859,7 @@ void tokenRefreshOptOutBeforeLoginForPhone(String apiVersion, Vertx vertx, Vertx void identityMapBothPhoneAndHashSpecified(Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; final String phone = "+15555555555"; - final String phoneHash = TokenUtils.getIdentityHashString(phone); + final String phoneHash = TokenUtils.getDiiHashString(phone); fakeAuth(clientSiteId, Role.MAPPER); setupSalts(); setupKeys(); @@ -2902,7 +2903,7 @@ void identityMapForPhone(Vertx vertx, VertxTestContext testContext) { void identityMapForPhoneHash(Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 201; final String phone = "+15555555555"; - final String phonneHash = TokenUtils.getIdentityHashString(phone); + final String phonneHash = TokenUtils.getDiiHashString(phone); fakeAuth(clientSiteId, Role.MAPPER); setupSalts(); setupKeys(); @@ -2977,7 +2978,7 @@ void identityMapBatchBothPhoneAndHashSpecified(String apiVersion, Vertx vertx, V req.put("phone_hash", phoneHashes); phones.add("+15555555555"); - phoneHashes.add(TokenUtils.getIdentityHashString("+15555555555")); + phoneHashes.add(TokenUtils.getDiiHashString("+15555555555")); send(apiVersion, vertx, apiVersion + "/identity/map", false, null, req, 400, respJson -> { assertFalse(respJson.containsKey("body")); @@ -3019,8 +3020,8 @@ void identityMapBatchPhoneHashes(String apiVersion, Vertx vertx, VertxTestContex JsonArray hashes = new JsonArray(); req.put("phone_hash", hashes); final String[] email_hashes = { - TokenUtils.getIdentityHashString("+15555555555"), - TokenUtils.getIdentityHashString("+15555555556"), + TokenUtils.getDiiHashString("+15555555555"), + TokenUtils.getDiiHashString("+15555555556"), }; for (String email_hash : email_hashes) { @@ -3309,7 +3310,7 @@ void cstgNoIdentityHashProvided(Vertx vertx, VertxTestContext testContext) throw }) void cstgDomainNameCheckFails(String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend(); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); sendCstg(vertx, "v2/token/client-generate", httpOrigin, @@ -3338,7 +3339,7 @@ void cstgDomainNameCheckFails(String httpOrigin, Vertx vertx, VertxTestContext t }) void cstgAppNameCheckFails(String appName, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend(Collections.emptyList(), List.of("com.123.Game.App.android")); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), appName); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), appName); sendCstg(vertx, "v2/token/client-generate", null, @@ -3373,7 +3374,7 @@ void cstgDomainNameCheckFailsAndLogInvalidHttpOrigin(String httpOrigin, Vertx ve this.uidOperatorVerticle.setLastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); setupCstgBackend(); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); sendCstg(vertx, "v2/token/client-generate", httpOrigin, @@ -3404,7 +3405,7 @@ void cstgLogsInvalidAppName(String appName, Vertx vertx, VertxTestContext testCo this.uidOperatorVerticle.setLastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); setupCstgBackend(); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), appName); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), appName); sendCstg(vertx, "v2/token/client-generate", null, @@ -3450,7 +3451,7 @@ void cstgDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) throw requestJson.put("timestamp", timestamp); requestJson.put("subscription_id", subscriptionID); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), null); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), null); sendCstg(vertx, "v2/token/client-generate", null, @@ -3488,7 +3489,7 @@ void cstgDomainNameCheckFailsAndLogSeveralInvalidHttpOrigin(String httpOrigin, V setupCstgBackend(); when(siteProvider.getSite(124)).thenReturn(new Site(124, "test2", true, new HashSet<>())); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); sendCstg(vertx, "v2/token/client-generate", httpOrigin, @@ -3518,7 +3519,7 @@ void cstgDomainNameCheckFailsAndLogSeveralInvalidHttpOrigin(String httpOrigin, V }) void cstgDomainNameCheckPasses(String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk", "cstg2.com", "localhost"); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); sendCstg(vertx, "v2/token/client-generate", httpOrigin, @@ -3532,7 +3533,7 @@ void cstgDomainNameCheckPasses(String httpOrigin, Vertx vertx, VertxTestContext JsonObject refreshBody = respJson.getJsonObject("body"); assertNotNull(refreshBody); var encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - validateAndGetToken(encoder, refreshBody, IdentityType.Email); //to validate token version is correct + validateAndGetToken(encoder, refreshBody, DiiType.Email); //to validate token version is correct testContext.completeNow(); }); } @@ -3545,7 +3546,7 @@ void cstgDomainNameCheckPasses(String httpOrigin, Vertx vertx, VertxTestContext }) void cstgAppNameCheckPasses(String appName, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend(Collections.emptyList(), List.of("com.123.Game.App.android", "123456789")); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), appName); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), appName); sendCstg(vertx, "v2/token/client-generate", null, @@ -3559,7 +3560,7 @@ void cstgAppNameCheckPasses(String appName, Vertx vertx, VertxTestContext testCo JsonObject refreshBody = respJson.getJsonObject("body"); assertNotNull(refreshBody); var encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - validateAndGetToken(encoder, refreshBody, IdentityType.Email); //to validate token version is correct + validateAndGetToken(encoder, refreshBody, DiiType.Email); //to validate token version is correct assertTokenStatusMetrics( clientSideTokenGenerateSiteId, TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, @@ -4026,18 +4027,18 @@ private Tuple.Tuple2 createClientSideTokenGenerateRequest return new Tuple.Tuple2<>(requestJson, secretKey); } - private Tuple.Tuple2 createClientSideTokenGenerateRequest(IdentityType identityType, String rawId, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException { - return createClientSideTokenGenerateRequest(identityType, rawId, timestamp, null); + private Tuple.Tuple2 createClientSideTokenGenerateRequest(DiiType diiType, String rawId, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException { + return createClientSideTokenGenerateRequest(diiType, rawId, timestamp, null); } - private Tuple.Tuple2 createClientSideTokenGenerateRequest(IdentityType identityType, String rawId, long timestamp, String appName) throws NoSuchAlgorithmException, InvalidKeyException { + private Tuple.Tuple2 createClientSideTokenGenerateRequest(DiiType diiType, String rawId, long timestamp, String appName) throws NoSuchAlgorithmException, InvalidKeyException { JsonObject identity = new JsonObject(); - if(identityType == IdentityType.Email) { + if(diiType == DiiType.Email) { identity.put("email_hash", getSha256(rawId)); } - else if(identityType == IdentityType.Phone) { + else if(diiType == DiiType.Phone) { identity.put("phone_hash", getSha256(rawId)); } else { //can't be other types @@ -4058,10 +4059,10 @@ private Tuple.Tuple2 createClientSideTokenGenerateRequest "test@example.com,Email", "+61400000000,Phone" }) - void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + void cstgUserOptsOutAfterTokenGenerate(String id, DiiType diiType, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk"); - final Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli()); + final Tuple.Tuple2 data = createClientSideTokenGenerateRequest(diiType, id, Instant.now().toEpochMilli()); // When we generate the token the user hasn't opted out. when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) @@ -4085,10 +4086,10 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver assertEquals("success", response.getString("status")); final JsonObject genBody = response.getJsonObject("body"); - final AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, identityType); - final TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, decodeV2RefreshToken(response), identityType); + final AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, diiType); + final TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, decodeV2RefreshToken(response), diiType); - assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, diiType, id); // When we refresh the token the user has opted out. when(optOutStore.getLatestEntry(any(FirstLevelHash.class))) @@ -4112,11 +4113,11 @@ void cstgUserOptsOutAfterTokenGenerate(String id, IdentityType identityType, Ver "false,abc@abc.com,Email", "false,+61400000000,Phone", }) - void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id, IdentityType identityType, + void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id, DiiType diiType, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk"); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(identityType, id, Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(diiType, id, Instant.now().toEpochMilli()); if(optOutExpected) { @@ -4149,13 +4150,13 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id decodeV2RefreshToken(respJson); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, identityType); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, genBody, diiType); - TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), identityType); + TokenRefreshRequest tokenRefreshRequest = decodeRefreshToken(encoder, genBody.getString("decrypted_refresh_token"), diiType); - byte[] expectedRawUidIdentity = getRawUidFromIdentity(identityType, id, firstLevelSalt, rotatingSalt123.getSalt()); + byte[] expectedRawUidIdentity = getRawUidFromIdentity(diiType, id, firstLevelSalt, rotatingSalt123.getSalt()); byte[] expectedFirstLevelHashIdentity = TokenUtils.getFirstLevelHashFromIdentity(id, firstLevelSalt); PrivacyBits expectedPrivacyBits = new PrivacyBits(); @@ -4168,7 +4169,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id expectedPrivacyBits, genBody, expectedFirstLevelHashIdentity); - assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, clientSideTokenGenerateSiteId, diiType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(genBody.getLong("refresh_from")), 10); @@ -4189,11 +4190,11 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id EncryptedTokenEncoder encoder2 = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); //make sure the new advertising token from refresh looks right - AdvertisingTokenRequest adTokenFromRefresh = validateAndGetToken(encoder2, refreshBody, identityType); + AdvertisingTokenRequest adTokenFromRefresh = validateAndGetToken(encoder2, refreshBody, diiType); String refreshTokenStringNew = refreshBody.getString("decrypted_refresh_token"); assertNotEquals(genRefreshToken, refreshTokenStringNew); - TokenRefreshRequest refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, identityType); + TokenRefreshRequest refreshTokenAfterRefreshSource = decodeRefreshToken(encoder, refreshTokenStringNew, diiType); assertAdvertisingTokenRefreshTokenRequests(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, @@ -4201,7 +4202,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id expectedPrivacyBits, genBody, expectedFirstLevelHashIdentity); - assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, identityType, id); + assertAreClientSideGeneratedTokens(adTokenFromRefresh, refreshTokenAfterRefreshSource, clientSideTokenGenerateSiteId, diiType, id); assertEqualsClose(Instant.now().plusMillis(identityExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("identity_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshExpiresAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_expires")), 10); assertEqualsClose(Instant.now().plusMillis(refreshIdentityAfter.toMillis()), Instant.ofEpochMilli(refreshBody.getLong("refresh_from")), 10); @@ -4226,7 +4227,7 @@ void cstgSuccessForBothOptedAndNonOptedOutTest(boolean optOutExpected, String id void cstgSaltsExpired(String httpOrigin, Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { when(saltProviderSnapshot.getExpires()).thenReturn(Instant.now().minus(1, ChronoUnit.HOURS)); setupCstgBackend("cstg.co.uk", "cstg2.com", "localhost"); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); sendCstg(vertx, "v2/token/client-generate", httpOrigin, @@ -4240,7 +4241,7 @@ void cstgSaltsExpired(String httpOrigin, Vertx vertx, VertxTestContext testConte JsonObject refreshBody = respJson.getJsonObject("body"); assertNotNull(refreshBody); var encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - validateAndGetToken(encoder, refreshBody, IdentityType.Email); //to validate token version is correct + validateAndGetToken(encoder, refreshBody, DiiType.Email); //to validate token version is correct verify(shutdownHandler, atLeastOnce()).handleSaltRetrievalResponse(true); @@ -4252,7 +4253,7 @@ void cstgSaltsExpired(String httpOrigin, Vertx vertx, VertxTestContext testConte void cstgNoActiveKey(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { setupCstgBackend("cstg.co.uk"); setupKeys(true); - Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(DiiType.Email, "random@unifiedid.com", Instant.now().toEpochMilli()); sendCstg(vertx, "v2/token/client-generate", "http://cstg.co.uk", @@ -4295,20 +4296,20 @@ void cstgInvalidInput(String identityType, String rawUID, Vertx vertx, VertxTest }); } - private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, int siteId, IdentityType identityType, String identity) { + private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, int siteId, DiiType diiType, String identity) { assertAreClientSideGeneratedTokens(advertisingTokenRequest, tokenRefreshRequest, siteId, - identityType, + diiType, identity, false); } - private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, int siteId, IdentityType identityType, String identity, boolean expectedOptOut) { + private void assertAreClientSideGeneratedTokens(AdvertisingTokenRequest advertisingTokenRequest, TokenRefreshRequest tokenRefreshRequest, int siteId, DiiType diiType, String identity, boolean expectedOptOut) { final PrivacyBits advertisingTokenPrivacyBits = advertisingTokenRequest.privacyBits; final PrivacyBits refreshTokenPrivacyBits = tokenRefreshRequest.privacyBits; - final byte[] rawUid = getRawUidFromIdentity(identityType, + final byte[] rawUid = getRawUidFromIdentity(diiType, identity, firstLevelSalt, rotatingSalt123.getSalt()); @@ -4500,7 +4501,7 @@ void getActiveKeyTest() { @ValueSource(strings = {"MultiKeysets", "AddKey", "RotateKey", "DisableActiveKey", "DisableDefaultKeyset"}) void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTestContext testContext) { final int clientSiteId = 101; - final String emailHash = TokenUtils.getIdentityHashString("test@uid2.com"); + final String emailHash = TokenUtils.getDiiHashString("test@uid2.com"); fakeAuth(clientSiteId, Role.GENERATOR); MultipleKeysetsTests test = new MultipleKeysetsTests(); //To read these tests, open the MultipleKeysetsTests() constructor in another window so you can see the keyset contents and validate expectations @@ -4556,7 +4557,7 @@ void tokenGenerateRotatingKeysets_GENERATOR(String testRun, Vertx vertx, VertxTe assertNotNull(body); EncryptedTokenEncoder encoder = new EncryptedTokenEncoder(new KeyManager(keysetKeyStore, keysetProvider)); - AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, IdentityType.Email); + AdvertisingTokenRequest advertisingTokenRequest = validateAndGetToken(encoder, body, DiiType.Email); assertEquals(clientSiteId, advertisingTokenRequest.sourcePublisher.siteId); //Uses a key from default keyset int clientKeyId; diff --git a/src/test/java/com/uid2/operator/V2RequestUtilTest.java b/src/test/java/com/uid2/operator/V2RequestUtilTest.java index f296411e0..ee42d6a21 100644 --- a/src/test/java/com/uid2/operator/V2RequestUtilTest.java +++ b/src/test/java/com/uid2/operator/V2RequestUtilTest.java @@ -3,7 +3,7 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; -import com.uid2.operator.model.IdentityScope; +import com.uid2.operator.model.identities.IdentityScope; import com.uid2.operator.model.KeyManager; import com.uid2.operator.service.V2RequestUtil; import com.uid2.shared.IClock; diff --git a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java index 6ab2447e7..b11c97f09 100644 --- a/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java +++ b/src/test/java/com/uid2/operator/benchmark/BenchmarkCommon.java @@ -3,8 +3,10 @@ import com.uid2.operator.Const; import com.uid2.operator.Main; import com.uid2.operator.model.*; +import com.uid2.operator.model.identities.DiiType; import com.uid2.operator.model.identities.FirstLevelHash; import com.uid2.operator.model.identities.HashedDii; +import com.uid2.operator.model.identities.IdentityScope; import com.uid2.operator.service.EncryptedTokenEncoder; import com.uid2.operator.service.IUIDOperatorService; import com.uid2.operator.service.UIDOperatorService; @@ -155,7 +157,7 @@ static HashedDii[] createHashedDiiIdentities() { for (int i = 0; i < 65536; i++) { final byte[] diiHash = new byte[33]; new Random().nextBytes(diiHash); - arr[i] = new HashedDii(IdentityScope.UID2, IdentityType.Email, diiHash); + arr[i] = new HashedDii(IdentityScope.UID2, DiiType.Email, diiHash); } return arr; }