Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add logging to get information about refresh token version #602

Merged
merged 6 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
import com.uid2.shared.model.KeysetKey;
import com.uid2.shared.model.TokenVersion;
import io.vertx.core.buffer.Buffer;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;

import java.time.Instant;
import java.util.Base64;

public class EncryptedTokenEncoder implements ITokenEncoder {

private final KeyManager keyManager;

public EncryptedTokenEncoder(KeyManager keyManager) {
Expand Down Expand Up @@ -259,13 +260,23 @@ public AdvertisingToken decodeAdvertisingTokenV3orV4(Buffer b, byte[] bytes, Tok
);
}

private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVersion) {
Counter.builder("uid2_refresh_token_served_count")
.description(String.format("Counter for the amount of refresh token %s served", tokenVersion.toString().toLowerCase()))
.tags("site_id", String.valueOf(siteId))
.tags("refresh_token_version", tokenVersion.toString().toLowerCase())
.register(Metrics.globalRegistry).increment();
}

public byte[] encode(RefreshToken t, Instant asOf) {
final KeysetKey serviceKey = this.keyManager.getRefreshKey(asOf);

switch (t.version) {
case V2:
recordRefreshTokenVersionCount(String.valueOf(t.publisherIdentity.siteId), TokenVersion.V2);
return encodeV2(t, serviceKey);
case V3:
recordRefreshTokenVersionCount(String.valueOf(t.publisherIdentity.siteId), TokenVersion.V3);
return encodeV3(t, serviceKey);
default:
throw new ClientInputValidationException("RefreshToken version " + t.version + " not supported");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.uid2.operator.model.*;
import com.uid2.operator.util.PrivacyBits;
import com.uid2.operator.vertx.OperatorShutdownHandler;
import com.uid2.shared.model.SaltEntry;
import com.uid2.operator.store.IOptOutStore;
import com.uid2.shared.store.ISaltProvider;
Expand Down
25 changes: 23 additions & 2 deletions src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ public class UIDOperatorVerticle extends AbstractVerticle {
public final static int MASTER_KEYSET_ID_FOR_SDKS = 9999999; //this is because SDKs have an issue where they assume keyset ids are always positive; that will be fixed.
public final static long OPT_OUT_CHECK_CUTOFF_DATE = Instant.parse("2023-09-01T00:00:00.00Z").getEpochSecond();
private final Handler<Boolean> saltRetrievalResponseHandler;

private final int maxBidstreamLifetimeSeconds;
private final int allowClockSkewSeconds;
protected int maxSharingLifetimeSeconds;
Expand Down Expand Up @@ -1778,13 +1777,34 @@ private void recordOptOutStatusEndpointStats(RoutingContext rc, int inputCount,
optOutDistSummary.record(optOutCount);
}

public TokenVersion getRefreshTokenVersion(String s) {
if (s != null && !s.isEmpty()) {
final byte[] bytes = EncodingUtils.fromBase64(s);
final Buffer b = Buffer.buffer(bytes);
if (b.getByte(1) == TokenVersion.V3.rawVersion) {
return TokenVersion.V3;
} else if (b.getByte(0) == TokenVersion.V2.rawVersion) {
return TokenVersion.V2;
}
}
return null;
}

private void recordRefreshTokenVersionCount(String siteId, TokenVersion tokenVersion) {
Counter.builder("uid2_refresh_token_received_count")
.description(String.format("Counter for the amount of refresh token %s received", tokenVersion.toString().toLowerCase()))
.tags("site_id", siteId)
.tags("refresh_token_version", tokenVersion.toString().toLowerCase())
.register(Metrics.globalRegistry).increment();

}

private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) {
final RefreshToken refreshToken;
try {
if (AuthMiddleware.isAuthenticated(rc)) {
rc.put(Const.RoutingContextData.SiteId, AuthMiddleware.getAuthClient(ClientKey.class, rc).getSiteId());
}

refreshToken = this.encoder.decodeRefreshToken(tokenStr);
} catch (ClientInputValidationException cie) {
return RefreshResponse.Invalid;
Expand All @@ -1795,6 +1815,7 @@ private RefreshResponse refreshIdentity(RoutingContext rc, String tokenStr) {
if (!AuthMiddleware.isAuthenticated(rc)) {
rc.put(Const.RoutingContextData.SiteId, refreshToken.publisherIdentity.siteId);
}
recordRefreshTokenVersionCount(String.valueOf(rc.data().get(Const.RoutingContextData.SiteId)), this.getRefreshTokenVersion(tokenStr));

return this.idService.refreshIdentity(refreshToken);
}
Expand Down
9 changes: 6 additions & 3 deletions src/test/java/com/uid2/operator/TokenEncodingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@
import com.uid2.shared.store.reader.RotatingKeysetKeyStore;
import com.uid2.shared.store.reader.RotatingKeysetProvider;
import com.uid2.shared.store.scope.GlobalScope;
import io.micrometer.core.instrument.Metrics;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import org.junit.Assert;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.ValueSource;

import java.time.Instant;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.*;

public class TokenEncodingTest {

Expand Down Expand Up @@ -80,6 +79,10 @@ public void testRefreshTokenEncoding(TokenVersion tokenVersion) {
Buffer b = Buffer.buffer(encodedBytes);
int keyId = b.getInt(tokenVersion == TokenVersion.V2 ? 25 : 2);
assertEquals(Data.RefreshKeySiteId, keyManager.getSiteIdFromKeyId(keyId));

assertNotNull(Metrics.globalRegistry
.get("uid2_refresh_token_served_count")
.counter());
}

@ParameterizedTest
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,8 @@ void tokenRefreshExpiredTokenAuthenticated(String apiVersion, Vertx vertx, Vertx

sendTokenRefresh(apiVersion, vertx, testContext, refreshToken, bodyJson.getString("refresh_response_key"), 400, refreshRespJson -> {
assertEquals("expired_token", refreshRespJson.getString("status"));
assertNotNull(Metrics.globalRegistry
.get("uid2_refresh_token_received_count").counter());
testContext.completeNow();
});
});
Expand All @@ -1763,6 +1765,8 @@ void tokenRefreshExpiredTokenUnauthenticated(String apiVersion, Vertx vertx, Ver

sendTokenRefresh(apiVersion, vertx, testContext, refreshToken, "", 400, refreshRespJson -> {
assertEquals("error", refreshRespJson.getString("status"));
assertNotNull(Metrics.globalRegistry
.get("uid2_refresh_token_received_count").counter());
testContext.completeNow();
});
});
Expand Down