diff --git a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java index 09af68a94..bd6f10edf 100644 --- a/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java +++ b/src/main/java/com/uid2/operator/monitoring/TokenResponseStatsCollector.java @@ -38,7 +38,8 @@ public enum ResponseStatus { PayloadHasNoBody, /* End of CSTG-related Status */ Unknown, - NoActiveKey + NoActiveKey, + Unauthorized } public static void record(ISiteStore siteStore, Integer siteId, Endpoint endpoint, TokenVersion advertisingTokenVersion, ResponseStatus responseStatus) { diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index 8f2e20012..59c46bae6 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -337,6 +337,12 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA return; } + if(clientSideKeypair.isDisabled()) { + SendClientErrorResponseAndRecordStats(ResponseStatus.Unauthorized, 401, rc, "Unauthorized", + clientSideKeypair.getSiteId(), TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, TokenResponseStatsCollector.ResponseStatus.Unauthorized, siteProvider); + return; + } + if (!hasValidOriginOrAppName(rc, request, clientSideKeypair)) { return; } diff --git a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java index 1a57827d8..33d8339fb 100644 --- a/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java +++ b/src/test/java/com/uid2/operator/UIDOperatorVerticleTest.java @@ -42,7 +42,6 @@ import io.vertx.ext.web.client.WebClient; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; -import org.apache.commons.collections4.CollectionUtils; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -3094,6 +3093,51 @@ void cstgLogsInvalidAppName(String appName, Vertx vertx, VertxTestContext testCo }); } + @Test + void cstgDisabledAsUnauthorized(Vertx vertx, VertxTestContext testContext) throws NoSuchAlgorithmException, InvalidKeyException { + ListAppender logWatcher = new ListAppender<>(); + logWatcher.start(); + ((Logger) LoggerFactory.getLogger(UIDOperatorVerticle.class)).addAppender(logWatcher); + this.uidOperatorVerticle.setLastInvalidOriginProcessTime(Instant.now().minusSeconds(3600)); + + setupCstgBackend(); + String subscriptionID = "PpRrE5YY84"; + ClientSideKeypair keypairDisabled = new ClientSideKeypair(subscriptionID, clientSideTokenGeneratePublicKey, clientSideTokenGeneratePrivateKey, clientSideTokenGenerateSiteId, "", Instant.now(), true, ""); + when(clientSideKeypairProvider.getSnapshot()).thenReturn(clientSideKeypairSnapshot); + when(clientSideKeypairSnapshot.getKeypair(subscriptionID)).thenReturn(keypairDisabled); + + final KeyFactory kf = KeyFactory.getInstance("EC"); + final PublicKey serverPublicKey = ClientSideTokenGenerateTestUtil.stringToPublicKey(clientSideTokenGeneratePublicKey, kf); + final PrivateKey clientPrivateKey = ClientSideTokenGenerateTestUtil.stringToPrivateKey("MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDsqxZicsGytVqN2HZqNDHtV422Lxio8m1vlflq4Jb47Q==", kf); + final SecretKey secretKey = ClientSideTokenGenerateTestUtil.deriveKey(serverPublicKey, clientPrivateKey); + final long timestamp = Instant.now().toEpochMilli(); + + + JsonObject requestJson = new JsonObject(); + requestJson.put("payload", ""); + requestJson.put("iv", ""); + requestJson.put("public_key", serverPublicKey.toString()); + requestJson.put("timestamp", timestamp); + requestJson.put("subscription_id", subscriptionID); + + Tuple.Tuple2 data = createClientSideTokenGenerateRequest(IdentityType.Email, "random@unifiedid.com", Instant.now().toEpochMilli(), false, null); + sendCstg(vertx, + "v2/token/client-generate", + null, + requestJson, + secretKey, + 401, + testContext, + respJson -> { + assertEquals("Unauthorized", respJson.getString("message")); + assertTokenStatusMetrics( + clientSideTokenGenerateSiteId, + TokenResponseStatsCollector.Endpoint.ClientSideTokenGenerateV2, + TokenResponseStatsCollector.ResponseStatus.Unauthorized); + testContext.completeNow(); + }); + } + @ParameterizedTest @CsvSource({ "true,http://gototest.com",