Skip to content
Open
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.uid2</groupId>
<artifactId>uid2-e2e</artifactId>
<version>4.2.17</version>
<version>4.2.18-alpha-96-SNAPSHOT</version>

<properties>
<maven.compiler.source>21</maven.compiler.source>
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/app/component/Core.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public JsonNode attest(String attestationRequest) throws Exception {
return OBJECT_MAPPER.readTree(response);
}

public JsonNode attestWithApiKey(String attestationRequest, String apiKey) throws Exception {
String response = HttpClient.post(getBaseUrl() + "/attest", attestationRequest, apiKey);
return OBJECT_MAPPER.readTree(response);
}

public JsonNode getWithCoreApiToken(String path) throws Exception {
return getWithCoreApiToken(path, false);
}
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/common/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public JsonNode getResponseJson() throws Exception {
return OBJECT_MAPPER.readTree(response);
}

public int getCode() {
return code;
}

private static String createErrorMessage(HttpMethod method, String url, int code, String message, String response) {
return "Unsuccessful %s request - URL: %s - Code: %d %s - Response body: %s".formatted(
method, url, code, message, response
Expand Down
54 changes: 53 additions & 1 deletion src/test/java/suite/core/CoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,61 @@ public void testAttest_EmptyAttestationRequest(Core core) {
assertEquals("Unsuccessful POST request - URL: " + coreUrl + "/attest - Code: 400 Bad Request - Response body: {\"status\":\"no attestation_request attached\"}", exception.getMessage());
}

/**
* Tests that an unknown / mistyped operator key is rejected with HTTP 401 and a body that
* names the cause (reason=unrecognized_key).
*/
@ParameterizedTest(name = "/attest unrecognized key - {0}")
@MethodSource({
"suite.core.TestData#baseArgs"
})
public void testAttest_UnrecognizedOperatorKey(Core core) {
// A well-formed but unknown key - not present in the operators store.
String bogusOperatorKey = "UID2-O-L-000-thisKeyDoesNotExist000000000000000000000000=";

HttpClient.HttpException exception = assertThrows(
HttpClient.HttpException.class,
() -> core.attestWithApiKey("{\"attestation_request\":\"AA==\"}", bogusOperatorKey)
);

assertEquals(401, exception.getCode(), "unknown operator key should be rejected with 401");
JsonNode body = assertDoesNotThrow(exception::getResponseJson);
assertAll("401 body should name the rejection cause",
() -> assertEquals("unauthorized", body.get("status").asText()),
() -> assertEquals("unrecognized_key", body.get("reason").asText()),
() -> assertTrue(body.get("message").asText().toLowerCase().contains("not recognized"),
"message should tell the operator the key was not recognized"));
}

/**
* Tests that a recognized-but-disabled operator key is rejected with HTTP 401 and reason=key_disabled,
* distinguishing it from an unknown key. Relies on the disabled operator key seeded in
* uid2-admin localstack (site_id 998, "Disabled Operator (E2E)").
*/
@ParameterizedTest(name = "/attest disabled key - {0}")
@MethodSource({
"suite.core.TestData#baseArgs"
})
public void testAttest_DisabledOperatorKey(Core core) {
String disabledOperatorKey = "UID2-O-L-998-d1sabledKeyForE2ETestOnly00000000000000000000=";

HttpClient.HttpException exception = assertThrows(
HttpClient.HttpException.class,
() -> core.attestWithApiKey("{\"attestation_request\":\"AA==\"}", disabledOperatorKey)
);

assertEquals(401, exception.getCode(), "disabled operator key should be rejected with 401");
JsonNode body = assertDoesNotThrow(exception::getResponseJson);
assertAll("401 body should identify the key as disabled",
() -> assertEquals("unauthorized", body.get("status").asText()),
() -> assertEquals("key_disabled", body.get("reason").asText()),
() -> assertTrue(body.get("message").asText().toLowerCase().contains("disabled"),
"message should tell the operator the key is disabled"));
}

/**
* Tests valid attestation request with JWT signing.
*
*
* Since LocalStack generates its own RSA key material,
* we dynamically fetch the public key from LocalStack's
* KMS using GetPublicKey API to validate JWT signatures.
Expand Down