Skip to content

Refactor Token Generation Logic to improve readability #1081

New issue

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

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

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/main/java/com/uid2/operator/model/IdentityResponse.java
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -52,4 +53,25 @@ public Instant getRefreshFrom() {
public boolean isOptedOut() {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
);
}

Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/uid2/operator/service/InputUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ public HashedDiiIdentity toHashedDiiIdentity(IdentityScope identityScope, int pr
this.identityType,
getIdentityInput(),
privacyBits,
establishedAt,
establishedAt);
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/uid2/operator/service/UIDOperatorService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -58,7 +58,7 @@ public class UIDOperatorService implements IUIDOperatorService {

private final Handler<Boolean> 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<Boolean> saltRetrievalResponseHandler) {
this.saltProvider = saltProvider;
this.encoder = encoder;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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),
Expand Down
37 changes: 9 additions & 28 deletions src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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);
Expand All @@ -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()) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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());
Expand Down
Loading