Skip to content
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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ And then add the artifact `incognia-api-client` **or** `incognia-api-client-shad
<dependency>
<groupId>com.incognia</groupId>
<artifactId>incognia-api-client</artifactId>
<version>3.15.1</version>
<version>3.16.0</version>
</dependency>
```
```xml
<dependency>
<groupId>com.incognia</groupId>
<artifactId>incognia-api-client-shaded</artifactId>
<version>3.15.1</version>
<version>3.16.0</version>
</dependency>
```

Expand All @@ -47,13 +47,13 @@ repositories {
And then add the dependency
```gradle
dependencies {
implementation 'com.incognia:incognia-api-client:3.15.1'
implementation 'com.incognia:incognia-api-client:3.16.0'
}
```
OR
```gradle
dependencies {
implementation 'com.incognia:incognia-api-client-shaded:3.15.1'
implementation 'com.incognia:incognia-api-client-shaded:3.16.0'
}
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group = "com.incognia"
version = "3.15.1"
version = "3.16.0"

task createProjectVersionFile {
def projectVersionDir = "$projectDir/src/main/java/com/incognia/api"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import com.incognia.common.exceptions.IncogniaException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import okhttp3.OkHttpClient;

public class TokenAwareNetworkingClient {
private static final String USER_AGENT_HEADER = "User-Agent";
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String LATENCY_HEADER = "X-Incognia-Latency";
private static final String USER_AGENT_HEADER_CONTENT =
String.format(
"incognia-api-java/%s (%s %s %s) Java/%s",
Expand All @@ -19,49 +22,48 @@ public class TokenAwareNetworkingClient {

private final NetworkingClient networkingClient;
private final TokenProvider tokenProvider;
private final AtomicReference<Long> lastLatency = new AtomicReference<>();

public TokenAwareNetworkingClient(
OkHttpClient httpClient, String baseUrl, String clientId, String clientSecret) {
this.networkingClient = new NetworkingClient(httpClient, baseUrl);
this.tokenProvider = new TokenProvider(clientId, clientSecret, networkingClient);
}

private Map<String, String> buildHeaders() throws IncogniaException {
Map<String, String> headers = new HashMap<>();
headers.put(USER_AGENT_HEADER, USER_AGENT_HEADER_CONTENT);
headers.put(AUTHORIZATION_HEADER, tokenProvider.buildAuthorizationHeader());
Long latency = lastLatency.get();
if (latency != null) {
headers.put(LATENCY_HEADER, Long.toString(latency));
}
return headers;
}

public <T, U> U doPost(
String path, T body, Class<U> responseType, Map<String, String> queryParameters)
throws IncogniaException {
tokenProvider.getToken();
Map<String, String> headers =
new HashMap<String, String>() {
{
put(USER_AGENT_HEADER, USER_AGENT_HEADER_CONTENT);
put(AUTHORIZATION_HEADER, tokenProvider.buildAuthorizationHeader());
}
};
return networkingClient.doPost(path, body, responseType, headers, queryParameters);
long start = System.nanoTime();
U result = networkingClient.doPost(path, body, responseType, buildHeaders(), queryParameters);
lastLatency.set(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
return result;
}

public <T, U> U doPost(String path, T body, Class<U> responseType) throws IncogniaException {
tokenProvider.getToken();
Map<String, String> headers =
new HashMap<String, String>() {
{
put(USER_AGENT_HEADER, USER_AGENT_HEADER_CONTENT);
put(AUTHORIZATION_HEADER, tokenProvider.buildAuthorizationHeader());
}
};
return networkingClient.doPost(path, body, responseType, headers);
long start = System.nanoTime();
U result = networkingClient.doPost(path, body, responseType, buildHeaders());
lastLatency.set(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
return result;
}

public <T> void doPost(String path, T body, Map<String, String> queryParameters)
throws IncogniaException {
tokenProvider.getToken();
Map<String, String> headers =
new HashMap<String, String>() {
{
put(USER_AGENT_HEADER, USER_AGENT_HEADER_CONTENT);
put(AUTHORIZATION_HEADER, tokenProvider.buildAuthorizationHeader());
}
};
networkingClient.doPost(path, body, headers, queryParameters);
long start = System.nanoTime();
networkingClient.doPost(path, body, buildHeaders(), queryParameters);
lastLatency.set(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
}
}
95 changes: 95 additions & 0 deletions src/test/java/com/incognia/api/IncogniaAPITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@
import lombok.SneakyThrows;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -1106,6 +1108,99 @@ void testRegisterLogin_whenAccountIdIsNotValid() {
.hasMessage("'account id' cannot be empty");
}

private static final String TOKEN_RESPONSE =
"{\"access_token\": \"test-token\", \"expires_in\": 300, \"token_type\": \"Bearer\"}";
private static final String SIGNUP_RESPONSE =
"{\"id\": \"5e76a7ca-577c-4f47-a752-9e1e0cee9e49\","
+ "\"request_id\": \"8afc84a7-f1d4-488d-bd69-36d9a37168b7\","
+ "\"risk_assessment\": \"low_risk\"}";
private static final String TRANSACTION_RESPONSE =
"{\"id\": \"dfe1f2ff-8f0d-4ce8-aed1-af8435143044\"," + "\"risk_assessment\": \"low_risk\"}";

@Test
@SneakyThrows
void testLbmt_absentOnFirstCall() {
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(TOKEN_RESPONSE));
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(SIGNUP_RESPONSE));

client.registerSignup(RegisterSignupRequest.builder().installationId("test").build());

mockServer.takeRequest(); // token request
RecordedRequest signupRequest = mockServer.takeRequest();
assertThat(signupRequest.getHeader("X-Incognia-Latency")).isNull();
}

@Test
@SneakyThrows
void testLbmt_sentOnSecondSignupCall() {
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(TOKEN_RESPONSE));
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(SIGNUP_RESPONSE));
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(SIGNUP_RESPONSE));

RegisterSignupRequest request = RegisterSignupRequest.builder().installationId("test").build();
client.registerSignup(request);
client.registerSignup(request);

mockServer.takeRequest(); // token request
RecordedRequest firstRequest = mockServer.takeRequest();
RecordedRequest secondRequest = mockServer.takeRequest();

assertThat(firstRequest.getHeader("X-Incognia-Latency")).isNull();
String latencyHeader = secondRequest.getHeader("X-Incognia-Latency");
assertThat(latencyHeader).isNotNull();
assertThat(Long.parseLong(latencyHeader)).isGreaterThanOrEqualTo(0L);
}

@Test
@SneakyThrows
void testLbmt_sentOnFeedbackAfterTransaction() {
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(TOKEN_RESPONSE));
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(TRANSACTION_RESPONSE));
mockServer.enqueue(new MockResponse().setResponseCode(200));

client.registerPayment(
RegisterPaymentRequest.builder()
.accountId("account-id")
.addresses(Collections.emptyMap())
.build());
client.registerFeedback(
FeedbackEvent.ACCOUNT_TAKEOVER,
Instant.now(),
FeedbackIdentifiers.builder().accountId("account-id").build());

mockServer.takeRequest(); // token request
RecordedRequest transactionRequest = mockServer.takeRequest();
RecordedRequest feedbackRequest = mockServer.takeRequest();

assertThat(transactionRequest.getHeader("X-Incognia-Latency")).isNull();
String latencyHeader = feedbackRequest.getHeader("X-Incognia-Latency");
assertThat(latencyHeader).isNotNull();
assertThat(Long.parseLong(latencyHeader)).isGreaterThanOrEqualTo(0L);
}

@Test
@SneakyThrows
void testLbmt_sentOnSignupAfterFeedback() {
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(TOKEN_RESPONSE));
mockServer.enqueue(new MockResponse().setResponseCode(200));
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody(SIGNUP_RESPONSE));

client.registerFeedback(
FeedbackEvent.ACCOUNT_TAKEOVER,
Instant.now(),
FeedbackIdentifiers.builder().accountId("account-id").build());
client.registerSignup(RegisterSignupRequest.builder().installationId("test").build());

mockServer.takeRequest(); // token request
RecordedRequest feedbackRequest = mockServer.takeRequest();
RecordedRequest signupRequest = mockServer.takeRequest();

assertThat(feedbackRequest.getHeader("X-Incognia-Latency")).isNull();
String latencyHeader = signupRequest.getHeader("X-Incognia-Latency");
assertThat(latencyHeader).isNotNull();
assertThat(Long.parseLong(latencyHeader)).isGreaterThanOrEqualTo(0L);
}

private void assertTransactionAssessment(TransactionAssessment transactionAssessment) {
assertThat(transactionAssessment)
.extracting("id", "riskAssessment", "deviceId")
Expand Down
Loading