Skip to content

Commit 234f730

Browse files
committed
SDK-2478: Allow the Relying Business to retrieve tracked devices for a session
1 parent 6649c24 commit 234f730

File tree

9 files changed

+270
-0
lines changed

9 files changed

+270
-0
lines changed

yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanClient.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.io.IOException;
77
import java.security.KeyPair;
88
import java.security.Security;
9+
import java.util.List;
910

1011
import com.yoti.api.client.InitialisationException;
1112
import com.yoti.api.client.KeyPairSource;
@@ -14,6 +15,7 @@
1415
import com.yoti.api.client.docs.session.create.SessionSpec;
1516
import com.yoti.api.client.docs.session.create.facecapture.CreateFaceCaptureResourcePayload;
1617
import com.yoti.api.client.docs.session.create.facecapture.UploadFaceCaptureImagePayload;
18+
import com.yoti.api.client.docs.session.devicemetadata.MetadataResponse;
1719
import com.yoti.api.client.docs.session.instructions.Instructions;
1820
import com.yoti.api.client.docs.session.retrieve.CreateFaceCaptureResourceResponse;
1921
import com.yoti.api.client.docs.session.retrieve.GetSessionResult;
@@ -242,6 +244,19 @@ public SessionConfigurationResponse getSessionConfiguration(String sessionId) th
242244
return docScanService.fetchSessionConfiguration(sdkId, keyPair, sessionId);
243245
}
244246

247+
/**
248+
* Fetches the tracked devices used by the end user, to interact with the given sessionID.
249+
*
250+
* @param sessionId the session ID
251+
*
252+
* @return the session configuration
253+
* @throws DocScanException if an error has occurred
254+
*/
255+
public List<MetadataResponse> getTrackedDevices(String sessionId) throws DocScanException {
256+
LOG.debug("Fetching tracked devices for session '{}'", sessionId);
257+
return docScanService.getTrackedDevices(sdkId, keyPair, sessionId);
258+
}
259+
245260
private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException {
246261
try {
247262
LOG.debug("Loading key pair from '{}'", kpSource);

yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.yoti.api.client.docs.session.create.SessionSpec;
2525
import com.yoti.api.client.docs.session.create.facecapture.CreateFaceCaptureResourcePayload;
2626
import com.yoti.api.client.docs.session.create.facecapture.UploadFaceCaptureImagePayload;
27+
import com.yoti.api.client.docs.session.devicemetadata.MetadataResponse;
2728
import com.yoti.api.client.docs.session.instructions.Instructions;
2829
import com.yoti.api.client.docs.session.retrieve.CreateFaceCaptureResourceResponse;
2930
import com.yoti.api.client.docs.session.retrieve.GetSessionResult;
@@ -39,6 +40,7 @@
3940
import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory;
4041

4142
import com.fasterxml.jackson.annotation.JsonInclude;
43+
import com.fasterxml.jackson.core.type.TypeReference;
4244
import com.fasterxml.jackson.databind.ObjectMapper;
4345
import com.fasterxml.jackson.databind.SerializationFeature;
4446
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@@ -52,6 +54,9 @@
5254
final class DocScanService {
5355

5456
private static final Logger LOG = LoggerFactory.getLogger(DocScanService.class);
57+
58+
private static final TypeReference<List<MetadataResponse>> METADATA_RESPONSE_TYPE_REF = new TypeReference<List<MetadataResponse>>() {};
59+
5560
private static final int HTTP_STATUS_NO_CONTENT = 204;
5661
private static final String YOTI_MULTIPART_BOUNDARY = "yoti-doc-scan-boundary";
5762

@@ -527,6 +532,30 @@ public void triggerIbvEmailNotification(String sdkId, KeyPair keyPair, String se
527532
}
528533
}
529534

535+
public List<MetadataResponse> getTrackedDevices(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException {
536+
notNullOrEmpty(sdkId, "SDK ID");
537+
notNull(keyPair, "Application key Pair");
538+
notNullOrEmpty(sessionId, "sessionId");
539+
540+
String path = unsignedPathFactory.createFetchTrackedDevices(sdkId, sessionId);
541+
LOG.info("Fetching tracked devices at '{}'", path);
542+
543+
try {
544+
SignedRequest signedRequest = signedRequestBuilderFactory.create()
545+
.withKeyPair(keyPair)
546+
.withBaseUrl(apiUrl)
547+
.withEndpoint(path)
548+
.withHttpMethod(HTTP_GET)
549+
.build();
550+
551+
return signedRequest.execute(METADATA_RESPONSE_TYPE_REF);
552+
} catch (GeneralSecurityException | ResourceException ex) {
553+
throw new DocScanException("Error executing the GET: " + ex.getMessage(), ex);
554+
} catch (IOException | URISyntaxException ex) {
555+
throw new DocScanException("Error building the request: " + ex.getMessage(), ex);
556+
}
557+
}
558+
530559
private String findContentType(SignedRequestResponse response) {
531560
List<String> contentTypeValues = null;
532561
for (Map.Entry<String, List<String>> entry : response.getResponseHeaders().entrySet()) {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.yoti.api.client.docs.session.devicemetadata;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class DeviceResponse {
6+
7+
@JsonProperty("ip_address")
8+
private String ipAddress;
9+
10+
@JsonProperty("ip_iso_country_code")
11+
private String ipIsoCountryCode;
12+
13+
@JsonProperty("manufacture_name")
14+
private String manufactureName;
15+
16+
@JsonProperty("model_name")
17+
private String modelName;
18+
19+
@JsonProperty("os_name")
20+
private String osName;
21+
22+
@JsonProperty("os_version")
23+
private String osVersion;
24+
25+
@JsonProperty("browser_name")
26+
private String browserName;
27+
28+
@JsonProperty("browser_version")
29+
private String browserVersion;
30+
31+
@JsonProperty("locale")
32+
private String locale;
33+
34+
@JsonProperty("client_version")
35+
private String clientVersion;
36+
37+
public String getIpAddress() {
38+
return ipAddress;
39+
}
40+
41+
public String getIpIsoCountryCode() {
42+
return ipIsoCountryCode;
43+
}
44+
45+
public String getManufactureName() {
46+
return manufactureName;
47+
}
48+
49+
public String getModelName() {
50+
return modelName;
51+
}
52+
53+
public String getOsName() {
54+
return osName;
55+
}
56+
57+
public String getOsVersion() {
58+
return osVersion;
59+
}
60+
61+
public String getBrowserName() {
62+
return browserName;
63+
}
64+
65+
public String getBrowserVersion() {
66+
return browserVersion;
67+
}
68+
69+
public String getLocale() {
70+
return locale;
71+
}
72+
73+
public String getClientVersion() {
74+
return clientVersion;
75+
}
76+
77+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.yoti.api.client.docs.session.devicemetadata;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class MetadataResponse {
6+
7+
@JsonProperty("event")
8+
private String event;
9+
10+
@JsonProperty("created")
11+
private String created;
12+
13+
@JsonProperty("device")
14+
private DeviceResponse device;
15+
16+
public String getEvent() {
17+
return event;
18+
}
19+
20+
public String getCreated() {
21+
return created;
22+
}
23+
24+
public DeviceResponse getDevice() {
25+
return device;
26+
}
27+
28+
}

yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcher.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.yoti.api.client.docs.session.retrieve.configuration.capture.liveness.RequiredLivenessResourceResponse;
66

7+
import com.fasterxml.jackson.core.type.TypeReference;
78
import com.fasterxml.jackson.databind.DeserializationFeature;
89
import com.fasterxml.jackson.databind.ObjectMapper;
910
import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -40,4 +41,9 @@ public <T> T doRequest(SignedRequest signedRequest, Class<T> resourceClass) thro
4041
return objectMapper.readValue(signedRequestResponse.getResponseBody(), resourceClass);
4142
}
4243

44+
public <T> T doRequest(SignedRequest signedRequest, TypeReference<T> resourceClass) throws ResourceException, IOException {
45+
SignedRequestResponse signedRequestResponse = rawResourceFetcher.doRequest(signedRequest);
46+
return objectMapper.readValue(signedRequestResponse.getResponseBody(), resourceClass);
47+
}
48+
4349
}

yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.yoti.api.client.Image;
88

9+
import com.fasterxml.jackson.core.type.TypeReference;
10+
911
public class SignedRequest {
1012

1113
private final URI uri;
@@ -56,6 +58,10 @@ public <T> T execute(Class<T> clazz) throws ResourceException, IOException {
5658
return jsonResourceFetcher.doRequest(this, clazz);
5759
}
5860

61+
public <T> T execute(TypeReference<T> typeReference) throws ResourceException, IOException {
62+
return jsonResourceFetcher.doRequest(this, typeReference);
63+
}
64+
5965
public SignedRequestResponse execute() throws ResourceException, IOException {
6066
return rawResourceFetcher.doRequest(this);
6167
}

yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class UnsignedPathFactory {
3232
private static final String DOCS_NEW_FACE_CAPTURE_RESOURCE = "/sessions/%s/resources/face-capture?sdkId=%s";
3333
private static final String DOCS_UPLOAD_FACE_CAPTURE_IMAGE = "/sessions/%s/resources/face-capture/%s/image?sdkId=%s";
3434
private static final String DOCS_TRIGGER_IBV_NOTIFICATION = "/sessions/%s/instructions/email?sdkId=%s";
35+
private static final String DOCS_FETCH_TRACKED_DEVICES = "/sessions/%s/tracked-devices?sdkId=%s";
3536

3637
public String createAmlPath(String appId) {
3738
return format(AML, appId);
@@ -121,4 +122,8 @@ public String createTriggerIbvEmailNotificationPath(String sdkId, String session
121122
return format(DOCS_TRIGGER_IBV_NOTIFICATION, sessionId, sdkId);
122123
}
123124

125+
public String createFetchTrackedDevices(String sdkId, String sessionId) {
126+
return format(DOCS_FETCH_TRACKED_DEVICES, sessionId, sdkId);
127+
}
128+
124129
}

yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,15 @@ public void getSupportedDocuments_shouldFailWithExceptionFromYotiDocsService() t
186186
assertThat(thrown, is(original));
187187
}
188188

189+
@Test
190+
public void getTrackedDevices_shouldFailWithExceptionFromYotiDocsService() throws Exception {
191+
DocScanException original = new DocScanException("Test exception");
192+
doThrow(original).when(docScanServiceMock).getTrackedDevices(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID));
193+
DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock);
194+
195+
DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.getTrackedDevices(SOME_SESSION_ID));
196+
197+
assertThat(thrown, is(original));
198+
}
199+
189200
}

0 commit comments

Comments
 (0)