From 209b5ad07d3972d7a611000e3dfcbecd02e37b4a Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 27 Sep 2024 13:24:33 +0100 Subject: [PATCH 01/28] DEVELOPMENT: Bump version to 4.0.0-SNAPSHOT --- README.md | 4 ++-- examples/doc-scan/pom.xml | 2 +- pom.xml | 2 +- yoti-sdk-api/pom.xml | 2 +- .../com/yoti/api/client/spi/remote/call/YotiConstants.java | 2 +- yoti-sdk-parent/pom.xml | 2 +- yoti-sdk-sandbox/pom.xml | 2 +- yoti-sdk-spring-boot-auto-config/README.md | 4 ++-- yoti-sdk-spring-boot-auto-config/pom.xml | 2 +- yoti-sdk-spring-boot-example/README.md | 2 +- yoti-sdk-spring-boot-example/pom.xml | 2 +- yoti-sdk-spring-security/README.md | 4 ++-- yoti-sdk-spring-security/pom.xml | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6d4715c49..84ff94252 100644 --- a/README.md +++ b/README.md @@ -101,13 +101,13 @@ If you are using Maven, you need to add the following dependency: com.yoti yoti-sdk-api - 3.12.0 + 4.0.0-SNAPSHOT ``` If you are using Gradle, here is the dependency to add: -`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '3.12.0'` +`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '4.0.0-SNAPSHOT'` You will find all classes packaged under `com.yoti.api` diff --git a/examples/doc-scan/pom.xml b/examples/doc-scan/pom.xml index 3437b01cc..468e0e43a 100644 --- a/examples/doc-scan/pom.xml +++ b/examples/doc-scan/pom.xml @@ -53,7 +53,7 @@ com.yoti yoti-sdk-api - 3.12.0 + 4.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 58299e883..8d4b8a1b0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk pom - 3.12.0 + 4.0.0-SNAPSHOT Yoti SDK Java SDK for simple integration with the Yoti platform https://github.com/getyoti/yoti-java-sdk diff --git a/yoti-sdk-api/pom.xml b/yoti-sdk-api/pom.xml index 18bcca29a..27714d7ab 100644 --- a/yoti-sdk-api/pom.xml +++ b/yoti-sdk-api/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 3.12.0 + 4.0.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java index 965706a3f..ae1f62831 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java @@ -29,7 +29,7 @@ private YotiConstants() {} public static final String CONTENT_TYPE_JPEG = "image/jpeg"; public static final String JAVA = "Java"; - public static final String SDK_VERSION = JAVA + "-3.12.0"; + public static final String SDK_VERSION = JAVA + "-4.0.0-SNAPSHOT"; public static final String SIGNATURE_ALGORITHM = "SHA256withRSA"; public static final String ASYMMETRIC_CIPHER = "RSA/NONE/PKCS1Padding"; public static final String SYMMETRIC_CIPHER = "AES/CBC/PKCS7Padding"; diff --git a/yoti-sdk-parent/pom.xml b/yoti-sdk-parent/pom.xml index d1e258d7e..2912695e4 100644 --- a/yoti-sdk-parent/pom.xml +++ b/yoti-sdk-parent/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk-parent pom - 3.12.0 + 4.0.0-SNAPSHOT Yoti SDK Parent Pom Parent pom for the Java SDK projects https://github.com/getyoti/yoti-java-sdk diff --git a/yoti-sdk-sandbox/pom.xml b/yoti-sdk-sandbox/pom.xml index 768c2913b..8bf17923e 100644 --- a/yoti-sdk-sandbox/pom.xml +++ b/yoti-sdk-sandbox/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 3.12.0 + 4.0.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-spring-boot-auto-config/README.md b/yoti-sdk-spring-boot-auto-config/README.md index 0c84a94cb..2d7f8864f 100644 --- a/yoti-sdk-spring-boot-auto-config/README.md +++ b/yoti-sdk-spring-boot-auto-config/README.md @@ -18,7 +18,7 @@ If you are using Maven, you need to add the following dependencies: com.yoti yoti-sdk-spring-boot-auto-config - 3.12.0 + 4.0.0-SNAPSHOT ``` @@ -26,7 +26,7 @@ If you are using Maven, you need to add the following dependencies: If you are using Gradle, here is the dependency to add: ``` -compile group: 'com.yoti', name: 'yoti-sdk-spring-boot-auto-config', version: '3.12.0' +compile group: 'com.yoti', name: 'yoti-sdk-spring-boot-auto-config', version: '4.0.0-SNAPSHOT' ``` diff --git a/yoti-sdk-spring-boot-auto-config/pom.xml b/yoti-sdk-spring-boot-auto-config/pom.xml index d690e2dfa..afa28fb84 100644 --- a/yoti-sdk-spring-boot-auto-config/pom.xml +++ b/yoti-sdk-spring-boot-auto-config/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 3.12.0 + 4.0.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-spring-boot-example/README.md b/yoti-sdk-spring-boot-example/README.md index 0693a3b71..5d2793937 100644 --- a/yoti-sdk-spring-boot-example/README.md +++ b/yoti-sdk-spring-boot-example/README.md @@ -17,7 +17,7 @@ Note that: com.yoti yoti-sdk-api - 3.12.0 + 4.0.0-SNAPSHOT ``` diff --git a/yoti-sdk-spring-boot-example/pom.xml b/yoti-sdk-spring-boot-example/pom.xml index b2f632c91..bb86ad435 100644 --- a/yoti-sdk-spring-boot-example/pom.xml +++ b/yoti-sdk-spring-boot-example/pom.xml @@ -6,7 +6,7 @@ com.yoti yoti-sdk-spring-boot-example Yoti Spring Boot Example - 3.12.0 + 4.0.0-SNAPSHOT org.springframework.boot diff --git a/yoti-sdk-spring-security/README.md b/yoti-sdk-spring-security/README.md index d401f9090..f6fe0ca0a 100644 --- a/yoti-sdk-spring-security/README.md +++ b/yoti-sdk-spring-security/README.md @@ -25,14 +25,14 @@ If you are using Maven, you need to add the following dependencies: com.yoti yoti-sdk-spring-security - 3.12.0 + 4.0.0-SNAPSHOT ``` If you are using Gradle, here is the dependency to add: ``` -compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '3.12.0' +compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '4.0.0-SNAPSHOT' ``` ### Provide a `YotiClient` instance diff --git a/yoti-sdk-spring-security/pom.xml b/yoti-sdk-spring-security/pom.xml index 2fc710f33..a902565b9 100644 --- a/yoti-sdk-spring-security/pom.xml +++ b/yoti-sdk-spring-security/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 3.12.0 + 4.0.0-SNAPSHOT ../yoti-sdk-parent From 04a5bb9699c38a90eef05e0d8d6fb811a7cd8f34 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 27 Sep 2024 13:40:49 +0100 Subject: [PATCH 02/28] SDK-2531: Update SessionSpec to use strongly typed object for Identity Profile requirements --- .../docs/session/create/SessionSpec.java | 11 +-- .../IdentityProfileRequirementsPayload.java | 67 +++++++++++++++++++ .../simple/IdentityProfileSchemePayload.java | 67 +++++++++++++++++++ .../docs/session/create/SessionSpecTest.java | 31 ++------- 4 files changed, 146 insertions(+), 30 deletions(-) create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java index b7a0a763a..7d473bb66 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java @@ -8,6 +8,7 @@ import com.yoti.api.client.docs.session.create.check.RequestedCheck; import com.yoti.api.client.docs.session.create.filters.RequiredDocument; import com.yoti.api.client.docs.session.create.identityprofile.advanced.AdvancedIdentityProfileRequirementsPayload; +import com.yoti.api.client.docs.session.create.identityprofile.simple.IdentityProfileRequirementsPayload; import com.yoti.api.client.docs.session.create.resources.ResourceCreationContainer; import com.yoti.api.client.docs.session.create.task.RequestedTask; @@ -55,7 +56,7 @@ public class SessionSpec { private final IbvOptions ibvOptions; @JsonProperty(Property.IDENTITY_PROFILE_REQUIREMENTS) - private final Map identityProfile; + private final IdentityProfileRequirementsPayload identityProfile; @JsonProperty(Property.ADVANCED_IDENTITY_PROFILE_REQUIREMENTS) private final AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements; @@ -81,7 +82,7 @@ public class SessionSpec { Boolean blockBiometricConsent, IbvOptions ibvOptions, ZonedDateTime sessionDeadline, - Map identityProfile, + IdentityProfileRequirementsPayload identityProfile, Map subject, ResourceCreationContainer resources, Boolean createIdentityProfilePreview, @@ -223,7 +224,7 @@ public ZonedDateTime getSessionDeadline() { * * @return Identity Profile */ - public Object getIdentityProfile() { + public IdentityProfileRequirementsPayload getIdentityProfile() { return identityProfile; } @@ -277,7 +278,7 @@ public static class Builder { private Boolean blockBiometricConsent; private IbvOptions ibvOptions; private ZonedDateTime sessionDeadline; - private Map identityProfile; + private IdentityProfileRequirementsPayload identityProfile; private AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirementsPayload; private Map subject; private ResourceCreationContainer resources; @@ -428,7 +429,7 @@ public Builder withSessionDeadline(ZonedDateTime sessionDeadline) { * @param identityProfile the Identity Profile * @return the Builder */ - public Builder withIdentityProfile(Map identityProfile) { + public Builder withIdentityProfile(IdentityProfileRequirementsPayload identityProfile) { this.identityProfile = identityProfile; return this; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java new file mode 100644 index 000000000..e75f454ca --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java @@ -0,0 +1,67 @@ +package com.yoti.api.client.docs.session.create.identityprofile.simple; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class IdentityProfileRequirementsPayload { + + @JsonProperty("trust_framework") + private final String trustFramework; + + @JsonProperty("scheme") + private final IdentityProfileSchemePayload scheme; + + IdentityProfileRequirementsPayload(String trustFramework, IdentityProfileSchemePayload scheme) { + this.trustFramework = trustFramework; + this.scheme = scheme; + } + + public static Builder builder() { + return new Builder(); + } + + public String getTrustFramework() { + return trustFramework; + } + + public IdentityProfileSchemePayload getScheme() { + return scheme; + } + + public static class Builder { + + private String trustFramework; + private IdentityProfileSchemePayload scheme; + + Builder() {} + + /** + * Sets the trust framework name for the Identity Profile requirement + * + * @param trustFramework the name of the trust framework + * @return the builder + */ + public Builder withTrustFramework(String trustFramework) { + this.trustFramework = trustFramework; + return this; + } + + /** + * Sets the scheme for the Identity Profile requirement + * + * @param scheme the scheme + * @return the builder + */ + public Builder withScheme(IdentityProfileSchemePayload scheme) { + this.scheme = scheme; + return this; + } + + public IdentityProfileRequirementsPayload build() { + return new IdentityProfileRequirementsPayload(trustFramework, scheme); + } + + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java new file mode 100644 index 000000000..228173b11 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java @@ -0,0 +1,67 @@ +package com.yoti.api.client.docs.session.create.identityprofile.simple; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class IdentityProfileSchemePayload { + + @JsonProperty("type") + private final String type; + + @JsonProperty("objective") + private final String objective; + + IdentityProfileSchemePayload(String type, String objective) { + this.type = type; + this.objective = objective; + } + + public static Builder builder() { + return new Builder(); + } + + public String getType() { + return type; + } + + public String getObjective() { + return objective; + } + + public static class Builder { + + private String type; + private String objective; + + Builder() {} + + /** + * Sets the type of the scheme for the Identity Profile + * + * @param type the type of scheme + * @return the builder + */ + public Builder withType(String type) { + this.type = type; + return this; + } + + /** + * Sets the objective of the scheme for the Identity Profile + * + * @param objective the objective of the scheme + * @return the builder + */ + public Builder withObjective(String objective) { + this.objective = objective; + return this; + } + + public IdentityProfileSchemePayload build() { + return new IdentityProfileSchemePayload(type, objective); + } + + } + +} diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java index d0bb1463f..e222b6f2a 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java @@ -20,6 +20,7 @@ import com.yoti.api.client.docs.session.create.check.RequestedDocumentAuthenticityCheck; import com.yoti.api.client.docs.session.create.check.RequestedLivenessCheck; import com.yoti.api.client.docs.session.create.filters.RequiredDocument; +import com.yoti.api.client.docs.session.create.identityprofile.simple.IdentityProfileRequirementsPayload; import com.yoti.api.client.docs.session.create.resources.ResourceCreationContainer; import com.yoti.api.client.docs.session.create.task.RequestedIdDocTextExtractionTask; @@ -57,6 +58,7 @@ public class SessionSpecTest { @Mock ZonedDateTime sessionDeadlineMock; @Mock ResourceCreationContainer resourceCreationContainerMock; @Mock ImportTokenPayload importTokenMock; + @Mock IdentityProfileRequirementsPayload identityProfileRequirementsPayloadMock; @Test public void shouldBuildWithMinimalConfiguration() { @@ -215,33 +217,12 @@ public void withSessionDeadline_shouldSetTheSessionDeadline() { } @Test - public void shouldBuildWithIdentityProfileRequirements() throws IOException { - Map scheme = new HashMap<>(); - scheme.put(IdentityProperty.TYPE, "A_TYPE"); - scheme.put(IdentityProperty.OBJECTIVE, "AN_OBJECTIVE"); - - Map identityProfile = new HashMap<>(); - identityProfile.put(IdentityProperty.TRUST_FRAMEWORK, "A_FRAMEWORK"); - identityProfile.put(IdentityProperty.SCHEME, scheme); - - JsonNode json = toSessionSpecJson(identityProfile); - - assertThat( - json.get(IdentityProperty.TRUST_FRAMEWORK).asText(), - is(equalTo(identityProfile.get(IdentityProperty.TRUST_FRAMEWORK))) - ); - - JsonNode schemeJsonNode = json.get(IdentityProperty.SCHEME); - assertThat(schemeJsonNode.get(IdentityProperty.TYPE).asText(), is(equalTo(scheme.get(IdentityProperty.TYPE)))); - assertThat(schemeJsonNode.get(IdentityProperty.OBJECTIVE).asText(), is(equalTo(scheme.get(IdentityProperty.OBJECTIVE)))); - } - - private static JsonNode toSessionSpecJson(Map obj) throws IOException { - SessionSpec session = SessionSpec.builder() - .withIdentityProfile(obj) + public void withIdentityProfile_shouldSetTheIdentityProfile() { + SessionSpec result = SessionSpec.builder() + .withIdentityProfile(identityProfileRequirementsPayloadMock) .build(); - return MAPPER.readTree(MAPPER.writeValueAsString(session.getIdentityProfile()).getBytes(DEFAULT_CHARSET)); + assertThat(result.getIdentityProfile(), is(identityProfileRequirementsPayloadMock)); } @Test From 097af1cf48af9e5b870cc8f4438861107d717ab2 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 27 Sep 2024 15:14:21 +0100 Subject: [PATCH 03/28] SDK-2532: Update SessionSpec to use strongly typed object for Identity Profile subject --- .../create/IdentityProfileSubjectPayload.java | 45 +++++++++++++++++ .../docs/session/create/SessionSpec.java | 10 ++-- .../docs/session/create/SessionSpecTest.java | 48 ++----------------- 3 files changed, 55 insertions(+), 48 deletions(-) create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IdentityProfileSubjectPayload.java diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IdentityProfileSubjectPayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IdentityProfileSubjectPayload.java new file mode 100644 index 000000000..6eeceb9bc --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IdentityProfileSubjectPayload.java @@ -0,0 +1,45 @@ +package com.yoti.api.client.docs.session.create; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class IdentityProfileSubjectPayload { + + @JsonProperty("subject_id") + private final String subjectId; + + IdentityProfileSubjectPayload(String subjectId) { + this.subjectId = subjectId; + } + + public static Builder builder() { + return new Builder(); + } + + public String getSubjectId() { + return subjectId; + } + + public static class Builder { + + private String subjectId; + + Builder() {} + + /** + * Sets the subject ID for the Identity Profile requirement + * + * @param subjectId the subject ID + * @return the builder + */ + public Builder withSubjectId(String subjectId) { + this.subjectId = subjectId; + return this; + } + + public IdentityProfileSubjectPayload build() { + return new IdentityProfileSubjectPayload(subjectId); + } + + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java index 7d473bb66..34318906e 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java @@ -62,7 +62,7 @@ public class SessionSpec { private final AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements; @JsonProperty(Property.SUBJECT) - private final Map subject; + private final IdentityProfileSubjectPayload subject; @JsonProperty(Property.RESOURCES) private final ResourceCreationContainer resources; @@ -83,7 +83,7 @@ public class SessionSpec { IbvOptions ibvOptions, ZonedDateTime sessionDeadline, IdentityProfileRequirementsPayload identityProfile, - Map subject, + IdentityProfileSubjectPayload subject, ResourceCreationContainer resources, Boolean createIdentityProfilePreview, AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements) { @@ -233,7 +233,7 @@ public IdentityProfileRequirementsPayload getIdentityProfile() { * * @return subject */ - public Map getSubject() { + public IdentityProfileSubjectPayload getSubject() { return subject; } @@ -280,7 +280,7 @@ public static class Builder { private ZonedDateTime sessionDeadline; private IdentityProfileRequirementsPayload identityProfile; private AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirementsPayload; - private Map subject; + private IdentityProfileSubjectPayload subject; private ResourceCreationContainer resources; private Boolean createIdentityProfilePreview; @@ -440,7 +440,7 @@ public Builder withIdentityProfile(IdentityProfileRequirementsPayload identityPr * @param subject the subject * @return the Builder */ - public Builder withSubject(Map subject) { + public Builder withSubject(IdentityProfileSubjectPayload subject) { this.subject = subject; return this; } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java index e222b6f2a..76d4bb39b 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java @@ -1,10 +1,7 @@ package com.yoti.api.client.docs.session.create; -import static com.yoti.api.client.spi.remote.call.YotiConstants.DEFAULT_CHARSET; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; @@ -12,10 +9,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import java.io.IOException; import java.time.ZonedDateTime; -import java.util.HashMap; -import java.util.Map; import com.yoti.api.client.docs.session.create.check.RequestedDocumentAuthenticityCheck; import com.yoti.api.client.docs.session.create.check.RequestedLivenessCheck; @@ -24,9 +18,6 @@ import com.yoti.api.client.docs.session.create.resources.ResourceCreationContainer; import com.yoti.api.client.docs.session.create.task.RequestedIdDocTextExtractionTask; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -51,14 +42,13 @@ public class SessionSpecTest { private static final String SOME_SDK_CONFIG_SUCCESS_URL = "https://yourdomain.com/some/success/endpoint"; private static final String SOME_SDK_CONFIG_ERROR_URL = "https://yourdomain.com/some/error/endpoint"; - private static final ObjectMapper MAPPER = new ObjectMapper(); - @Mock RequiredDocument requiredDocumentMock; @Mock IbvOptions ibvOptionsMock; @Mock ZonedDateTime sessionDeadlineMock; @Mock ResourceCreationContainer resourceCreationContainerMock; @Mock ImportTokenPayload importTokenMock; @Mock IdentityProfileRequirementsPayload identityProfileRequirementsPayloadMock; + @Mock IdentityProfileSubjectPayload identityProfileSubjectPayloadMock; @Test public void shouldBuildWithMinimalConfiguration() { @@ -226,21 +216,12 @@ public void withIdentityProfile_shouldSetTheIdentityProfile() { } @Test - public void shouldBuildWithSubject() throws IOException { - Map subject = new HashMap<>(); - subject.put(SubjectProperty.SUBJECT_ID, "A_SUBJECT_ID"); - - SessionSpec session = SessionSpec.builder() - .withSubject(subject) + public void withSubject_shouldSetTheSubject() { + SessionSpec result = SessionSpec.builder() + .withSubject(identityProfileSubjectPayloadMock) .build(); - ObjectMapper mapper = new ObjectMapper(); - - JsonNode json = mapper.readTree( - mapper.writeValueAsString(session.getSubject()).getBytes(DEFAULT_CHARSET) - ); - - assertThat(json.get("subject_id").asText(), is(Matchers.equalTo(subject.get(SubjectProperty.SUBJECT_ID)))); + assertThat(result.getSubject(), is(identityProfileSubjectPayloadMock)); } @Test @@ -270,23 +251,4 @@ public void shouldBuildWithImportToken() { assertThat(sessionSpec.getImportToken(), is(importTokenMock)); } - private static final class IdentityProperty { - - private static final String TYPE = "type"; - private static final String SCHEME = "scheme"; - private static final String OBJECTIVE = "objective"; - private static final String TRUST_FRAMEWORK = "trust_framework"; - - private IdentityProperty() { } - - } - - private static final class SubjectProperty { - - private static final String SUBJECT_ID = "subject_id"; - - private SubjectProperty() {} - - } - } From 4e53eca0c9fd06378f635e2dd388efc8d62fc08a Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 27 Sep 2024 15:25:48 +0100 Subject: [PATCH 04/28] SDK-2533: Change IdentityProfileResponse to use a stronly typed object for the report --- .../src/main/resources/templates/success.html | 8 ++++ .../IdentityProfileReportResponse.java | 45 +++++++++++++++++++ .../retrieve/IdentityProfileResponse.java | 6 +-- ...ProfileSchemeComplianceReportResponse.java | 43 ++++++++++++++++++ .../IdentityProfileSchemeResponse.java | 31 +++++++++++++ 5 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileReportResponse.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeComplianceReportResponse.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeResponse.java diff --git a/examples/doc-scan/src/main/resources/templates/success.html b/examples/doc-scan/src/main/resources/templates/success.html index 1d85831f9..2ddeb6f4a 100644 --- a/examples/doc-scan/src/main/resources/templates/success.html +++ b/examples/doc-scan/src/main/resources/templates/success.html @@ -965,6 +965,14 @@

Identity Profile

+ +
+ Generated Profile Media: + +
+
+
diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileReportResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileReportResponse.java new file mode 100644 index 000000000..99cfc60f4 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileReportResponse.java @@ -0,0 +1,45 @@ +package com.yoti.api.client.docs.session.retrieve; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class IdentityProfileReportResponse { + + @JsonProperty("trust_framework") + private String trustFramework; + + @JsonProperty("media") + private MediaResponse media; + + @JsonProperty("schemes_compliance") + private List schemesCompliance; + + /** + * The trust framework the report was generated for + * + * @return the trust framework + */ + public String getTrustFramework() { + return trustFramework; + } + + /** + * The media object containing the report + * + * @return the report media + */ + public MediaResponse getMedia() { + return media; + } + + /** + * The list of schemes used in the trust framework + * + * @return the list of schemes + */ + public List getSchemesCompliance() { + return schemesCompliance; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java index 896e56223..ba4b09d70 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java @@ -1,7 +1,5 @@ package com.yoti.api.client.docs.session.retrieve; -import java.util.Map; - import com.fasterxml.jackson.annotation.JsonProperty; public class IdentityProfileResponse { @@ -16,7 +14,7 @@ public class IdentityProfileResponse { private IdentityProfileFailureResponse failureReason; @JsonProperty(Property.IDENTITY_PROFILE_REPORT) - private Map identityProfileReport; + private IdentityProfileReportResponse identityProfileReport; public String getSubjectId() { return subjectId; @@ -30,7 +28,7 @@ public IdentityProfileFailureResponse getFailureReason() { return failureReason; } - public Map getIdentityProfileReport() { + public IdentityProfileReportResponse getIdentityProfileReport() { return identityProfileReport; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeComplianceReportResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeComplianceReportResponse.java new file mode 100644 index 000000000..646886c9b --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeComplianceReportResponse.java @@ -0,0 +1,43 @@ +package com.yoti.api.client.docs.session.retrieve; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class IdentityProfileSchemeComplianceReportResponse { + + @JsonProperty("scheme") + private IdentityProfileSchemeResponse scheme; + + @JsonProperty("requirements_met") + private Boolean requirementsMet; + + @JsonProperty("requirements_not_met_info") + private String requirementsNotMetInfo; + + /** + * The Identity Profile scheme + * + * @return the scheme + */ + public IdentityProfileSchemeResponse getScheme() { + return scheme; + } + + /** + * Whether or not the requirements for the scheme were met + * + * @return boolean + */ + public Boolean getRequirementsMet() { + return requirementsMet; + } + + /** + * Information about why the requirements for the scheme were not met + * + * @return string + */ + public String getRequirementsNotMetInfo() { + return requirementsNotMetInfo; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeResponse.java new file mode 100644 index 000000000..fe33fceed --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeResponse.java @@ -0,0 +1,31 @@ +package com.yoti.api.client.docs.session.retrieve; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class IdentityProfileSchemeResponse { + + @JsonProperty("type") + private String type; + + @JsonProperty("objective") + private String objective; + + /** + * The type of the scheme + * + * @return the type + */ + public String getType() { + return type; + } + + /** + * The objective of the scheme + * + * @return the objective + */ + public String getObjective() { + return objective; + } + +} From c23ba66678e1d1506350ba3fdf82d3001e2266a3 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 27 Sep 2024 17:04:50 +0100 Subject: [PATCH 05/28] SDK-2532: Rename IdentityProfileSubjectPayload -> SubjectPayload --- .../api/client/docs/session/create/SessionSpec.java | 11 +++++------ ...ProfileSubjectPayload.java => SubjectPayload.java} | 8 ++++---- .../client/docs/session/create/SessionSpecTest.java | 6 +++--- 3 files changed, 12 insertions(+), 13 deletions(-) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/{IdentityProfileSubjectPayload.java => SubjectPayload.java} (78%) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java index 34318906e..ef5a52a1c 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java @@ -3,7 +3,6 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; -import java.util.Map; import com.yoti.api.client.docs.session.create.check.RequestedCheck; import com.yoti.api.client.docs.session.create.filters.RequiredDocument; @@ -62,7 +61,7 @@ public class SessionSpec { private final AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements; @JsonProperty(Property.SUBJECT) - private final IdentityProfileSubjectPayload subject; + private final SubjectPayload subject; @JsonProperty(Property.RESOURCES) private final ResourceCreationContainer resources; @@ -83,7 +82,7 @@ public class SessionSpec { IbvOptions ibvOptions, ZonedDateTime sessionDeadline, IdentityProfileRequirementsPayload identityProfile, - IdentityProfileSubjectPayload subject, + SubjectPayload subject, ResourceCreationContainer resources, Boolean createIdentityProfilePreview, AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements) { @@ -233,7 +232,7 @@ public IdentityProfileRequirementsPayload getIdentityProfile() { * * @return subject */ - public IdentityProfileSubjectPayload getSubject() { + public SubjectPayload getSubject() { return subject; } @@ -280,7 +279,7 @@ public static class Builder { private ZonedDateTime sessionDeadline; private IdentityProfileRequirementsPayload identityProfile; private AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirementsPayload; - private IdentityProfileSubjectPayload subject; + private SubjectPayload subject; private ResourceCreationContainer resources; private Boolean createIdentityProfilePreview; @@ -440,7 +439,7 @@ public Builder withIdentityProfile(IdentityProfileRequirementsPayload identityPr * @param subject the subject * @return the Builder */ - public Builder withSubject(IdentityProfileSubjectPayload subject) { + public Builder withSubject(SubjectPayload subject) { this.subject = subject; return this; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IdentityProfileSubjectPayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SubjectPayload.java similarity index 78% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IdentityProfileSubjectPayload.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SubjectPayload.java index 6eeceb9bc..513a40595 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IdentityProfileSubjectPayload.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SubjectPayload.java @@ -2,12 +2,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; -public class IdentityProfileSubjectPayload { +public class SubjectPayload { @JsonProperty("subject_id") private final String subjectId; - IdentityProfileSubjectPayload(String subjectId) { + SubjectPayload(String subjectId) { this.subjectId = subjectId; } @@ -36,8 +36,8 @@ public Builder withSubjectId(String subjectId) { return this; } - public IdentityProfileSubjectPayload build() { - return new IdentityProfileSubjectPayload(subjectId); + public SubjectPayload build() { + return new SubjectPayload(subjectId); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java index 76d4bb39b..cf303428e 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java @@ -48,7 +48,7 @@ public class SessionSpecTest { @Mock ResourceCreationContainer resourceCreationContainerMock; @Mock ImportTokenPayload importTokenMock; @Mock IdentityProfileRequirementsPayload identityProfileRequirementsPayloadMock; - @Mock IdentityProfileSubjectPayload identityProfileSubjectPayloadMock; + @Mock SubjectPayload subjectPayloadMock; @Test public void shouldBuildWithMinimalConfiguration() { @@ -218,10 +218,10 @@ public void withIdentityProfile_shouldSetTheIdentityProfile() { @Test public void withSubject_shouldSetTheSubject() { SessionSpec result = SessionSpec.builder() - .withSubject(identityProfileSubjectPayloadMock) + .withSubject(subjectPayloadMock) .build(); - assertThat(result.getSubject(), is(identityProfileSubjectPayloadMock)); + assertThat(result.getSubject(), is(subjectPayloadMock)); } @Test From 49c5c808058cacd76ae7fdc7d896e4fd936b1e44 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 27 Sep 2024 17:11:18 +0100 Subject: [PATCH 06/28] NA: Inline JSON property name in IDV classes --- .../docs/session/create/IbvOptions.java | 16 +---- .../client/docs/session/create/SdkConfig.java | 55 +++++------------- .../docs/session/create/SessionSpec.java | 58 ++++++------------- .../client/docs/session/create/UserPrice.java | 13 +---- .../session/retrieve/GetSessionResult.java | 46 +++++---------- .../retrieve/IdentityProfileResponse.java | 19 ++---- .../session/retrieve/ImportTokenResponse.java | 13 +---- .../spi/remote/call/ProfileResponse.java | 16 +---- 8 files changed, 60 insertions(+), 176 deletions(-) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IbvOptions.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IbvOptions.java index 669697fda..3551278ec 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IbvOptions.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/IbvOptions.java @@ -6,13 +6,13 @@ public class IbvOptions { - @JsonProperty(Property.SUPPORT) + @JsonProperty("support") private final String support; - @JsonProperty(Property.GUIDANCE_URL) + @JsonProperty("guidance_url") private final String guidanceUrl; - @JsonProperty(Property.USER_PRICE) + @JsonProperty("user_price") private final UserPrice userPrice; private IbvOptions(String support, String guidanceUrl, UserPrice userPrice) { @@ -102,14 +102,4 @@ public IbvOptions build() { } - private static final class Property { - - private static final String SUPPORT = "support"; - private static final String GUIDANCE_URL = "guidance_url"; - private static final String USER_PRICE = "user_price"; - - private Property() { } - - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java index 56253bbec..549b429d1 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java @@ -12,52 +12,52 @@ */ public class SdkConfig { - @JsonProperty(Property.ALLOWED_CAPTURE_METHODS) + @JsonProperty("allowed_capture_methods") private final String allowedCaptureMethods; - @JsonProperty(Property.PRIMARY_COLOUR) + @JsonProperty("primary_colour") private final String primaryColour; - @JsonProperty(Property.PRIMARY_COLOUR_DARK_MODE) + @JsonProperty("primary_colour_dark_mode") private final String primaryColourDarkMode; - @JsonProperty(Property.SECONDARY_COLOUR) + @JsonProperty("secondary_colour") private final String secondaryColour; - @JsonProperty(Property.FONT_COLOUR) + @JsonProperty("font_colour") private final String fontColour; - @JsonProperty(Property.DARK_MODE) + @JsonProperty("dark_mode") private final String darkMode; - @JsonProperty(Property.LOCALE) + @JsonProperty("locale") private final String locale; - @JsonProperty(Property.PRESET_ISSUING_COUNTRY) + @JsonProperty("preset_issuing_country") private final String presetIssuingCountry; - @JsonProperty(Property.SUCCESS_URL) + @JsonProperty("success_url") private final String successUrl; - @JsonProperty(Property.ERROR_URL) + @JsonProperty("error_url") private final String errorUrl; - @JsonProperty(Property.PRIVACY_POLICY_URL) + @JsonProperty("privacy_policy_url") private final String privacyPolicyUrl; - @JsonProperty(Property.ALLOW_HANDOFF) + @JsonProperty("allow_handoff") private final Boolean allowHandoff; - @JsonProperty(Property.ATTEMPTS_CONFIGURATION) + @JsonProperty("attempts_configuration") private final AttemptsConfiguration attemptsConfiguration; - @JsonProperty(Property.BRAND_ID) + @JsonProperty("brand_id") private final String brandId; - @JsonProperty(Property.BIOMETRIC_CONSENT_FLOW) + @JsonProperty("biometric_consent_flow") private final String biometricConsentFlow; - @JsonProperty(Property.SUPPRESSED_SCREENS) + @JsonProperty("suppressed_screens") private final List suppressedScreens; SdkConfig(String allowedCaptureMethods, @@ -536,27 +536,4 @@ public SdkConfig build() { } } - private static final class Property { - - private static final String ALLOWED_CAPTURE_METHODS = "allowed_capture_methods"; - private static final String PRIMARY_COLOUR = "primary_colour"; - private static final String PRIMARY_COLOUR_DARK_MODE = "primary_colour_dark_mode"; - private static final String SECONDARY_COLOUR = "secondary_colour"; - private static final String FONT_COLOUR = "font_colour"; - private static final String DARK_MODE = "dark_mode"; - private static final String LOCALE = "locale"; - private static final String PRESET_ISSUING_COUNTRY = "preset_issuing_country"; - private static final String SUCCESS_URL = "success_url"; - private static final String ERROR_URL = "error_url"; - private static final String PRIVACY_POLICY_URL = "privacy_policy_url"; - private static final String ALLOW_HANDOFF = "allow_handoff"; - private static final String ATTEMPTS_CONFIGURATION = "attempts_configuration"; - private static final String BRAND_ID = "brand_id"; - private static final String BIOMETRIC_CONSENT_FLOW = "biometric_consent_flow"; - private static final String SUPPRESSED_SCREENS = "suppressed_screens"; - - private Property() {} - - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java index ef5a52a1c..834bbbb15 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java @@ -18,55 +18,55 @@ */ public class SessionSpec { - @JsonProperty(Property.CLIENT_SESSION_TOKEN_TTL) + @JsonProperty("client_session_token_ttl") private final Integer clientSessionTokenTtl; - @JsonProperty(Property.SESSION_DEADLINE) + @JsonProperty("session_deadline") private final ZonedDateTime sessionDeadline; - @JsonProperty(Property.RESOURCES_TTL) + @JsonProperty("resources_ttl") private final Integer resourcesTtl; - @JsonProperty(Property.IMPORT_TOKEN) + @JsonProperty("import_token") private final ImportTokenPayload importToken; - @JsonProperty(Property.USER_TRACKING_ID) + @JsonProperty("user_tracking_id") private final String userTrackingId; - @JsonProperty(Property.NOTIFICATIONS) + @JsonProperty("notifications") private final NotificationConfig notifications; - @JsonProperty(Property.REQUESTED_CHECKS) + @JsonProperty("requested_checks") private final List> requestedChecks; - @JsonProperty(Property.REQUESTED_TASKS) + @JsonProperty("requested_tasks") private final List> requestedTasks; - @JsonProperty(Property.SDK_CONFIG) + @JsonProperty("sdk_config") private final SdkConfig sdkConfig; - @JsonProperty(Property.REQUIRED_DOCUMENTS) + @JsonProperty("required_documents") private final List requiredDocuments; - @JsonProperty(Property.BLOCK_BIOMETRIC_CONSENT) + @JsonProperty("block_biometric_consent") private final Boolean blockBiometricConsent; - @JsonProperty(Property.IBV_OPTIONS) + @JsonProperty("ibv_options") private final IbvOptions ibvOptions; - @JsonProperty(Property.IDENTITY_PROFILE_REQUIREMENTS) + @JsonProperty("identity_profile_requirements") private final IdentityProfileRequirementsPayload identityProfile; - @JsonProperty(Property.ADVANCED_IDENTITY_PROFILE_REQUIREMENTS) + @JsonProperty("advanced_identity_profile_requirements") private final AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements; - @JsonProperty(Property.SUBJECT) + @JsonProperty("subject") private final SubjectPayload subject; - @JsonProperty(Property.RESOURCES) + @JsonProperty("resources") private final ResourceCreationContainer resources; - @JsonProperty(Property.CREATE_IDENTITY_PROFILE_PREVIEW) + @JsonProperty("create_identity_profile_preview") private final Boolean createIdentityProfilePreview; SessionSpec(Integer clientSessionTokenTtl, @@ -504,28 +504,4 @@ public SessionSpec build() { } } - private static final class Property { - - private static final String CLIENT_SESSION_TOKEN_TTL = "client_session_token_ttl"; - private static final String SESSION_DEADLINE = "session_deadline"; - private static final String RESOURCES_TTL = "resources_ttl"; - private static final String USER_TRACKING_ID = "user_tracking_id"; - private static final String NOTIFICATIONS = "notifications"; - private static final String REQUESTED_CHECKS = "requested_checks"; - private static final String REQUESTED_TASKS = "requested_tasks"; - private static final String SDK_CONFIG = "sdk_config"; - private static final String REQUIRED_DOCUMENTS = "required_documents"; - private static final String BLOCK_BIOMETRIC_CONSENT = "block_biometric_consent"; - private static final String IBV_OPTIONS = "ibv_options"; - private static final String IDENTITY_PROFILE_REQUIREMENTS = "identity_profile_requirements"; - private static final String ADVANCED_IDENTITY_PROFILE_REQUIREMENTS = "advanced_identity_profile_requirements"; - private static final String SUBJECT = "subject"; - private static final String RESOURCES = "resources"; - private static final String CREATE_IDENTITY_PROFILE_PREVIEW = "create_identity_profile_preview"; - private static final String IMPORT_TOKEN = "import_token"; - - private Property() { } - - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/UserPrice.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/UserPrice.java index 38d1a745c..90c651a78 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/UserPrice.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/UserPrice.java @@ -6,10 +6,10 @@ public class UserPrice { - @JsonProperty(Property.AMOUNT) + @JsonProperty("amount") private final String amount; - @JsonProperty(Property.CURRENCY) + @JsonProperty("currency") private final String currency; private UserPrice(String amount, String currency) { @@ -78,13 +78,4 @@ public UserPrice build() { } - private static final class Property { - - private static final String AMOUNT = "amount"; - private static final String CURRENCY = "currency"; - - private Property() { } - - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java index 87e2f233b..6be4325d8 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java @@ -9,43 +9,43 @@ public class GetSessionResult { - @JsonProperty(Property.CLIENT_SESSION_TOKEN_TTL) + @JsonProperty("client_session_token_ttl") private long clientSessionTokenTtl; - @JsonProperty(Property.SESSION_ID) + @JsonProperty("session_id") private String sessionId; - @JsonProperty(Property.USER_TRACKING_ID) + @JsonProperty("user_tracking_id") private String userTrackingId; - @JsonProperty(Property.STATE) + @JsonProperty("state") private String state; - @JsonProperty(Property.CLIENT_SESSION_TOKEN) + @JsonProperty("client_session_token") private String clientSessionToken; - @JsonProperty(Property.BIOMETRIC_CONSENT) + @JsonProperty("biometric_consent") private String biometricConsent; - @JsonProperty(Property.CHECKS) + @JsonProperty("checks") private List checks; - @JsonProperty(Property.RESOURCES) + @JsonProperty("resources") private ResourceContainer resources; - @JsonProperty(Property.IDENTITY_PROFILE) + @JsonProperty("identity_profile") private IdentityProfileResponse identityProfile; - @JsonProperty(Property.ADVANCED_IDENTITY_PROFILE) + @JsonProperty("advanced_identity_profile") private AdvancedIdentityProfileResponse advancedIdentityProfile; - @JsonProperty(Property.IDENTITY_PROFILE_PREVIEW) + @JsonProperty("identity_profile_preview") private IdentityProfilePreviewResponse identityProfilePreview; - @JsonProperty(Property.ADVANCED_IDENTITY_PROFILE_PREVIEW) + @JsonProperty("advanced_identity_profile_preview") private IdentityProfilePreviewResponse advancedIdentityProfilePreview; - @JsonProperty(Property.IMPORT_TOKEN) + @JsonProperty("import_token") private ImportTokenResponse importToken; public long getClientSessionTokenTtl() { @@ -175,24 +175,4 @@ private List filterChecksByType(Class clazz) { .collect(Collectors.toList()); } - private static final class Property { - - private static final String CLIENT_SESSION_TOKEN_TTL = "client_session_token_ttl"; - private static final String SESSION_ID = "session_id"; - private static final String USER_TRACKING_ID = "user_tracking_id"; - private static final String STATE = "state"; - private static final String CLIENT_SESSION_TOKEN = "client_session_token"; - private static final String BIOMETRIC_CONSENT = "biometric_consent"; - private static final String CHECKS = "checks"; - private static final String RESOURCES = "resources"; - private static final String IDENTITY_PROFILE = "identity_profile"; - private static final String ADVANCED_IDENTITY_PROFILE = "advanced_identity_profile"; - private static final String IDENTITY_PROFILE_PREVIEW = "identity_profile_preview"; - private static final String ADVANCED_IDENTITY_PROFILE_PREVIEW = "advanced_identity_profile_preview"; - private static final String IMPORT_TOKEN = "import_token"; - - private Property() { } - - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java index ba4b09d70..8cb52cc3c 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java @@ -4,16 +4,16 @@ public class IdentityProfileResponse { - @JsonProperty(Property.SUBJECT_ID) + @JsonProperty("subject_id") private String subjectId; - @JsonProperty(Property.RESULT) + @JsonProperty("result") private String result; - @JsonProperty(Property.FAILURE_REASON) + @JsonProperty("failure_reason") private IdentityProfileFailureResponse failureReason; - @JsonProperty(Property.IDENTITY_PROFILE_REPORT) + @JsonProperty("identity_profile_report") private IdentityProfileReportResponse identityProfileReport; public String getSubjectId() { @@ -32,15 +32,4 @@ public IdentityProfileReportResponse getIdentityProfileReport() { return identityProfileReport; } - private static final class Property { - - private static final String SUBJECT_ID = "subject_id"; - private static final String RESULT = "result"; - private static final String FAILURE_REASON = "failure_reason"; - private static final String IDENTITY_PROFILE_REPORT = "identity_profile_report"; - - private Property() { } - - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ImportTokenResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ImportTokenResponse.java index 73e30650e..2cffb878d 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ImportTokenResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ImportTokenResponse.java @@ -4,10 +4,10 @@ public class ImportTokenResponse { - @JsonProperty(Property.MEDIA) + @JsonProperty("media") private MediaResponse media; - @JsonProperty(Property.FAILURE_REASON) + @JsonProperty("failure_reason") private String failureReason; public MediaResponse getMedia() { @@ -18,13 +18,4 @@ public String getFailureReason() { return failureReason; } - private static final class Property { - - private static final String MEDIA = "media"; - private static final String FAILURE_REASON = "failure_reason"; - - private Property() { } - - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileResponse.java index b3dcc319b..53c9ed8ce 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileResponse.java @@ -6,13 +6,13 @@ public class ProfileResponse { - @JsonProperty(Property.SESSION_DATA) + @JsonProperty("session_data") private String sessionData; - @JsonProperty(Property.RECEIPT) + @JsonProperty("receipt") private Receipt receipt; - @JsonProperty(Property.ERROR_DETAILS) + @JsonProperty("error_details") private ErrorDetails error; public ProfileResponse() { } @@ -105,14 +105,4 @@ public ProfileResponse build() { } - private static final class Property { - - private static final String SESSION_DATA = "session_data"; - private static final String RECEIPT = "receipt"; - private static final String ERROR_DETAILS = "error_details"; - - private Property() { } - - } - } From 606757ed5f8541a3f3cf42fe033d87d6369df64f Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 27 Sep 2024 17:11:42 +0100 Subject: [PATCH 07/28] NA: Optimize imports --- .../liveness/UnknownRequiredLivenessResourceResponse.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/liveness/UnknownRequiredLivenessResourceResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/liveness/UnknownRequiredLivenessResourceResponse.java index 8a5c79677..375aa50ed 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/liveness/UnknownRequiredLivenessResourceResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/liveness/UnknownRequiredLivenessResourceResponse.java @@ -1,7 +1,5 @@ package com.yoti.api.client.docs.session.retrieve.configuration.capture.liveness; -import com.yoti.api.client.docs.session.retrieve.configuration.capture.liveness.RequiredLivenessResourceResponse; - public class UnknownRequiredLivenessResourceResponse extends RequiredLivenessResourceResponse { } From 404ac45688c630171852b7da2e22712c3f623b30 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Mon, 30 Sep 2024 12:20:58 +0100 Subject: [PATCH 08/28] NA: Update README with breaking changes in 4.0.0 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 84ff94252..a30beba81 100644 --- a/README.md +++ b/README.md @@ -294,6 +294,10 @@ Instructions on how to run the Spring example projects can be found at the follo This major update does not have any major updates to the API, but instead builds upon and standardizes our implementation. +## Breaking changes and enhancements made in v4.0.0 + +- Creating an Identity Profile session now uses strongly typed classes, instead of a Map + ### Dropped support for Java 7 Minimum supported Java version is now 8. From ccc772bb4b93ba9ff674c5e2ea468bfa62c5ebf1 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Mon, 30 Sep 2024 16:32:50 +0100 Subject: [PATCH 09/28] SDK-2534: Move Identity Profile responses and associated classes to their own package --- .../api/client/docs/session/retrieve/GetSessionResult.java | 2 ++ .../{ => identityprofile}/IdentityProfileFailureResponse.java | 2 +- .../{ => identityprofile}/IdentityProfilePreviewResponse.java | 4 +++- .../{ => identityprofile}/IdentityProfileReportResponse.java | 4 +++- .../{ => identityprofile}/IdentityProfileResponse.java | 2 +- .../IdentityProfileSchemeComplianceReportResponse.java | 2 +- .../{ => identityprofile}/IdentityProfileSchemeResponse.java | 2 +- .../RequirementNotMetDetailsResponse.java | 2 +- .../advanced/AdvancedIdentityProfileResponse.java | 2 +- 9 files changed, 14 insertions(+), 8 deletions(-) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/{ => identityprofile}/IdentityProfileFailureResponse.java (88%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/{ => identityprofile}/IdentityProfilePreviewResponse.java (63%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/{ => identityprofile}/IdentityProfileReportResponse.java (88%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/{ => identityprofile}/IdentityProfileResponse.java (91%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/{ => identityprofile}/IdentityProfileSchemeComplianceReportResponse.java (93%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/{ => identityprofile}/IdentityProfileSchemeResponse.java (88%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/{ => identityprofile}/RequirementNotMetDetailsResponse.java (92%) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java index 6be4325d8..00e81162d 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java @@ -3,6 +3,8 @@ import java.util.List; import java.util.stream.Collectors; +import com.yoti.api.client.docs.session.retrieve.identityprofile.IdentityProfilePreviewResponse; +import com.yoti.api.client.docs.session.retrieve.identityprofile.IdentityProfileResponse; import com.yoti.api.client.docs.session.retrieve.identityprofile.advanced.AdvancedIdentityProfileResponse; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileFailureResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileFailureResponse.java similarity index 88% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileFailureResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileFailureResponse.java index 8c73a8b0c..f532c3aff 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileFailureResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileFailureResponse.java @@ -1,4 +1,4 @@ -package com.yoti.api.client.docs.session.retrieve; +package com.yoti.api.client.docs.session.retrieve.identityprofile; import java.util.List; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfilePreviewResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfilePreviewResponse.java similarity index 63% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfilePreviewResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfilePreviewResponse.java index fd9698aaa..0874938ca 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfilePreviewResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfilePreviewResponse.java @@ -1,4 +1,6 @@ -package com.yoti.api.client.docs.session.retrieve; +package com.yoti.api.client.docs.session.retrieve.identityprofile; + +import com.yoti.api.client.docs.session.retrieve.MediaResponse; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileReportResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileReportResponse.java similarity index 88% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileReportResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileReportResponse.java index 99cfc60f4..afecc98ca 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileReportResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileReportResponse.java @@ -1,7 +1,9 @@ -package com.yoti.api.client.docs.session.retrieve; +package com.yoti.api.client.docs.session.retrieve.identityprofile; import java.util.List; +import com.yoti.api.client.docs.session.retrieve.MediaResponse; + import com.fasterxml.jackson.annotation.JsonProperty; public class IdentityProfileReportResponse { diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileResponse.java similarity index 91% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileResponse.java index 8cb52cc3c..46c7a1484 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileResponse.java @@ -1,4 +1,4 @@ -package com.yoti.api.client.docs.session.retrieve; +package com.yoti.api.client.docs.session.retrieve.identityprofile; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeComplianceReportResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileSchemeComplianceReportResponse.java similarity index 93% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeComplianceReportResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileSchemeComplianceReportResponse.java index 646886c9b..babcdb91a 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeComplianceReportResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileSchemeComplianceReportResponse.java @@ -1,4 +1,4 @@ -package com.yoti.api.client.docs.session.retrieve; +package com.yoti.api.client.docs.session.retrieve.identityprofile; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileSchemeResponse.java similarity index 88% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileSchemeResponse.java index fe33fceed..d2884f3a4 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdentityProfileSchemeResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/IdentityProfileSchemeResponse.java @@ -1,4 +1,4 @@ -package com.yoti.api.client.docs.session.retrieve; +package com.yoti.api.client.docs.session.retrieve.identityprofile; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/RequirementNotMetDetailsResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/RequirementNotMetDetailsResponse.java similarity index 92% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/RequirementNotMetDetailsResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/RequirementNotMetDetailsResponse.java index 5927ca047..ecbfab8a3 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/RequirementNotMetDetailsResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/RequirementNotMetDetailsResponse.java @@ -1,4 +1,4 @@ -package com.yoti.api.client.docs.session.retrieve; +package com.yoti.api.client.docs.session.retrieve.identityprofile; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/advanced/AdvancedIdentityProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/advanced/AdvancedIdentityProfileResponse.java index 9d1e9c35a..4922dcf1b 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/advanced/AdvancedIdentityProfileResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/identityprofile/advanced/AdvancedIdentityProfileResponse.java @@ -1,6 +1,6 @@ package com.yoti.api.client.docs.session.retrieve.identityprofile.advanced; -import com.yoti.api.client.docs.session.retrieve.IdentityProfileFailureResponse; +import com.yoti.api.client.docs.session.retrieve.identityprofile.IdentityProfileFailureResponse; import com.fasterxml.jackson.annotation.JsonProperty; From f8475dfc77c016d09bd9671b6cc7748445cea184 Mon Sep 17 00:00:00 2001 From: Michael Buck Date: Fri, 5 Dec 2025 09:53:44 +0000 Subject: [PATCH 10/28] SDK-2771: Rename SignedRequest->YotiHttpRequest --- yoti-sdk-api/spotbugs/exclude-filter.xml | 4 +- .../yoti/api/client/docs/DocScanService.java | 74 ++-- .../spi/remote/call/ImageResourceFetcher.java | 10 +- .../spi/remote/call/JsonResourceFetcher.java | 12 +- .../spi/remote/call/ProfileService.java | 22 +- .../spi/remote/call/RawResourceFetcher.java | 12 +- .../spi/remote/call/ResourceFetcher.java | 3 +- ...ignedRequest.java => YotiHttpRequest.java} | 6 +- ...ilder.java => YotiHttpRequestBuilder.java} | 28 +- ...ava => YotiHttpRequestBuilderFactory.java} | 6 +- ...estResponse.java => YotiHttpResponse.java} | 4 +- .../spi/remote/call/aml/RemoteAmlService.java | 20 +- .../call/identity/DigitalIdentityService.java | 18 +- .../call/qrcode/DynamicSharingService.java | 21 +- .../api/client/docs/DocScanServiceTest.java | 319 +++++++++--------- .../remote/call/ImageResourceFetcherTest.java | 20 +- .../remote/call/JsonResourceFetcherTest.java | 22 +- .../spi/remote/call/ProfileServiceTest.java | 27 +- .../remote/call/RawResourceFetcherTest.java | 8 +- ...t.java => YotiHttpRequestBuilderTest.java} | 70 ++-- .../remote/call/aml/RemoteAmlServiceTest.java | 16 +- .../identity/DigitalIdentityServiceTest.java | 52 +-- .../qrcode/DynamicSharingServiceTest.java | 16 +- .../api/client/sandbox/YotiSandboxClient.java | 18 +- .../sandbox/docs/DocScanSandboxClient.java | 20 +- .../client/sandbox/YotiSandboxClientTest.java | 41 +-- .../docs/DocScanSandboxClientTest.java | 57 ++-- 27 files changed, 467 insertions(+), 459 deletions(-) rename yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/{SignedRequest.java => YotiHttpRequest.java} (92%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/{SignedRequestBuilder.java => YotiHttpRequestBuilder.java} (88%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/{SignedRequestBuilderFactory.java => YotiHttpRequestBuilderFactory.java} (80%) rename yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/{SignedRequestResponse.java => YotiHttpResponse.java} (80%) rename yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/{SignedRequestBuilderTest.java => YotiHttpRequestBuilderTest.java} (85%) diff --git a/yoti-sdk-api/spotbugs/exclude-filter.xml b/yoti-sdk-api/spotbugs/exclude-filter.xml index 827443487..af1625f33 100644 --- a/yoti-sdk-api/spotbugs/exclude-filter.xml +++ b/yoti-sdk-api/spotbugs/exclude-filter.xml @@ -27,12 +27,12 @@ - + - + diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java index e586b6b8c..3d0bed70a 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java @@ -34,9 +34,9 @@ import com.yoti.api.client.docs.support.SupportedDocumentsResponse; import com.yoti.api.client.spi.remote.MediaValue; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; -import com.yoti.api.client.spi.remote.call.SignedRequestResponse; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpResponse; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.annotation.JsonInclude; @@ -62,15 +62,15 @@ final class DocScanService { private final UnsignedPathFactory unsignedPathFactory; private final ObjectMapper objectMapper; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String apiUrl; private DocScanService(UnsignedPathFactory pathFactory, ObjectMapper objectMapper, - SignedRequestBuilderFactory signedRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.unsignedPathFactory = pathFactory; this.objectMapper = objectMapper; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; apiUrl = System.getProperty(PROPERTY_YOTI_DOCS_URL, DEFAULT_YOTI_DOCS_URL); } @@ -82,7 +82,7 @@ public static DocScanService newInstance() { objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.registerModule(new JavaTimeModule()); - return new DocScanService(new UnsignedPathFactory(), objectMapper, new SignedRequestBuilderFactory()); + return new DocScanService(new UnsignedPathFactory(), objectMapper, new YotiHttpRequestBuilderFactory()); } /** @@ -105,7 +105,7 @@ public CreateSessionResult createSession(String sdkId, KeyPair keyPair, SessionS try { byte[] payload = objectMapper.writeValueAsBytes(sessionSpec); - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) @@ -114,7 +114,7 @@ public CreateSessionResult createSession(String sdkId, KeyPair keyPair, SessionS .withHeader(CONTENT_TYPE, CONTENT_TYPE_JSON) .build(); - return signedRequest.execute(CreateSessionResult.class); + return yotiHttpRequest.execute(CreateSessionResult.class); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -144,14 +144,14 @@ public GetSessionResult retrieveSession(String sdkId, KeyPair keyPair, String se LOG.info("Fetching session from '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - return signedRequest.execute(GetSessionResult.class); + return yotiHttpRequest.execute(GetSessionResult.class); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -180,14 +180,14 @@ public void deleteSession(String sdkId, KeyPair keyPair, String sessionId) throw LOG.info("Deleting session from '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_DELETE) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -219,13 +219,13 @@ public Media getMediaContent(String sdkId, KeyPair keyPair, String sessionId, St LOG.info("Fetching media from '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - SignedRequestResponse response = signedRequest.execute(); + YotiHttpResponse response = yotiHttpRequest.execute(); if (response.getResponseCode() == HTTP_STATUS_NO_CONTENT) { return null; @@ -259,14 +259,14 @@ public void deleteMediaContent(String sdkId, KeyPair keyPair, String sessionId, LOG.info("Deleting media at '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_DELETE) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -288,7 +288,7 @@ public void putIbvInstructions(String sdkId, KeyPair keyPair, String sessionId, try { byte[] payload = objectMapper.writeValueAsBytes(instructions); - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) @@ -296,7 +296,7 @@ public void putIbvInstructions(String sdkId, KeyPair keyPair, String sessionId, .withPayload(payload) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -315,14 +315,14 @@ public InstructionsResponse getIbvInstructions(String sdkId, KeyPair keyPair, St LOG.info("Fetching IBV instructions at '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - return signedRequest.execute(InstructionsResponse.class); + return yotiHttpRequest.execute(InstructionsResponse.class); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -350,14 +350,14 @@ public ContactProfileResponse fetchInstructionsContactProfile(String sdkId, KeyP LOG.info("Fetching instruction contact profile from '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - return signedRequest.execute(ContactProfileResponse.class); + return yotiHttpRequest.execute(ContactProfileResponse.class); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -376,13 +376,13 @@ public Media getIbvInstructionsPdf(String sdkId, KeyPair keyPair, String session LOG.info("Fetching instructions PDF at '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - SignedRequestResponse response = signedRequest.execute(); + YotiHttpResponse response = yotiHttpRequest.execute(); if (response.getResponseCode() == HTTP_STATUS_NO_CONTENT) { return null; @@ -406,14 +406,14 @@ public SessionConfigurationResponse fetchSessionConfiguration(String sdkId, KeyP LOG.info("Fetching session configuration from '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - return signedRequest.execute(SessionConfigurationResponse.class); + return yotiHttpRequest.execute(SessionConfigurationResponse.class); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -438,7 +438,7 @@ public CreateFaceCaptureResourceResponse createFaceCaptureResource(String sdkId, try { byte[] payload = objectMapper.writeValueAsBytes(createFaceCaptureResourcePayload); - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) @@ -446,7 +446,7 @@ public CreateFaceCaptureResourceResponse createFaceCaptureResource(String sdkId, .withHttpMethod(HTTP_POST) .build(); - return signedRequest.execute(CreateFaceCaptureResourceResponse.class); + return yotiHttpRequest.execute(CreateFaceCaptureResourceResponse.class); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -468,7 +468,7 @@ public void uploadFaceCaptureImage(String sdkId, KeyPair keyPair, String session LOG.info("Uploading image to Face Capture resource at '{}'", path); try { - signedRequestBuilderFactory.create() + yotiHttpRequestBuilderFactory.create() .withMultipartBoundary(YOTI_MULTIPART_BOUNDARY) .withMultipartBinaryBody( "binary-content", @@ -494,14 +494,14 @@ public SupportedDocumentsResponse getSupportedDocuments(KeyPair keyPair, boolean String path = unsignedPathFactory.createGetSupportedDocumentsPath(includeNonLatin); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - return signedRequest.execute(SupportedDocumentsResponse.class); + return yotiHttpRequest.execute(SupportedDocumentsResponse.class); } catch (GeneralSecurityException | ResourceException ex) { throw new DocScanException("Error executing the GET: " + ex.getMessage(), ex); } catch (IOException | URISyntaxException ex) { @@ -518,7 +518,7 @@ public void triggerIbvEmailNotification(String sdkId, KeyPair keyPair, String se LOG.info("Triggering IBV email notification at '{}'", path); try { - signedRequestBuilderFactory.create() + yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) @@ -541,14 +541,14 @@ public List getTrackedDevices(String sdkId, KeyPair keyPair, S LOG.info("Fetching tracked devices at '{}'", path); try { - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - return signedRequest.execute(METADATA_RESPONSE_TYPE_REF); + return yotiHttpRequest.execute(METADATA_RESPONSE_TYPE_REF); } catch (GeneralSecurityException | ResourceException ex) { throw new DocScanException("Error executing the GET: " + ex.getMessage(), ex); } catch (IOException | URISyntaxException ex) { @@ -565,7 +565,7 @@ public void deleteTrackedDevices(String sdkId, KeyPair keyPair, String sessionId LOG.info("Deleting tracked devices at '{}'", path); try { - signedRequestBuilderFactory.create() + yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) @@ -579,7 +579,7 @@ public void deleteTrackedDevices(String sdkId, KeyPair keyPair, String sessionId } } - private String findContentType(SignedRequestResponse response) { + private String findContentType(YotiHttpResponse response) { List contentTypeValues = null; for (Map.Entry> entry : response.getResponseHeaders().entrySet()) { if (entry.getKey() != null && entry.getKey().toLowerCase(Locale.ENGLISH).equals(CONTENT_TYPE.toLowerCase(Locale.ENGLISH))) { diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcher.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcher.java index 236339efa..adb9b4c49 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcher.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcher.java @@ -29,10 +29,10 @@ private ImageResourceFetcher(RawResourceFetcher rawResourceFetcher) { this.rawResourceFetcher = rawResourceFetcher; } - Image doRequest(SignedRequest signedRequest) throws IOException, ResourceException { - SignedRequestResponse signedRequestResponse = rawResourceFetcher.doRequest(signedRequest); - String contentType = getContentType(signedRequestResponse.getResponseHeaders()); - byte[] responseBody = signedRequestResponse.getResponseBody(); + Image doRequest(YotiHttpRequest yotiHttpRequest) throws IOException, ResourceException { + YotiHttpResponse yotiHttpResponse = rawResourceFetcher.doRequest(yotiHttpRequest); + String contentType = getContentType(yotiHttpResponse.getResponseHeaders()); + byte[] responseBody = yotiHttpResponse.getResponseBody(); switch (contentType) { case CONTENT_TYPE_PNG: return new PngAttributeValue(responseBody); @@ -40,7 +40,7 @@ Image doRequest(SignedRequest signedRequest) throws IOException, ResourceExcepti return new JpegAttributeValue(responseBody); default: LOG.error("Failed to convert image of type: (" + contentType + ")"); - throw new ResourceException(signedRequestResponse.getResponseCode(), "Failed to convert image of type: (" + contentType + ")", null); + throw new ResourceException(yotiHttpResponse.getResponseCode(), "Failed to convert image of type: (" + contentType + ")", null); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcher.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcher.java index 7f8423823..434baf0d6 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcher.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcher.java @@ -36,14 +36,14 @@ private JsonResourceFetcher(ObjectMapper objectMapper, } @Override - public T doRequest(SignedRequest signedRequest, Class resourceClass) throws ResourceException, IOException { - SignedRequestResponse signedRequestResponse = rawResourceFetcher.doRequest(signedRequest); - return objectMapper.readValue(signedRequestResponse.getResponseBody(), resourceClass); + public T doRequest(YotiHttpRequest yotiHttpRequest, Class resourceClass) throws ResourceException, IOException { + YotiHttpResponse yotiHttpResponse = rawResourceFetcher.doRequest(yotiHttpRequest); + return objectMapper.readValue(yotiHttpResponse.getResponseBody(), resourceClass); } - public T doRequest(SignedRequest signedRequest, TypeReference resourceClass) throws ResourceException, IOException { - SignedRequestResponse signedRequestResponse = rawResourceFetcher.doRequest(signedRequest); - return objectMapper.readValue(signedRequestResponse.getResponseBody(), resourceClass); + public T doRequest(YotiHttpRequest yotiHttpRequest, TypeReference resourceClass) throws ResourceException, IOException { + YotiHttpResponse yotiHttpResponse = rawResourceFetcher.doRequest(yotiHttpRequest); + return objectMapper.readValue(yotiHttpResponse.getResponseBody(), resourceClass); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java index fb2e5ecca..3aa6915c2 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java @@ -29,7 +29,7 @@ public class ProfileService { private static final Logger LOG = LoggerFactory.getLogger(ProfileService.class); private final UnsignedPathFactory unsignedPathFactory; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String apiUrl; static { @@ -39,12 +39,12 @@ public class ProfileService { public static ProfileService newInstance() { return new ProfileService( new UnsignedPathFactory(), - new SignedRequestBuilderFactory()); + new YotiHttpRequestBuilderFactory()); } - ProfileService(UnsignedPathFactory profilePathFactory, SignedRequestBuilderFactory signedRequestBuilderFactory) { + ProfileService(UnsignedPathFactory profilePathFactory, YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.unsignedPathFactory = profilePathFactory; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; apiUrl = System.getProperty(PROPERTY_YOTI_API_URL, DEFAULT_YOTI_API_URL); } @@ -63,18 +63,18 @@ public ProfileResponse getProfile(KeyPair keyPair, String appId, String connectT try { String authKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); - SignedRequest signedRequest = createSignedRequest(keyPair, path, authKey); - return fetchReceipt(signedRequest); + YotiHttpRequest yotiHttpRequest = createSignedRequest(keyPair, path, authKey); + return fetchReceipt(yotiHttpRequest); } catch (IOException ioe) { throw new ProfileException("Error calling service to get profile", ioe); } } - private ProfileResponse fetchReceipt(SignedRequest signedRequest) throws IOException, ProfileException { - LOG.info("Fetching profile from resource at '{}'", signedRequest.getUri()); + private ProfileResponse fetchReceipt(YotiHttpRequest yotiHttpRequest) throws IOException, ProfileException { + LOG.info("Fetching profile from resource at '{}'", yotiHttpRequest.getUri()); try { - return signedRequest.execute(ProfileResponse.class); + return yotiHttpRequest.execute(ProfileResponse.class); } catch (ResourceException ex) { int responseCode = ex.getResponseCode(); switch (responseCode) { @@ -88,9 +88,9 @@ private ProfileResponse fetchReceipt(SignedRequest signedRequest) throws IOExcep } } - SignedRequest createSignedRequest(KeyPair keyPair, String path, String authKey) throws ProfileException { + YotiHttpRequest createSignedRequest(KeyPair keyPair, String path, String authKey) throws ProfileException { try { - return signedRequestBuilderFactory.create() + return yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/RawResourceFetcher.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/RawResourceFetcher.java index 520898460..4838fbd66 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/RawResourceFetcher.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/RawResourceFetcher.java @@ -22,12 +22,12 @@ private static Scanner createScanner(InputStream inputStream) { return new Scanner(inputStream, DEFAULT_CHARSET).useDelimiter("\\A"); } - public SignedRequestResponse doRequest(SignedRequest signedRequest) throws IOException, ResourceException { - UrlConnector urlConnector = UrlConnector.get(signedRequest.getUri().toString()); - return doRequest(urlConnector, signedRequest.getMethod(), signedRequest.getData(), signedRequest.getHeaders()); + public YotiHttpResponse doRequest(YotiHttpRequest yotiHttpRequest) throws IOException, ResourceException { + UrlConnector urlConnector = UrlConnector.get(yotiHttpRequest.getUri().toString()); + return doRequest(urlConnector, yotiHttpRequest.getMethod(), yotiHttpRequest.getData(), yotiHttpRequest.getHeaders()); } - public SignedRequestResponse doRequest(UrlConnector urlConnector, String method, byte[] data, Map headers) + public YotiHttpResponse doRequest(UrlConnector urlConnector, String method, byte[] data, Map headers) throws IOException, ResourceException { HttpURLConnection httpUrlConnection = openConnection(urlConnector, method, headers); sendBody(data, httpUrlConnection); @@ -89,13 +89,13 @@ private void sendBody(byte[] body, HttpURLConnection httpUrlConnection) throws I * @throws ResourceException * @throws IOException */ - private SignedRequestResponse parseResponse(HttpURLConnection httpUrlConnection) throws ResourceException, IOException { + private YotiHttpResponse parseResponse(HttpURLConnection httpUrlConnection) throws ResourceException, IOException { int responseCode = httpUrlConnection.getResponseCode(); if (responseCode >= HttpURLConnection.HTTP_BAD_REQUEST) { String responseBody = readError(httpUrlConnection); throw new ResourceException(responseCode, httpUrlConnection.getResponseMessage(), responseBody); } - return new SignedRequestResponse(responseCode, readBody(httpUrlConnection), httpUrlConnection.getHeaderFields()); + return new YotiHttpResponse(responseCode, readBody(httpUrlConnection), httpUrlConnection.getHeaderFields()); } /** diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ResourceFetcher.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ResourceFetcher.java index d88166020..0de4d0e1d 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ResourceFetcher.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ResourceFetcher.java @@ -1,10 +1,9 @@ package com.yoti.api.client.spi.remote.call; import java.io.IOException; -import java.util.Map; public interface ResourceFetcher { - T doRequest(SignedRequest signedRequest, Class resourceClass) throws ResourceException, IOException; + T doRequest(YotiHttpRequest yotiHttpRequest, Class resourceClass) throws ResourceException, IOException; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequest.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequest.java similarity index 92% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequest.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequest.java index b971c050c..97649a0f4 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequest.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequest.java @@ -8,7 +8,7 @@ import com.fasterxml.jackson.core.type.TypeReference; -public class SignedRequest { +public class YotiHttpRequest { private final URI uri; private final String method; @@ -18,7 +18,7 @@ public class SignedRequest { private final RawResourceFetcher rawResourceFetcher; private final ImageResourceFetcher imageResourceFetcher; - SignedRequest(final URI uri, + YotiHttpRequest(final URI uri, final String method, final byte[] data, final Map headers, @@ -62,7 +62,7 @@ public T execute(TypeReference typeReference) throws ResourceException, I return jsonResourceFetcher.doRequest(this, typeReference); } - public SignedRequestResponse execute() throws ResourceException, IOException { + public YotiHttpResponse execute() throws ResourceException, IOException { return rawResourceFetcher.doRequest(this); } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilder.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java similarity index 88% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilder.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java index 64da85845..c742c636c 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilder.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java @@ -25,7 +25,7 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; -public class SignedRequestBuilder { +public class YotiHttpRequestBuilder { private KeyPair keyPair; private String baseUrl; @@ -43,7 +43,7 @@ public class SignedRequestBuilder { private final ImageResourceFetcher imageResourceFetcher; private MultipartEntityBuilder multipartEntityBuilder; - SignedRequestBuilder(PathFactory pathFactory, + YotiHttpRequestBuilder(PathFactory pathFactory, SignedMessageFactory signedMessageFactory, HeadersFactory headersFactory, JsonResourceFetcher jsonResourceFetcher, @@ -63,7 +63,7 @@ public class SignedRequestBuilder { * @param keyPair the key pair * @return the updated builder */ - public SignedRequestBuilder withKeyPair(KeyPair keyPair) { + public YotiHttpRequestBuilder withKeyPair(KeyPair keyPair) { this.keyPair = keyPair; return this; } @@ -74,7 +74,7 @@ public SignedRequestBuilder withKeyPair(KeyPair keyPair) { * @param baseUrl the base url * @return the updated builder */ - public SignedRequestBuilder withBaseUrl(String baseUrl) { + public YotiHttpRequestBuilder withBaseUrl(String baseUrl) { this.baseUrl = baseUrl.replaceAll("([/]+)$", ""); return this; } @@ -85,7 +85,7 @@ public SignedRequestBuilder withBaseUrl(String baseUrl) { * @param endpoint the endpoint * @return the updated builder */ - public SignedRequestBuilder withEndpoint(String endpoint) { + public YotiHttpRequestBuilder withEndpoint(String endpoint) { this.endpoint = endpoint; return this; } @@ -96,7 +96,7 @@ public SignedRequestBuilder withEndpoint(String endpoint) { * @param payload the payload * @return the update builder */ - public SignedRequestBuilder withPayload(byte[] payload) { + public YotiHttpRequestBuilder withPayload(byte[] payload) { this.multipartEntityBuilder = null; this.payload = payload; return this; @@ -109,7 +109,7 @@ public SignedRequestBuilder withPayload(byte[] payload) { * @param value the value of the query parameter * @return the updated builder */ - public SignedRequestBuilder withQueryParameter(String name, String value) { + public YotiHttpRequestBuilder withQueryParameter(String name, String value) { this.queryParameters.put(name, value); return this; } @@ -121,7 +121,7 @@ public SignedRequestBuilder withQueryParameter(String name, String value) { * @param value the value of the header * @return the updated builder */ - public SignedRequestBuilder withHeader(String name, String value) { + public YotiHttpRequestBuilder withHeader(String name, String value) { this.headers.put(name, value); return this; } @@ -132,13 +132,13 @@ public SignedRequestBuilder withHeader(String name, String value) { * @param httpMethod the HTTP method * @return the updated builder */ - public SignedRequestBuilder withHttpMethod(String httpMethod) throws IllegalArgumentException { + public YotiHttpRequestBuilder withHttpMethod(String httpMethod) throws IllegalArgumentException { Validation.withinList(httpMethod, SUPPORTED_HTTP_METHODS); this.httpMethod = httpMethod; return this; } - private SignedRequestBuilder forMultipartRequest() { + private YotiHttpRequestBuilder forMultipartRequest() { if (this.multipartEntityBuilder == null) { this.multipartEntityBuilder = MultipartEntityBuilder.create(); } @@ -152,7 +152,7 @@ private SignedRequestBuilder forMultipartRequest() { * @param multipartBoundary the multipart boundary * @return the updated builder */ - public SignedRequestBuilder withMultipartBoundary(String multipartBoundary) { + public YotiHttpRequestBuilder withMultipartBoundary(String multipartBoundary) { Validation.notNullOrEmpty(multipartBoundary, "multipartBoundary"); forMultipartRequest(); multipartEntityBuilder.setBoundary(multipartBoundary); @@ -171,7 +171,7 @@ public SignedRequestBuilder withMultipartBoundary(String multipartBoundary) { * @param fileName the filename of the binary body * @return the updated builder */ - public SignedRequestBuilder withMultipartBinaryBody(String name, byte[] payload, ContentType contentType, String fileName) { + public YotiHttpRequestBuilder withMultipartBinaryBody(String name, byte[] payload, ContentType contentType, String fileName) { Validation.notNullOrEmpty(name, "name"); Validation.notNull(payload, "payload"); Validation.notNull(contentType, "contentType"); @@ -186,7 +186,7 @@ public SignedRequestBuilder withMultipartBinaryBody(String name, byte[] payload, * * @return the signed request */ - public SignedRequest build() throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { + public YotiHttpRequest build() throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { validateRequest(); if (endpoint.contains("?")) { @@ -216,7 +216,7 @@ public SignedRequest build() throws GeneralSecurityException, UnsupportedEncodin String digest = createDigest(builtEndpoint, finalPayload); headers.putAll(headersFactory.create(digest)); - return new SignedRequest( + return new YotiHttpRequest( new URI(baseUrl + builtEndpoint), httpMethod, finalPayload, diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilderFactory.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java similarity index 80% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilderFactory.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java index 54f826865..e97285211 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilderFactory.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java @@ -4,7 +4,7 @@ import com.yoti.api.client.spi.remote.call.factory.PathFactory; import com.yoti.api.client.spi.remote.call.factory.SignedMessageFactory; -public class SignedRequestBuilderFactory { +public class YotiHttpRequestBuilderFactory { private static final PathFactory pathFactory; private static final SignedMessageFactory signedMessageFactory; @@ -22,8 +22,8 @@ public class SignedRequestBuilderFactory { imageResourceFetcher = ImageResourceFetcher.newInstance(rawResourceFetcher); } - public SignedRequestBuilder create() { - return new SignedRequestBuilder(pathFactory, signedMessageFactory, headersFactory, jsonResourceFetcher, rawResourceFetcher, imageResourceFetcher); + public YotiHttpRequestBuilder create() { + return new YotiHttpRequestBuilder(pathFactory, signedMessageFactory, headersFactory, jsonResourceFetcher, rawResourceFetcher, imageResourceFetcher); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpResponse.java similarity index 80% rename from yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestResponse.java rename to yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpResponse.java index bcad72eaf..120755cff 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/SignedRequestResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpResponse.java @@ -3,13 +3,13 @@ import java.util.List; import java.util.Map; -public class SignedRequestResponse { +public class YotiHttpResponse { private final int responseCode; private final byte[] responseBody; private final Map> responseHeaders; - public SignedRequestResponse(int responseCode, byte[] responseBody, Map> responseHeaders) { + public YotiHttpResponse(int responseCode, byte[] responseBody, Map> responseHeaders) { this.responseCode = responseCode; this.responseBody = responseBody.clone(); this.responseHeaders = responseHeaders; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java index 033bca436..7ecbc3741 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java @@ -20,8 +20,8 @@ import com.yoti.api.client.aml.AmlProfile; import com.yoti.api.client.aml.AmlResult; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.databind.ObjectMapper; @@ -30,23 +30,23 @@ public class RemoteAmlService { private final UnsignedPathFactory unsignedPathFactory; private final ObjectMapper objectMapper; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String apiUrl; public static RemoteAmlService newInstance() { return new RemoteAmlService( new UnsignedPathFactory(), new ObjectMapper(), - new SignedRequestBuilderFactory() + new YotiHttpRequestBuilderFactory() ); } RemoteAmlService(UnsignedPathFactory unsignedPathFactory, ObjectMapper objectMapper, - SignedRequestBuilderFactory signedRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.unsignedPathFactory = unsignedPathFactory; this.objectMapper = objectMapper; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; apiUrl = System.getProperty(PROPERTY_YOTI_API_URL, DEFAULT_YOTI_API_URL); } @@ -60,8 +60,8 @@ public AmlResult performCheck(KeyPair keyPair, String appId, AmlProfile amlProfi String resourcePath = unsignedPathFactory.createAmlPath(appId); byte[] body = objectMapper.writeValueAsString(amlProfile).getBytes(DEFAULT_CHARSET); - SignedRequest signedRequest = createSignedRequest(keyPair, resourcePath, body); - return signedRequest.execute(AmlResult.class); + YotiHttpRequest yotiHttpRequest = createSignedRequest(keyPair, resourcePath, body); + return yotiHttpRequest.execute(AmlResult.class); } catch (IOException ioException) { throw new AmlException("Error communicating with AML endpoint", ioException); } catch (ResourceException resourceException) { @@ -82,9 +82,9 @@ private AmlException createExceptionFromStatusCode(ResourceException e) { } } - SignedRequest createSignedRequest(KeyPair keyPair, String resourcePath, byte[] body) throws AmlException { + YotiHttpRequest createSignedRequest(KeyPair keyPair, String resourcePath, byte[] body) throws AmlException { try { - return signedRequestBuilderFactory.create() + return yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(resourcePath) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java index b79178c00..5c0bb9450 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java @@ -22,9 +22,9 @@ import com.yoti.api.client.identity.ShareSessionQrCode; import com.yoti.api.client.identity.ShareSessionRequest; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilder; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.yoti.json.ResourceMapper; import com.yoti.validation.Validation; @@ -39,14 +39,14 @@ public class DigitalIdentityService { private static final byte[] EMPTY_JSON = "{}".getBytes(StandardCharsets.UTF_8); private final UnsignedPathFactory pathFactory; - private final SignedRequestBuilderFactory requestBuilderFactory; + private final YotiHttpRequestBuilderFactory requestBuilderFactory; private final ReceiptParser receiptParser; private final String apiUrl; public DigitalIdentityService( UnsignedPathFactory pathFactory, - SignedRequestBuilderFactory requestBuilderFactory, + YotiHttpRequestBuilderFactory requestBuilderFactory, ReceiptParser receiptParser) { this.pathFactory = pathFactory; this.requestBuilderFactory = requestBuilderFactory; @@ -58,7 +58,7 @@ public DigitalIdentityService( public static DigitalIdentityService newInstance() { return new DigitalIdentityService( new UnsignedPathFactory(), - new SignedRequestBuilderFactory(), + new YotiHttpRequestBuilderFactory(), ReceiptParser.newInstance() ); } @@ -215,14 +215,14 @@ public MatchResult fetchMatch(String sdkId, KeyPair keyPair, MatchRequest matchR } } - SignedRequest createSignedRequest(String sdkId, KeyPair keyPair, String path) + YotiHttpRequest createSignedRequest(String sdkId, KeyPair keyPair, String path) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { return createSignedRequest(sdkId, keyPair, path, HTTP_GET, null); } - SignedRequest createSignedRequest(String sdkId, KeyPair keyPair, String path, String method, byte[] payload) + YotiHttpRequest createSignedRequest(String sdkId, KeyPair keyPair, String path, String method, byte[] payload) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { - SignedRequestBuilder request = requestBuilderFactory.create() + YotiHttpRequestBuilder request = requestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java index fc9b47422..acc452140 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java @@ -15,9 +15,8 @@ import com.yoti.api.client.shareurl.DynamicShareException; import com.yoti.api.client.shareurl.ShareUrlResult; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilder; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.databind.ObjectMapper; @@ -30,7 +29,7 @@ public static DynamicSharingService newInstance() { return new DynamicSharingService( new UnsignedPathFactory(), new ObjectMapper(), - new SignedRequestBuilderFactory() + new YotiHttpRequestBuilderFactory() ); } @@ -38,16 +37,16 @@ public static DynamicSharingService newInstance() { private final UnsignedPathFactory unsignedPathFactory; private final ObjectMapper objectMapper; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String apiUrl; DynamicSharingService(UnsignedPathFactory unsignedPathFactory, ObjectMapper objectMapper, - SignedRequestBuilderFactory signedRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.unsignedPathFactory = unsignedPathFactory; this.objectMapper = objectMapper; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; apiUrl = System.getProperty(PROPERTY_YOTI_API_URL, DEFAULT_YOTI_API_URL); } @@ -63,9 +62,9 @@ public ShareUrlResult createShareUrl(String appId, KeyPair keyPair, DynamicScena try { byte[] body = objectMapper.writeValueAsString(dynamicScenario).getBytes(DEFAULT_CHARSET); - SignedRequest signedRequest = createSignedRequest(keyPair, path, body); + YotiHttpRequest yotiHttpRequest = createSignedRequest(keyPair, path, body); - return signedRequest.execute(ShareUrlResult.class); + return yotiHttpRequest.execute(ShareUrlResult.class); } catch (ResourceException ex) { throw new DynamicShareException("Error posting the request: ", ex); } catch (IOException ex) { @@ -73,9 +72,9 @@ public ShareUrlResult createShareUrl(String appId, KeyPair keyPair, DynamicScena } } - SignedRequest createSignedRequest(KeyPair keyPair, String path, byte[] body) throws DynamicShareException { + YotiHttpRequest createSignedRequest(KeyPair keyPair, String path, byte[] body) throws DynamicShareException { try { - return signedRequestBuilderFactory.create() + return yotiHttpRequestBuilderFactory.create() .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java index a945140fb..0dba44137 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java @@ -11,7 +11,6 @@ import static junit.framework.TestCase.assertSame; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.any; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; @@ -54,10 +53,10 @@ import com.yoti.api.client.docs.support.SupportedDocumentsResponse; import com.yoti.api.client.spi.remote.call.HttpMethod; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilder; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; -import com.yoti.api.client.spi.remote.call.SignedRequestResponse; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpResponse; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.core.type.TypeReference; @@ -93,10 +92,10 @@ public class DocScanServiceTest { @Mock UnsignedPathFactory unsignedPathFactoryMock; @Mock ObjectMapper objectMapperMock; - @Mock SignedRequest signedRequestMock; - @Mock(answer = Answers.RETURNS_SELF) SignedRequestBuilder signedRequestBuilderMock; - @Mock SignedRequestResponse signedRequestResponseMock; - @Mock SignedRequestBuilderFactory signedRequestBuilderFactoryMock; + @Mock YotiHttpRequest yotiHttpRequestMock; + @Mock(answer = Answers.RETURNS_SELF) YotiHttpRequestBuilder yotiHttpRequestBuilderMock; + @Mock YotiHttpResponse yotiHttpResponseMock; + @Mock YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactoryMock; @Mock SupportedDocumentsResponse supportedDocumentsResponseMock; @Mock Instructions instructionsMock; @Mock CreateFaceCaptureResourcePayload createFaceCaptureResourcePayloadMock; @@ -109,7 +108,7 @@ public static void setUpClass() throws Exception { @Before public void setUp() { - when(signedRequestBuilderFactoryMock.create()).thenReturn(signedRequestBuilderMock); + when(yotiHttpRequestBuilderFactoryMock.create()).thenReturn(yotiHttpRequestBuilderMock); } @Test @@ -137,7 +136,7 @@ public void createSession_shouldThrowExceptionWhenMissingSessionSpec() { public void createSession_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); SessionSpec sessionSpecMock = mock(SessionSpec.class); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); @@ -149,8 +148,8 @@ public void createSession_shouldWrapGeneralSecurityException() throws Exception public void createSession_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); SessionSpec sessionSpecMock = mock(SessionSpec.class); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(CreateSessionResult.class)).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(CreateSessionResult.class)).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); @@ -162,8 +161,8 @@ public void createSession_shouldWrapResourceException() throws Exception { public void createSession_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); SessionSpec sessionSpecMock = mock(SessionSpec.class); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(CreateSessionResult.class)).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(CreateSessionResult.class)).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); @@ -175,7 +174,7 @@ public void createSession_shouldWrapIOException() throws Exception { public void createSession_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); SessionSpec sessionSpecMock = mock(SessionSpec.class); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); @@ -188,7 +187,7 @@ public void createSession_shouldWrapURISyntaxException() throws Exception { public void createSession_shouldWrapGeneralException() { Exception someException = new Exception("Some exception we weren't expecting"); SessionSpec sessionSpecMock = mock(SessionSpec.class); - doAnswer(i -> {throw someException;}).when(signedRequestBuilderFactoryMock).create(); + doAnswer(i -> {throw someException;}).when(yotiHttpRequestBuilderFactoryMock).create(); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); @@ -201,19 +200,19 @@ public void createSession_shouldCallSignedRequestBuilderWithCorrectMethods() thr SessionSpec sessionSpecMock = mock(SessionSpec.class); CreateSessionResult createSessionResultMock = mock(CreateSessionResult.class); when(objectMapperMock.writeValueAsBytes(sessionSpecMock)).thenReturn(SOME_SESSION_SPEC_BYTES); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(CreateSessionResult.class)).thenReturn(createSessionResultMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(CreateSessionResult.class)).thenReturn(createSessionResultMock); when(unsignedPathFactoryMock.createNewYotiDocsSessionPath(SOME_APP_ID)).thenReturn(SOME_PATH); CreateSessionResult result = docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock); assertThat(result, is(createSessionResultMock)); - verify(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_POST); - verify(signedRequestBuilderMock).withPayload(SOME_SESSION_SPEC_BYTES); - verify(signedRequestBuilderMock).withHeader(CONTENT_TYPE, CONTENT_TYPE_JSON); + verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_POST); + verify(yotiHttpRequestBuilderMock).withPayload(SOME_SESSION_SPEC_BYTES); + verify(yotiHttpRequestBuilderMock).withHeader(CONTENT_TYPE, CONTENT_TYPE_JSON); } @Test @@ -254,7 +253,7 @@ public void retrieveSession_shouldThrowExceptionWhenSessionIdIsEmpty() { @Test public void retrieveSession_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -265,8 +264,8 @@ public void retrieveSession_shouldWrapGeneralSecurityException() throws Exceptio @Test public void retrieveSession_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(GetSessionResult.class)).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(GetSessionResult.class)).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -277,8 +276,8 @@ public void retrieveSession_shouldWrapResourceException() throws Exception { @Test public void retrieveSession_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(GetSessionResult.class)).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(GetSessionResult.class)).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -289,7 +288,7 @@ public void retrieveSession_shouldWrapIOException() throws Exception { @Test public void retrieveSession_shouldWrapGeneralException() { Exception someException = new Exception("Some exception we weren't expecting"); - doAnswer(i -> {throw someException;}).when(signedRequestBuilderFactoryMock).create(); + doAnswer(i -> {throw someException;}).when(yotiHttpRequestBuilderFactoryMock).create(); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -300,17 +299,17 @@ public void retrieveSession_shouldWrapGeneralException() { @Test public void retrieveSession_shouldCallSignedRequestBuilderWithCorrectMethods() throws Exception { GetSessionResult docScanSessionResponseMock = mock(GetSessionResult.class); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(GetSessionResult.class)).thenReturn(docScanSessionResponseMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(GetSessionResult.class)).thenReturn(docScanSessionResponseMock); when(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); GetSessionResult result = docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); assertThat(result, is(docScanSessionResponseMock)); - verify(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_GET); + verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_GET); } @Test @@ -351,7 +350,7 @@ public void deleteSession_shouldThrowExceptionWhenSessionIdIsEmpty() { @Test public void deleteSession_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -362,8 +361,8 @@ public void deleteSession_shouldWrapGeneralSecurityException() throws Exception @Test public void deleteSession_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -374,8 +373,8 @@ public void deleteSession_shouldWrapResourceException() throws Exception { @Test public void deleteSession_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -386,7 +385,7 @@ public void deleteSession_shouldWrapIOException() throws Exception { @Test public void deleteSession_shouldWrapGeneralException() { Exception someException = new Exception("Some exception we weren't expecting"); - doAnswer(i -> {throw someException;}).when(signedRequestBuilderFactoryMock).create(); + doAnswer(i -> {throw someException;}).when(yotiHttpRequestBuilderFactoryMock).create(); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -396,15 +395,15 @@ public void deleteSession_shouldWrapGeneralException() { @Test public void deleteSession_shouldBuildSignedRequest() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); - verify(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); + verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); } @Test @@ -459,7 +458,7 @@ public void getMediaContent_shouldThrowExceptionWhenMediaIdIsEmpty() { @Test public void getMediaContent_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -470,8 +469,8 @@ public void getMediaContent_shouldWrapGeneralSecurityException() throws Exceptio @Test public void getMediaContent_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -482,8 +481,8 @@ public void getMediaContent_shouldWrapResourceException() throws Exception { @Test public void getMediaContent_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -494,7 +493,7 @@ public void getMediaContent_shouldWrapIOException() throws Exception { @Test public void getMediaContent_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -504,25 +503,25 @@ public void getMediaContent_shouldWrapURISyntaxException() throws Exception { @Test public void getMediaContent_shouldBuildSignedRequest() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - SignedRequestResponse signedRequestResponseMock = mock(SignedRequestResponse.class, RETURNS_DEEP_STUBS); - when(signedRequestMock.execute()).thenReturn(signedRequestResponseMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + YotiHttpResponse yotiHttpResponseMock = mock(YotiHttpResponse.class, RETURNS_DEEP_STUBS); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); - verify(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_GET); + verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_GET); } @Test public void getMediaContent_shouldReturnMedia() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenReturn(signedRequestResponseMock); - when(signedRequestResponseMock.getResponseHeaders()).thenReturn(createHeadersMap(CONTENT_TYPE, CONTENT_TYPE_JSON)); - when(signedRequestResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + when(yotiHttpResponseMock.getResponseHeaders()).thenReturn(createHeadersMap(CONTENT_TYPE, CONTENT_TYPE_JSON)); + when(yotiHttpResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); Media result = docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); @@ -533,9 +532,9 @@ public void getMediaContent_shouldReturnMedia() throws Exception { @Test public void getMediaContent_shouldReturnNullForNoContent() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenReturn(signedRequestResponseMock); - when(signedRequestResponseMock.getResponseCode()).thenReturn(204); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + when(yotiHttpResponseMock.getResponseCode()).thenReturn(204); when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); Media result = docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); @@ -545,10 +544,10 @@ public void getMediaContent_shouldReturnNullForNoContent() throws Exception { @Test public void getMediaContent_shouldNotBeCaseSensitive() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenReturn(signedRequestResponseMock); - when(signedRequestResponseMock.getResponseHeaders()).thenReturn(createHeadersMap("content-type", "image/png")); - when(signedRequestResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + when(yotiHttpResponseMock.getResponseHeaders()).thenReturn(createHeadersMap("content-type", "image/png")); + when(yotiHttpResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); Media result = docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); @@ -615,7 +614,7 @@ public void deleteMediaContent_shouldThrowExceptionWhenMediaIdIsEmpty() { @Test public void deleteMediaContent_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -626,8 +625,8 @@ public void deleteMediaContent_shouldWrapGeneralSecurityException() throws Excep @Test public void deleteMediaContent_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -638,8 +637,8 @@ public void deleteMediaContent_shouldWrapResourceException() throws Exception { @Test public void deleteMediaContent_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -650,7 +649,7 @@ public void deleteMediaContent_shouldWrapIOException() throws Exception { @Test public void deleteMediaContent_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -660,15 +659,15 @@ public void deleteMediaContent_shouldWrapURISyntaxException() throws Exception { @Test public void deleteMediaContent_shouldBuildSignedRequest() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); - verify(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); + verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); } @Test @@ -738,7 +737,7 @@ public void putIbvInstructions_shouldThrowExceptionWhenInstructionsIsNull() { @Test public void putIbvInstructions_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); @@ -748,8 +747,8 @@ public void putIbvInstructions_shouldWrapGeneralSecurityException() throws Excep @Test public void putIbvInstructions_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); @@ -759,8 +758,8 @@ public void putIbvInstructions_shouldWrapResourceException() throws Exception { @Test public void putIbvInstructions_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); @@ -770,7 +769,7 @@ public void putIbvInstructions_shouldWrapIOException() throws Exception { @Test public void putIbvInstructions_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); @@ -815,7 +814,7 @@ public void getIbvInstructions_shouldThrowExceptionWhenSessionIdIsEmpty() { @Test public void getIbvInstructions_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -825,8 +824,8 @@ public void getIbvInstructions_shouldWrapGeneralSecurityException() throws Excep @Test public void getIbvInstructions_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(InstructionsResponse.class)).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(InstructionsResponse.class)).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -836,8 +835,8 @@ public void getIbvInstructions_shouldWrapResourceException() throws Exception { @Test public void getIbvInstructions_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(InstructionsResponse.class)).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(InstructionsResponse.class)).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -847,7 +846,7 @@ public void getIbvInstructions_shouldWrapIOException() throws Exception { @Test public void getIbvInstructions_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -892,7 +891,7 @@ public void getIbvInstructionsPdf_shouldThrowExceptionWhenSessionIdIsEmpty() { @Test public void getIbvInstructionsPdf_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -902,8 +901,8 @@ public void getIbvInstructionsPdf_shouldWrapGeneralSecurityException() throws Ex @Test public void getIbvInstructionsPdf_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -913,8 +912,8 @@ public void getIbvInstructionsPdf_shouldWrapResourceException() throws Exception @Test public void getIbvInstructionsPdf_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -924,7 +923,7 @@ public void getIbvInstructionsPdf_shouldWrapIOException() throws Exception { @Test public void getIbvInstructionsPdf_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -933,10 +932,10 @@ public void getIbvInstructionsPdf_shouldWrapURISyntaxException() throws Exceptio @Test public void getIbvInstructionsPdf_shouldReturnMedia() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenReturn(signedRequestResponseMock); - when(signedRequestResponseMock.getResponseHeaders()).thenReturn(createHeadersMap(CONTENT_TYPE, CONTENT_TYPE_JSON)); - when(signedRequestResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + when(yotiHttpResponseMock.getResponseHeaders()).thenReturn(createHeadersMap(CONTENT_TYPE, CONTENT_TYPE_JSON)); + when(yotiHttpResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); when(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); Media result = docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); @@ -947,9 +946,9 @@ public void getIbvInstructionsPdf_shouldReturnMedia() throws Exception { @Test public void getIbvInstructionsPdf_shouldReturnNullForNoContent() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenReturn(signedRequestResponseMock); - when(signedRequestResponseMock.getResponseCode()).thenReturn(204); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + when(yotiHttpResponseMock.getResponseCode()).thenReturn(204); when(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); Media result = docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); @@ -995,7 +994,7 @@ public void fetchInstructionsContactProfile_shouldThrowExceptionWhenSessionIdIsE @Test public void fetchInstructionsContactProfile_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1005,8 +1004,8 @@ public void fetchInstructionsContactProfile_shouldWrapGeneralSecurityException() @Test public void fetchInstructionsContactProfile_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(ContactProfileResponse.class)).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(ContactProfileResponse.class)).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1016,8 +1015,8 @@ public void fetchInstructionsContactProfile_shouldWrapResourceException() throws @Test public void fetchInstructionsContactProfile_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(ContactProfileResponse.class)).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(ContactProfileResponse.class)).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1027,7 +1026,7 @@ public void fetchInstructionsContactProfile_shouldWrapIOException() throws Excep @Test public void fetchInstructionsContactProfile_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1072,7 +1071,7 @@ public void fetchSessionConfiguration_shouldThrowExceptionWhenSessionIdIsEmpty() @Test public void fetchSessionConfiguration_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1082,8 +1081,8 @@ public void fetchSessionConfiguration_shouldWrapGeneralSecurityException() throw @Test public void fetchSessionConfiguration_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(SessionConfigurationResponse.class)).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(SessionConfigurationResponse.class)).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1093,8 +1092,8 @@ public void fetchSessionConfiguration_shouldWrapResourceException() throws Excep @Test public void fetchSessionConfiguration_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(SessionConfigurationResponse.class)).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(SessionConfigurationResponse.class)).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1104,7 +1103,7 @@ public void fetchSessionConfiguration_shouldWrapIOException() throws Exception { @Test public void fetchSessionConfiguration_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1156,7 +1155,7 @@ public void createFaceCaptureResource_shouldThrowExceptionWhenPayloadIsNull() { @Test public void createFaceCaptureResource_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); @@ -1166,8 +1165,8 @@ public void createFaceCaptureResource_shouldWrapGeneralSecurityException() throw @Test public void createFaceCaptureResource_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(CreateFaceCaptureResourceResponse.class)).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(CreateFaceCaptureResourceResponse.class)).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); @@ -1177,8 +1176,8 @@ public void createFaceCaptureResource_shouldWrapResourceException() throws Excep @Test public void createFaceCaptureResource_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(CreateFaceCaptureResourceResponse.class)).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(CreateFaceCaptureResourceResponse.class)).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); @@ -1188,7 +1187,7 @@ public void createFaceCaptureResource_shouldWrapIOException() throws Exception { @Test public void createFaceCaptureResource_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); @@ -1257,7 +1256,7 @@ public void uploadFaceCaptureImage_shouldWrapGeneralSecurityException() throws E when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); @@ -1271,7 +1270,7 @@ public void uploadFaceCaptureImage_shouldWrapURISyntaxException() throws Excepti when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); @@ -1285,8 +1284,8 @@ public void uploadFaceCaptureImage_shouldWrapIOException() throws Exception { when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); IOException ioException = new IOException("some IO exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); @@ -1300,8 +1299,8 @@ public void uploadFaceCaptureImage_shouldWrapResourceException() throws Exceptio when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); @@ -1347,7 +1346,7 @@ public void triggerIbvEmailNotification_shouldThrowExceptionWhenSessionIdIsEmpty @Test public void triggerIbvEmailNotification_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1357,8 +1356,8 @@ public void triggerIbvEmailNotification_shouldWrapGeneralSecurityException() thr @Test public void triggerIbvEmailNotification_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1368,8 +1367,8 @@ public void triggerIbvEmailNotification_shouldWrapResourceException() throws Exc @Test public void triggerIbvEmailNotification_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1379,7 +1378,7 @@ public void triggerIbvEmailNotification_shouldWrapIOException() throws Exception @Test public void triggerIbvEmailNotification_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1396,7 +1395,7 @@ public void getSupportedDocuments_shouldThrowExceptionWhenKeyPairIsNull() { @Test public void getSupportedDocuments_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); @@ -1407,8 +1406,8 @@ public void getSupportedDocuments_shouldWrapGeneralSecurityException() throws Ex @Test public void getSupportedDocuments_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(SupportedDocumentsResponse.class)).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(SupportedDocumentsResponse.class)).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); @@ -1419,8 +1418,8 @@ public void getSupportedDocuments_shouldWrapResourceException() throws Exception @Test public void getSupportedDocuments_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(SupportedDocumentsResponse.class)).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(SupportedDocumentsResponse.class)).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); @@ -1431,7 +1430,7 @@ public void getSupportedDocuments_shouldWrapIOException() throws Exception { @Test public void getSupportedDocuments_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); @@ -1441,8 +1440,8 @@ public void getSupportedDocuments_shouldWrapURISyntaxException() throws Exceptio @Test public void getSupportedDocuments_shouldReturnSupportedDocuments() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(SupportedDocumentsResponse.class)).thenReturn(supportedDocumentsResponseMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(SupportedDocumentsResponse.class)).thenReturn(supportedDocumentsResponseMock); when(unsignedPathFactoryMock.createGetSupportedDocumentsPath(false)).thenReturn(SOME_PATH); SupportedDocumentsResponse result = docScanService.getSupportedDocuments(KEY_PAIR, false); @@ -1483,7 +1482,7 @@ public void getTrackedDevices_shouldThrowExceptionWhenSessionIdIsEmpty() { @Test public void getTrackedDevices_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1494,8 +1493,8 @@ public void getTrackedDevices_shouldWrapGeneralSecurityException() throws Except @Test public void getTrackedDevices_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1506,8 +1505,8 @@ public void getTrackedDevices_shouldWrapResourceException() throws Exception { @Test public void getTrackedDevices_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1518,7 +1517,7 @@ public void getTrackedDevices_shouldWrapIOException() throws Exception { @Test public void getTrackedDevices_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1528,9 +1527,9 @@ public void getTrackedDevices_shouldWrapURISyntaxException() throws Exception { @Test public void getTrackedDevices_shouldReturnTrackedDevices() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); MetadataResponse metadataResponseMock = mock(MetadataResponse.class); - when(signedRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenReturn(Collections.singletonList(metadataResponseMock)); + when(yotiHttpRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenReturn(Collections.singletonList(metadataResponseMock)); when(unsignedPathFactoryMock.createFetchTrackedDevices(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); List result = docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); @@ -1571,7 +1570,7 @@ public void deleteTrackedDevices_shouldThrowExceptionWhenSessionIdIsEmpty() { @Test public void deleteTrackedDevices_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); - when(signedRequestBuilderMock.build()).thenThrow(gse); + when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1582,8 +1581,8 @@ public void deleteTrackedDevices_shouldWrapGeneralSecurityException() throws Exc @Test public void deleteTrackedDevices_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1594,8 +1593,8 @@ public void deleteTrackedDevices_shouldWrapResourceException() throws Exception @Test public void deleteTrackedDevices_shouldWrapIOException() throws Exception { IOException ioException = new IOException("Some io exception"); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(signedRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); @@ -1606,7 +1605,7 @@ public void deleteTrackedDevices_shouldWrapIOException() throws Exception { @Test public void deleteTrackedDevices_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); - when(signedRequestBuilderMock.build()).thenThrow(uriSyntaxException); + when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcherTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcherTest.java index e3494d70a..c45c1ca08 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcherTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ImageResourceFetcherTest.java @@ -29,7 +29,7 @@ public class ImageResourceFetcherTest { @InjectMocks ImageResourceFetcher testObj; @Mock RawResourceFetcher rawResourceFetcherMock; - @Mock SignedRequest signedRequestMock; + @Mock YotiHttpRequest yotiHttpRequestMock; private Map> createResponseHeaderMap(String name, List values) { HashMap> result = new HashMap<>(); @@ -40,10 +40,10 @@ private Map> createResponseHeaderMap(String name, List> headersMap = createResponseHeaderMap("Content-Type", asList(YotiConstants.CONTENT_TYPE_PNG)); - SignedRequestResponse signedRequestResponse = new SignedRequestResponse(SOME_OK_STATUS_CODE, SOME_RESPONSE_BODY, headersMap); - when(rawResourceFetcherMock.doRequest(signedRequestMock)).thenReturn(signedRequestResponse); + YotiHttpResponse yotiHttpResponse = new YotiHttpResponse(SOME_OK_STATUS_CODE, SOME_RESPONSE_BODY, headersMap); + when(rawResourceFetcherMock.doRequest(yotiHttpRequestMock)).thenReturn(yotiHttpResponse); - Image result = testObj.doRequest(signedRequestMock); + Image result = testObj.doRequest(yotiHttpRequestMock); assertThat(result.getMimeType(), is(YotiConstants.CONTENT_TYPE_PNG)); assertTrue(Arrays.equals(result.getContent(), SOME_RESPONSE_BODY)); @@ -52,10 +52,10 @@ public void doRequest_shouldReturnPngImage() throws Exception { @Test public void doRequest_shouldReturnJpegImage() throws Exception { Map> headersMap = createResponseHeaderMap("Content-Type", asList(YotiConstants.CONTENT_TYPE_JPEG)); - SignedRequestResponse signedRequestResponse = new SignedRequestResponse(SOME_OK_STATUS_CODE, SOME_RESPONSE_BODY, headersMap); - when(rawResourceFetcherMock.doRequest(signedRequestMock)).thenReturn(signedRequestResponse); + YotiHttpResponse yotiHttpResponse = new YotiHttpResponse(SOME_OK_STATUS_CODE, SOME_RESPONSE_BODY, headersMap); + when(rawResourceFetcherMock.doRequest(yotiHttpRequestMock)).thenReturn(yotiHttpResponse); - Image result = testObj.doRequest(signedRequestMock); + Image result = testObj.doRequest(yotiHttpRequestMock); String mimeType = result.getMimeType(); byte[] content = result.getContent(); @@ -67,10 +67,10 @@ public void doRequest_shouldReturnJpegImage() throws Exception { @Test(expected = ResourceException.class) public void doRequest_shouldThrowResourceExceptionForUnsupportedImageType() throws Exception { Map> headersMap = createResponseHeaderMap("Content-Type", asList("image/webp")); - SignedRequestResponse signedRequestResponse = new SignedRequestResponse(SOME_OK_STATUS_CODE, SOME_RESPONSE_BODY, headersMap); - when(rawResourceFetcherMock.doRequest(signedRequestMock)).thenReturn(signedRequestResponse); + YotiHttpResponse yotiHttpResponse = new YotiHttpResponse(SOME_OK_STATUS_CODE, SOME_RESPONSE_BODY, headersMap); + when(rawResourceFetcherMock.doRequest(yotiHttpRequestMock)).thenReturn(yotiHttpResponse); - testObj.doRequest(signedRequestMock); + testObj.doRequest(yotiHttpRequestMock); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcherTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcherTest.java index 1253590be..9dfb79c7a 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcherTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/JsonResourceFetcherTest.java @@ -21,46 +21,46 @@ public class JsonResourceFetcherTest { @Mock ObjectMapper objectMapperMock; @Mock RawResourceFetcher rawResourceFetcherMock; - @Mock SignedRequest signedRequestMock; - @Mock SignedRequestResponse signedRequestResponseMock; + @Mock YotiHttpRequest yotiHttpRequestMock; + @Mock YotiHttpResponse yotiHttpResponseMock; Object parsedResponse = new Object(); @Before public void setUp() throws Exception { - when(rawResourceFetcherMock.doRequest(signedRequestMock)).thenReturn(signedRequestResponseMock); + when(rawResourceFetcherMock.doRequest(yotiHttpRequestMock)).thenReturn(yotiHttpResponseMock); } @Test public void fetchResource_shouldReturnResource() throws Exception { - when(objectMapperMock.readValue(signedRequestResponseMock.getResponseBody(), Object.class)).thenReturn(parsedResponse); + when(objectMapperMock.readValue(yotiHttpResponseMock.getResponseBody(), Object.class)).thenReturn(parsedResponse); - Object result = testObj.doRequest(signedRequestMock, Object.class); + Object result = testObj.doRequest(yotiHttpRequestMock, Object.class); assertSame(parsedResponse, result); } @Test(expected = IOException.class) public void fetchResource_shouldThrowIOExceptionForInvalidResponse() throws Exception { - when(objectMapperMock.readValue(signedRequestResponseMock.getResponseBody(), Object.class)).thenThrow(new IOException()); + when(objectMapperMock.readValue(yotiHttpResponseMock.getResponseBody(), Object.class)).thenThrow(new IOException()); - testObj.doRequest(signedRequestMock, Object.class); + testObj.doRequest(yotiHttpRequestMock, Object.class); } @Test public void doRequest_shouldReturnResource() throws Exception { - when(objectMapperMock.readValue(signedRequestResponseMock.getResponseBody(), Object.class)).thenReturn(parsedResponse); + when(objectMapperMock.readValue(yotiHttpResponseMock.getResponseBody(), Object.class)).thenReturn(parsedResponse); - Object result = testObj.doRequest(signedRequestMock, Object.class); + Object result = testObj.doRequest(yotiHttpRequestMock, Object.class); assertSame(parsedResponse, result); } @Test(expected = IOException.class) public void doRequest_shouldThrowIOExceptionForInvalidResponse() throws Exception { - when(objectMapperMock.readValue(signedRequestResponseMock.getResponseBody(), Object.class)).thenThrow(new IOException()); + when(objectMapperMock.readValue(yotiHttpResponseMock.getResponseBody(), Object.class)).thenThrow(new IOException()); - testObj.doRequest(signedRequestMock, Object.class); + testObj.doRequest(yotiHttpRequestMock, Object.class); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java index e95ce4e43..c567f9f23 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java @@ -5,7 +5,8 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; import java.io.IOException; import java.security.KeyPair; @@ -14,10 +15,14 @@ import com.yoti.api.client.ProfileException; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; -import org.junit.*; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.junit.*; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ProfileServiceTest { @@ -40,7 +45,7 @@ public class ProfileServiceTest { @Mock UnsignedPathFactory unsignedPathFactory; - @Mock SignedRequest signedRequest; + @Mock YotiHttpRequest yotiHttpRequest; @BeforeClass public static void setUpClass() throws Exception { @@ -55,8 +60,8 @@ public void setUp() { @Test public void shouldReturnReceiptForCorrectRequest() throws Exception { - doReturn(signedRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); - when(signedRequest.execute(ProfileResponse.class)).thenReturn(PROFILE_RESPONSE); + doReturn(yotiHttpRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + when(yotiHttpRequest.execute(ProfileResponse.class)).thenReturn(PROFILE_RESPONSE); Receipt result = testObj.getReceipt(KEY_PAIR, APP_ID, TOKEN); assertSame(RECEIPT, result); @@ -65,8 +70,8 @@ public void shouldReturnReceiptForCorrectRequest() throws Exception { @Test public void shouldThrowExceptionForIOError() throws Exception { IOException ioException = new IOException("Test exception"); - doReturn(signedRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); - when(signedRequest.execute(ProfileResponse.class)).thenThrow(ioException); + doReturn(yotiHttpRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + when(yotiHttpRequest.execute(ProfileResponse.class)).thenThrow(ioException); try { testObj.getReceipt(KEY_PAIR, APP_ID, TOKEN); @@ -79,8 +84,8 @@ public void shouldThrowExceptionForIOError() throws Exception { @Test public void shouldThrowExceptionWithResourceExceptionCause() throws Throwable { ResourceException resourceException = new ResourceException(404, "Not Found", "Test exception"); - doReturn(signedRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); - when(signedRequest.execute(ProfileResponse.class)).thenThrow(resourceException); + doReturn(yotiHttpRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + when(yotiHttpRequest.execute(ProfileResponse.class)).thenThrow(resourceException); try { testObj.getReceipt(KEY_PAIR, APP_ID, TOKEN); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/RawResourceFetcherTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/RawResourceFetcherTest.java index 492346298..fb0e965b2 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/RawResourceFetcherTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/RawResourceFetcherTest.java @@ -66,7 +66,7 @@ public void doRequest_shouldReturnByteArray() throws Exception { when(httpURLConnectionMock.getInputStream()).thenReturn(inputStreamSpy); when(httpURLConnectionMock.getResponseCode()).thenReturn(HTTP_OK); - SignedRequestResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_GET, null, TEST_HEADERS); + YotiHttpResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_GET, null, TEST_HEADERS); verify(httpURLConnectionMock).setRequestMethod("GET"); verify(httpURLConnectionMock).setRequestProperty(TEST_HEADER_KEY, TEST_HEADER_VALUE); @@ -82,7 +82,7 @@ public void chunkRead_shouldHandleInputStreamSmallerThanDefaultChunkSize() throw when(httpURLConnectionMock.getInputStream()).thenReturn(smallerSizeByteArray); when(httpURLConnectionMock.getResponseCode()).thenReturn(HTTP_OK); - SignedRequestResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_GET, null, TEST_HEADERS); + YotiHttpResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_GET, null, TEST_HEADERS); verify(httpURLConnectionMock).setRequestMethod("GET"); verify(httpURLConnectionMock).setRequestProperty(TEST_HEADER_KEY, TEST_HEADER_VALUE); @@ -98,7 +98,7 @@ public void chunkRead_shouldHandleInputStreamLargerThanDefaultChunkSize() throws when(httpURLConnectionMock.getInputStream()).thenReturn(largerSizeByteArray); when(httpURLConnectionMock.getResponseCode()).thenReturn(HTTP_OK); - SignedRequestResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_GET, null, TEST_HEADERS); + YotiHttpResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_GET, null, TEST_HEADERS); verify(httpURLConnectionMock).setRequestMethod("GET"); verify(httpURLConnectionMock).setRequestProperty(TEST_HEADER_KEY, TEST_HEADER_VALUE); @@ -165,7 +165,7 @@ public void doRequest_shouldSendBodyAndReturnResponse() throws Exception { when(httpURLConnectionMock.getResponseCode()).thenReturn(HTTP_OK); when(httpURLConnectionMock.getInputStream()).thenReturn(inputStreamSpy); - SignedRequestResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_POST, requestBody, TEST_HEADERS); + YotiHttpResponse result = testObj.doRequest(urlConnectorMock, HttpMethod.HTTP_POST, requestBody, TEST_HEADERS); verify(httpURLConnectionMock).setRequestMethod("POST"); verify(httpURLConnectionMock).setRequestProperty(TEST_HEADER_KEY, TEST_HEADER_VALUE); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilderTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderTest.java similarity index 85% rename from yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilderTest.java rename to yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderTest.java index ff15ad7f6..ea8e09c5e 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/SignedRequestBuilderTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderTest.java @@ -15,8 +15,13 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.io.IOException; import java.io.OutputStream; @@ -36,14 +41,21 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.junit.*; +import org.junit.BeforeClass; +import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.junit.*; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.class) -public class SignedRequestBuilderTest { +public class YotiHttpRequestBuilderTest { private static final String SOME_ENDPOINT = "/someEndpoint"; private static final String SOME_SIGNATURE = "someSignature"; @@ -71,7 +83,7 @@ public static void setUpClass() throws Exception { KEY_PAIR = generateKeyPairFrom(KEY_PAIR_PEM); } - @InjectMocks SignedRequestBuilder signedRequestBuilder; + @InjectMocks YotiHttpRequestBuilder yotiHttpRequestBuilder; @Mock PathFactory pathFactoryMock; @Mock SignedMessageFactory signedMessageFactoryMock; @@ -86,7 +98,7 @@ public static void setUpClass() throws Exception { @Test public void withHttpMethod_shouldThrowExceptionWhenSuppliedWithUnsupportedHttpMethod() { try { - signedRequestBuilder.withHttpMethod("someNonsenseHere"); + yotiHttpRequestBuilder.withHttpMethod("someNonsenseHere"); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("someNonsenseHere")); return; @@ -98,7 +110,7 @@ public void withHttpMethod_shouldThrowExceptionWhenSuppliedWithUnsupportedHttpMe @Test public void build_shouldThrowExceptionWhenMissingKeyPair() throws Exception { try { - signedRequestBuilder.build(); + yotiHttpRequestBuilder.build(); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("keyPair")); return; @@ -109,7 +121,7 @@ public void build_shouldThrowExceptionWhenMissingKeyPair() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingBaseUrl() throws Exception { try { - signedRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .build(); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("baseUrl")); @@ -121,7 +133,7 @@ public void build_shouldThrowExceptionWhenMissingBaseUrl() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingEndpoint() throws Exception { try { - signedRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(SOME_BASE_URL) .build(); } catch (IllegalArgumentException e) { @@ -134,7 +146,7 @@ public void build_shouldThrowExceptionWhenMissingEndpoint() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingHttpMethod() throws Exception { try { - signedRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .build(); @@ -149,7 +161,7 @@ public void build_shouldThrowExceptionWhenMissingHttpMethod() throws Exception { public void build_shouldCreateSignedRequestWithCustomQueryParameter() throws Exception { when(pathFactoryMock.createSignatureParams()).thenReturn(SIGNATURE_PARAMS_STRING); - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -161,7 +173,7 @@ public void build_shouldCreateSignedRequestWithCustomQueryParameter() throws Exc @Test public void build_shouldCreateSignedRequestWithProvidedHttpHeader() throws Exception { - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(DEFAULT_YOTI_API_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -177,7 +189,7 @@ public void build_shouldIgnoreAnyProvidedSignedRequestHeaders() throws Exception when(signedMessageFactoryMock.create(any(PrivateKey.class), anyString(), anyString())).thenReturn(SOME_SIGNATURE); when(headersFactoryMock.create(SOME_SIGNATURE)).thenReturn(SIGNED_REQUEST_HEADERS); - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(DEFAULT_YOTI_API_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -189,69 +201,69 @@ public void build_shouldIgnoreAnyProvidedSignedRequestHeaders() throws Exception @Test public void withBoundary_shouldThrowWhenBoundaryIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBoundary(null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBoundary(null)); assertThat(ex.getMessage(), containsString("multipartBoundary")); } @Test public void withBoundary_shouldThrowWhenBoundaryIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBoundary("")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBoundary("")); assertThat(ex.getMessage(), containsString("multipartBoundary")); } @Test public void withMultipartBinaryBody_shouldThrowWhenNameIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBinaryBody(null, null, null, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBinaryBody(null, null, null, null)); assertThat(ex.getMessage(), containsString("name")); } @Test public void withMultipartBinaryBody_shouldThrowWhenNameIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBinaryBody("", null, null, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBinaryBody("", null, null, null)); assertThat(ex.getMessage(), containsString("name")); } @Test public void withMultipartBinaryBody_shouldThrowWhenPayloadIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, null, null, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, null, null, null)); assertThat(ex.getMessage(), containsString("payload")); } @Test public void withMultipartBinaryBody_shouldThrowWhenContentTypeIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, null, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, null, null)); assertThat(ex.getMessage(), containsString("contentType")); } @Test public void withMultipartBinaryBody_shouldThrowWhenFileNameIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, null)); assertThat(ex.getMessage(), containsString("fileName")); } @Test public void withMultipartBinaryBody_shouldThrowWhenFileNameIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> signedRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> yotiHttpRequestBuilder.withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, "")); assertThat(ex.getMessage(), containsString("fileName")); } @Test public void shouldRemoveTrailingSlashesFromBaseUrl() throws Exception { - SignedRequest simpleSignedRequest = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest simpleYotiHttpRequest = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(SOME_BASE_URL + "////////////") .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) .build(); - assertThat(simpleSignedRequest.getUri().toString(), containsString(SOME_BASE_URL + SOME_ENDPOINT)); + assertThat(simpleYotiHttpRequest.getUri().toString(), containsString(SOME_BASE_URL + SOME_ENDPOINT)); } @Test @@ -260,7 +272,7 @@ public void shouldCreateSignedRequestSuccessfullyWithRequiredFieldsOnly() throws when(signedMessageFactoryMock.create(any(PrivateKey.class), anyString(), anyString())).thenReturn(SOME_SIGNATURE); when(headersFactoryMock.create(SOME_SIGNATURE)).thenReturn(SIGNED_REQUEST_HEADERS); - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -281,7 +293,7 @@ public void shouldCreatedSignedRequestSuccessfullyWithAllProperties() throws Exc when(signedMessageFactoryMock.create(any(PrivateKey.class), anyString(), anyString(), any(byte[].class))).thenReturn(SOME_SIGNATURE); when(headersFactoryMock.create(SOME_SIGNATURE)).thenReturn(SIGNED_REQUEST_HEADERS); - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -323,7 +335,7 @@ public void shouldSetContentTypeToMultipartWhenUserHasSetRequestTypeToMultipart( try (MockedStatic ms = Mockito.mockStatic(MultipartEntityBuilder.class)) { ms.when(MultipartEntityBuilder::create).thenReturn(multipartEntityBuilderMock); - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withMultipartBoundary(SOME_MULTIPART_BOUNDARY) .withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, SOME_MULTIPART_FILE_NAME) .withBaseUrl(SOME_BASE_URL) @@ -352,7 +364,7 @@ public void shouldThrowIllegalArgumentExceptionWhenThereIsAnErrorBuildingTheMult ms.when(MultipartEntityBuilder::create).thenReturn(multipartEntityBuilderMock); IllegalStateException exception = assertThrows(IllegalStateException.class, () -> { - signedRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) .withMultipartBoundary(SOME_MULTIPART_BOUNDARY) .withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, SOME_MULTIPART_FILE_NAME) .withBaseUrl(SOME_BASE_URL) diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java index 3f032bdf6..8c22c18c0 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java @@ -17,7 +17,7 @@ import com.yoti.api.client.aml.AmlProfile; import com.yoti.api.client.aml.AmlResult; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.core.JsonProcessingException; @@ -47,7 +47,7 @@ public class RemoteAmlServiceTest { @Mock AmlProfile amlProfileMock; @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPairMock; - @Mock SignedRequest signedRequestMock; + @Mock YotiHttpRequest yotiHttpRequestMock; @Mock AmlResult amlResultMock; @BeforeClass @@ -63,8 +63,8 @@ public void setUp() { @Test public void shouldPerformAmlCheck() throws Exception { when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); - when(signedRequestMock.execute(AmlResult.class)).thenReturn(amlResultMock); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); + when(yotiHttpRequestMock.execute(AmlResult.class)).thenReturn(amlResultMock); AmlResult result = testObj.performCheck(keyPairMock, SOME_APP_ID, amlProfileMock); @@ -75,8 +75,8 @@ public void shouldPerformAmlCheck() throws Exception { public void shouldWrapIOException() throws Exception { IOException ioException = new IOException(); when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); - when(signedRequestMock.execute(AmlResult.class)).thenThrow(ioException); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); + when(yotiHttpRequestMock.execute(AmlResult.class)).thenThrow(ioException); try { testObj.performCheck(keyPairMock, SOME_APP_ID, amlProfileMock); @@ -90,8 +90,8 @@ public void shouldWrapIOException() throws Exception { public void shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(HTTP_UNAUTHORIZED, "Unauthorized", "failed verification"); when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); - when(signedRequestMock.execute(AmlResult.class)).thenThrow(resourceException); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); + when(yotiHttpRequestMock.execute(AmlResult.class)).thenThrow(resourceException); try { testObj.performCheck(keyPairMock, SOME_APP_ID, amlProfileMock); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java index 8e3cacdbf..d80182b21 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java @@ -1,12 +1,13 @@ package com.yoti.api.client.spi.remote.call.identity; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.Answers.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; @@ -18,17 +19,22 @@ import com.yoti.api.client.identity.MatchResult; import com.yoti.api.client.identity.ShareSession; import com.yoti.api.client.identity.ShareSessionRequest; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilder; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.yoti.json.ResourceMapper; import com.fasterxml.jackson.core.JsonProcessingException; -import org.junit.*; +import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.junit.*; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class DigitalIdentityServiceTest { @@ -44,11 +50,11 @@ public class DigitalIdentityServiceTest { @Spy @InjectMocks DigitalIdentityService identityService; @Mock UnsignedPathFactory unsignedPathFactory; - @Mock(answer = RETURNS_DEEP_STUBS) SignedRequestBuilder signedRequestBuilder; - @Mock SignedRequestBuilderFactory requestBuilderFactory; + @Mock(answer = RETURNS_DEEP_STUBS) YotiHttpRequestBuilder yotiHttpRequestBuilder; + @Mock YotiHttpRequestBuilderFactory requestBuilderFactory; @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPair; - @Mock SignedRequest signedRequest; + @Mock YotiHttpRequest yotiHttpRequest; @Mock ShareSessionRequest shareSessionRequest; @Mock ShareSession shareSession; @@ -124,7 +130,7 @@ public void createShareSession_SerializingWrongPayload_Exception() { public void createShareSession_BuildingRequestWithWrongUri_Exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); @@ -147,7 +153,7 @@ public void createShareSession_BuildingRequestWithWrongQueryParams_Exception() t try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); @@ -170,7 +176,7 @@ public void createShareSession_BuildingRequestWithWrongDigest_Exception() throws try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); @@ -193,12 +199,12 @@ public void createShareSession_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); when(identityService.createSignedRequest(SDK_ID, keyPair, SESSION_CREATION_PATH, POST, A_BODY_BYTES)) - .thenReturn(signedRequest); + .thenReturn(yotiHttpRequest); - when(signedRequest.execute(ShareSession.class)).thenReturn(shareSession); + when(yotiHttpRequest.execute(ShareSession.class)).thenReturn(shareSession); ShareSession result = identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest); assertSame(shareSession, result); @@ -347,7 +353,7 @@ public void fetchMatch_SerializingWrongPayload_Exception() { public void fetchMatch_BuildingRequestWithWrongEndpoint_Exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); @@ -370,7 +376,7 @@ public void fetchMatch_BuildingRequestWithWrongQueryParams_Exception() throws Ex try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); @@ -393,7 +399,7 @@ public void fetchMatch_BuildingRequestWithWrongDigest_Exception() throws Excepti try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); @@ -416,12 +422,12 @@ public void fetchMatch_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) - .thenReturn(signedRequest); + .thenReturn(yotiHttpRequest); - when(signedRequest.execute(MatchResult.class)).thenReturn(matchResult); + when(yotiHttpRequest.execute(MatchResult.class)).thenReturn(matchResult); MatchResult result = identityService.fetchMatch(SDK_ID, keyPair, matchRequest); assertSame(matchResult, result); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java index 55ff43d29..009fa8ea5 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java @@ -15,7 +15,7 @@ import com.yoti.api.client.shareurl.DynamicShareException; import com.yoti.api.client.shareurl.ShareUrlResult; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.core.JsonProcessingException; @@ -44,7 +44,7 @@ public class DynamicSharingServiceTest { @Mock ObjectMapper objectMapperMock; @Mock DynamicScenario simpleDynamicScenarioMock; - @Mock SignedRequest signedRequestMock; + @Mock YotiHttpRequest yotiHttpRequestMock; @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPairMock; @Mock ShareUrlResult shareUrlResultMock; @@ -90,8 +90,8 @@ public void shouldThrowDynamicShareExceptionWhenParsingFails() throws Exception public void shouldThrowExceptionForIOError() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); IOException ioException = new IOException(); - doReturn(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); - when(signedRequestMock.execute(ShareUrlResult.class)).thenThrow(ioException); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenThrow(ioException); try { testObj.createShareUrl(APP_ID, keyPairMock, simpleDynamicScenarioMock); @@ -105,8 +105,8 @@ public void shouldThrowExceptionForIOError() throws Exception { public void shouldThrowExceptionWithResourceExceptionCause() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); ResourceException resourceException = new ResourceException(404, "Not Found", "Test exception"); - doReturn(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); - when(signedRequestMock.execute(ShareUrlResult.class)).thenThrow(resourceException); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenThrow(resourceException); try { testObj.createShareUrl(APP_ID, keyPairMock, simpleDynamicScenarioMock); @@ -119,8 +119,8 @@ public void shouldThrowExceptionWithResourceExceptionCause() throws Exception { @Test public void shouldReturnReceiptForCorrectRequest() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); - doReturn(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); - when(signedRequestMock.execute(ShareUrlResult.class)).thenReturn(shareUrlResultMock); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenReturn(shareUrlResultMock); ShareUrlResult result = testObj.createShareUrl(APP_ID, keyPairMock, simpleDynamicScenarioMock); assertSame(shareUrlResultMock, result); diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java index 1f113c752..74ab2dc17 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java @@ -18,11 +18,9 @@ import com.yoti.api.client.spi.remote.call.JsonResourceFetcher; import com.yoti.api.client.spi.remote.call.ResourceException; import com.yoti.api.client.spi.remote.call.ResourceFetcher; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilder; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.YotiConstants; -import com.yoti.api.client.spi.remote.call.factory.SignedMessageFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; @@ -39,7 +37,7 @@ public class YotiSandboxClient { private final ObjectMapper mapper; private final SandboxPathFactory sandboxPathFactory; private final ResourceFetcher resourceFetcher; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; public static YotiSandboxClientBuilder builder() { return new YotiSandboxClientBuilder(); @@ -49,13 +47,13 @@ public static YotiSandboxClientBuilder builder() { KeyPair keyPair, SandboxPathFactory pathFactory, ObjectMapper mapper, - ResourceFetcher resourceFetcher, SignedRequestBuilderFactory signedRequestBuilderFactory) { + ResourceFetcher resourceFetcher, YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.appId = appId; this.keyPair = keyPair; this.sandboxPathFactory = pathFactory; this.mapper = mapper; this.resourceFetcher = resourceFetcher; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; this.sandboxBasePath = System.getProperty(YotiConstants.PROPERTY_YOTI_API_URL, DEFAULT_SANDBOX_API_URL); notNullOrEmpty(sandboxBasePath, "Sandbox base path"); @@ -65,14 +63,14 @@ public String setupSharingProfile(YotiTokenRequest yotiTokenRequest) { String requestPath = sandboxPathFactory.createSandboxPath(appId); try { byte[] body = mapper.writeValueAsBytes(yotiTokenRequest); - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withBaseUrl(sandboxBasePath) .withEndpoint(requestPath) .withKeyPair(keyPair) .withHttpMethod(HTTP_POST) .withPayload(body) .build(); - YotiTokenResponse yotiTokenResponse = resourceFetcher.doRequest(signedRequest, YotiTokenResponse.class); + YotiTokenResponse yotiTokenResponse = resourceFetcher.doRequest(yotiHttpRequest, YotiTokenResponse.class); return yotiTokenResponse.getToken(); } catch (IOException | GeneralSecurityException | ResourceException | URISyntaxException e) { throw new SandboxException(e); @@ -108,7 +106,7 @@ public YotiSandboxClient build() { notNullOrEmpty(appId, "appId"); notNull(keyPair, "keyPair"); return new YotiSandboxClient(appId, keyPair, new SandboxPathFactory(), new ObjectMapper(), JsonResourceFetcher.newInstance(), - new SignedRequestBuilderFactory()); + new YotiHttpRequestBuilderFactory()); } } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java index d70165518..d5c7f40d0 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java @@ -17,8 +17,8 @@ import com.yoti.api.client.spi.remote.KeyStreamVisitor; import com.yoti.api.client.spi.remote.call.HttpMethod; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; @@ -31,18 +31,18 @@ public class DocScanSandboxClient { private final String docScanBaseUrl; private final ObjectMapper mapper; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String sdkId; private final KeyPair keyPair; DocScanSandboxClient(String sdkId, KeyPair keyPair, ObjectMapper mapper, - SignedRequestBuilderFactory signedRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.sdkId = sdkId; this.keyPair = keyPair; this.mapper = mapper; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; this.docScanBaseUrl = System.getProperty(PROPERTY_YOTI_DOCS_URL, DEFAULT_DOC_SCAN_SANDBOX_API_URL); } @@ -63,7 +63,7 @@ public void configureSessionResponse(String sessionId, ResponseConfig responseCo try { byte[] body = mapper.writeValueAsBytes(responseConfig); - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withBaseUrl(docScanBaseUrl) .withEndpoint(path) .withKeyPair(keyPair) @@ -72,7 +72,7 @@ public void configureSessionResponse(String sessionId, ResponseConfig responseCo .withQueryParameter("sdkId", sdkId) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (URISyntaxException | GeneralSecurityException | ResourceException | IOException e) { throw new SandboxException(e); } @@ -89,7 +89,7 @@ public void configureApplicationResponse(ResponseConfig sandboxExpectation) thro try { byte[] body = mapper.writeValueAsBytes(sandboxExpectation); - SignedRequest signedRequest = signedRequestBuilderFactory.create() + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withBaseUrl(docScanBaseUrl) .withEndpoint(path) .withKeyPair(keyPair) @@ -97,7 +97,7 @@ public void configureApplicationResponse(ResponseConfig sandboxExpectation) thro .withPayload(body) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (URISyntaxException | GeneralSecurityException | ResourceException | IOException e) { throw new SandboxException(e); } @@ -132,7 +132,7 @@ public DocScanSandboxClient build() { notNullOrEmpty(sdkId, "sdkId"); notNull(keyPair, "keyPair"); - return new DocScanSandboxClient(sdkId, keyPair, new ObjectMapper(), new SignedRequestBuilderFactory()); + return new DocScanSandboxClient(sdkId, keyPair, new ObjectMapper(), new YotiHttpRequestBuilderFactory()); } } } diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java index 828213aac..2742c65c3 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java @@ -1,28 +1,16 @@ package com.yoti.api.client.sandbox; -import static com.yoti.api.client.sandbox.YotiSandboxClient.YOTI_SANDBOX_PATH_PREFIX; -import static com.yoti.api.client.spi.remote.call.HttpMethod.HTTP_POST; -import static com.yoti.api.client.spi.remote.call.YotiConstants.DIGEST_HEADER; -import static com.yoti.api.client.spi.remote.call.YotiConstants.JAVA; -import static com.yoti.api.client.spi.remote.call.YotiConstants.SDK_VERSION; -import static com.yoti.api.client.spi.remote.call.YotiConstants.YOTI_SDK_HEADER; -import static com.yoti.api.client.spi.remote.call.YotiConstants.YOTI_SDK_VERSION_HEADER; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Answers.RETURNS_DEEP_STUBS; import static org.mockito.Answers.RETURNS_SELF; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.net.URL; -import java.security.GeneralSecurityException; import java.security.KeyPair; -import java.util.Map; import com.yoti.api.client.KeyPairSource; import com.yoti.api.client.sandbox.profile.request.YotiTokenRequest; @@ -30,19 +18,15 @@ import com.yoti.api.client.spi.remote.KeyStreamVisitor; import com.yoti.api.client.spi.remote.call.ResourceException; import com.yoti.api.client.spi.remote.call.ResourceFetcher; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilder; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; -import com.yoti.api.client.spi.remote.call.UrlConnector; -import com.yoti.api.client.spi.remote.call.factory.SignedMessageFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @@ -63,18 +47,19 @@ public class YotiSandboxClientTest { @Mock KeyPairSource keyPairSourceMock; @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPairMock; - @Mock SignedRequestBuilderFactory signedRequestBuilderFactoryMock; - @Mock(answer = RETURNS_SELF) SignedRequestBuilder signedRequestBuilderMock; - @Mock SignedRequest signedRequestMock; + @Mock YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactoryMock; + @Mock(answer = RETURNS_SELF) YotiHttpRequestBuilder yotiHttpRequestBuilderMock; + @Mock YotiHttpRequest yotiHttpRequestMock; @Mock YotiTokenRequest yotiTokenRequestMock; @Mock YotiTokenResponse yotiTokenResponseMock; @Before public void setUp() throws Exception { - when(signedRequestBuilderFactoryMock.create()).thenReturn(signedRequestBuilderMock); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - testObj = new YotiSandboxClient(SOME_APP_ID, keyPairMock, sandboxPathFactoryMock, objectMapperMock, resourceFetcherMock, signedRequestBuilderFactoryMock); + when(yotiHttpRequestBuilderFactoryMock.create()).thenReturn(yotiHttpRequestBuilderMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + testObj = new YotiSandboxClient(SOME_APP_ID, keyPairMock, sandboxPathFactoryMock, objectMapperMock, resourceFetcherMock, + yotiHttpRequestBuilderFactoryMock); } @Test @@ -130,7 +115,7 @@ public void setupSharingProfile_shouldWrapIOException() throws Exception { public void setupSharingProfile_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(401, null, null); when(objectMapperMock.writeValueAsBytes(yotiTokenRequestMock)).thenReturn(BODY_BYTES); - when(resourceFetcherMock.doRequest(signedRequestMock, YotiTokenResponse.class)).thenThrow(resourceException); + when(resourceFetcherMock.doRequest(yotiHttpRequestMock, YotiTokenResponse.class)).thenThrow(resourceException); try { testObj.setupSharingProfile(yotiTokenRequestMock); @@ -146,12 +131,12 @@ public void setupSharingProfile_shouldWrapResourceException() throws Exception { public void setupSharingProfile_shouldReturnTokenFromSandbox() throws Exception { when(sandboxPathFactoryMock.createSandboxPath(SOME_APP_ID)).thenReturn(SOME_PATH); when(objectMapperMock.writeValueAsBytes(yotiTokenRequestMock)).thenReturn(BODY_BYTES); - when(resourceFetcherMock.doRequest(signedRequestMock, YotiTokenResponse.class)).thenReturn(yotiTokenResponseMock); + when(resourceFetcherMock.doRequest(yotiHttpRequestMock, YotiTokenResponse.class)).thenReturn(yotiTokenResponseMock); when(yotiTokenResponseMock.getToken()).thenReturn(SOME_TOKEN); String result = testObj.setupSharingProfile(yotiTokenRequestMock); - verify(resourceFetcherMock).doRequest(signedRequestMock, YotiTokenResponse.class); + verify(resourceFetcherMock).doRequest(yotiHttpRequestMock, YotiTokenResponse.class); assertEquals(SOME_TOKEN, result); } diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java index 3c6b94b85..a0e76ee2d 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java @@ -3,9 +3,10 @@ import static com.yoti.api.client.spi.remote.call.YotiConstants.PROPERTY_YOTI_DOCS_URL; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.fail; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.io.IOException; import java.security.KeyPair; @@ -14,15 +15,19 @@ import com.yoti.api.client.sandbox.docs.request.ResponseConfig; import com.yoti.api.client.sandbox.util.FieldSetter; import com.yoti.api.client.spi.remote.call.ResourceException; -import com.yoti.api.client.spi.remote.call.SignedRequest; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilder; -import com.yoti.api.client.spi.remote.call.SignedRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.YotiHttpRequest; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; +import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.*; +import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.junit.*; +import org.mockito.Answers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class DocScanSandboxClientTest { @@ -32,9 +37,9 @@ public class DocScanSandboxClientTest { private static final String SOME_SDK_ID = "someSdkId"; private static final String SOME_SESSION_ID = "someSessionId"; - @Mock SignedRequestBuilderFactory signedRequestBuilderFactory; - @Mock(answer = Answers.RETURNS_SELF) SignedRequestBuilder signedRequestBuilderMock; - @Mock SignedRequest signedRequestMock; + @Mock YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; + @Mock(answer = Answers.RETURNS_SELF) YotiHttpRequestBuilder yotiHttpRequestBuilderMock; + @Mock YotiHttpRequest yotiHttpRequestMock; @Mock ResponseConfig responseConfigMock; @Mock ObjectMapper objectMapperMock; @Mock KeyPair keyPairMock; @@ -43,7 +48,7 @@ public class DocScanSandboxClientTest { @Before public void setUp() { - when(signedRequestBuilderFactory.create()).thenReturn(signedRequestBuilderMock); + when(yotiHttpRequestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilderMock); } @Test @@ -51,8 +56,8 @@ public void configureSessionResponse_shouldWrapIoException() throws Exception { IOException ioException = new IOException("Some error"); when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); - when(signedRequestMock.execute()).thenThrow(ioException); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); try { docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); @@ -68,8 +73,8 @@ public void configureSessionResponse_shouldWrapResourceException() throws Except ResourceException resourceException = new ResourceException(400, "Some error", "There was some error"); when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); - when(signedRequestMock.execute()).thenThrow(resourceException); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); try { docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); @@ -83,29 +88,29 @@ public void configureSessionResponse_shouldWrapResourceException() throws Except @Test public void configureSessionResponse_shouldCallSignedRequestBuilderWithCorrectValues() throws Exception { when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withKeyPair(keyPairMock); - verify(signedRequestBuilderMock).withEndpoint("/sessions/" + SOME_SESSION_ID + "/response-config"); - verify(signedRequestBuilderMock).withPayload(SOME_BYTES); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withKeyPair(keyPairMock); + verify(yotiHttpRequestBuilderMock).withEndpoint("/sessions/" + SOME_SESSION_ID + "/response-config"); + verify(yotiHttpRequestBuilderMock).withPayload(SOME_BYTES); } @Test public void configureApplicationResponse_shouldCallSignedRequestBuilderWithCorrectValues() throws Exception { when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); FieldSetter.setField(docScanSandboxClient, "sdkId", SOME_SDK_ID); docScanSandboxClient.configureApplicationResponse(responseConfigMock); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withKeyPair(keyPairMock); - verify(signedRequestBuilderMock).withEndpoint("/apps/" + SOME_SDK_ID + "/response-config"); - verify(signedRequestBuilderMock).withPayload(SOME_BYTES); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withKeyPair(keyPairMock); + verify(yotiHttpRequestBuilderMock).withEndpoint("/apps/" + SOME_SDK_ID + "/response-config"); + verify(yotiHttpRequestBuilderMock).withPayload(SOME_BYTES); } } From 5cee1cf7181dd2d489fe1aae1ec15f0e1e1060a9 Mon Sep 17 00:00:00 2001 From: Michael Buck Date: Wed, 10 Dec 2025 17:17:27 +0000 Subject: [PATCH 11/28] SDK-2771: [MB] Introduce support for auth tokens --- .../api/client/DigitalIdentityClient.java | 43 +- .../java/com/yoti/api/client/YotiClient.java | 37 +- .../yoti/api/client/docs/DocScanClient.java | 102 +-- .../yoti/api/client/docs/DocScanService.java | 181 +++--- .../api/client/spi/remote/ReceiptFetcher.java | 8 +- .../spi/remote/call/ProfileService.java | 31 +- .../client/spi/remote/call/YotiConstants.java | 1 + .../remote/call/YotiHttpRequestBuilder.java | 101 ++- .../call/YotiHttpRequestBuilderFactory.java | 8 +- .../spi/remote/call/aml/RemoteAmlService.java | 37 +- .../factory/AmlSignedRequestStrategy.java | 35 + .../spi/remote/call/factory/AuthStrategy.java | 15 + .../call/factory/AuthTokenStrategy.java | 30 + .../DigitalIdentitySignedRequestStrategy.java | 33 + .../factory/DocsSignedRequestStrategy.java | 35 + .../remote/call/factory/HeadersFactory.java | 18 +- .../spi/remote/call/factory/PathFactory.java | 52 -- .../factory/ProfileSignedRequestStrategy.java | 35 + .../call/factory/SignedRequestStrategy.java | 49 ++ .../factory/SimpleSignedRequestStrategy.java | 27 + .../call/factory/UnsignedPathFactory.java | 88 +-- .../call/identity/DigitalIdentityService.java | 85 +-- .../call/qrcode/DynamicSharingService.java | 22 +- .../api/client/DigitalIdentityClientTest.java | 94 +-- .../com/yoti/api/client/YotiClientTest.java | 131 ++-- .../client/docs/DocScanClientBuilderTest.java | 77 ++- .../api/client/docs/DocScanClientTest.java | 76 +-- .../api/client/docs/DocScanServiceTest.java | 603 ++++++------------ .../client/spi/remote/ReceiptFetcherTest.java | 50 +- .../spi/remote/call/ProfileServiceTest.java | 26 +- .../call/YotiHttpRequestBuilderTest.java | 111 ++-- .../remote/call/aml/RemoteAmlServiceTest.java | 32 +- .../call/factory/HeadersFactoryTest.java | 25 +- .../remote/call/factory/PathFactoryTest.java | 95 --- .../identity/DigitalIdentityServiceTest.java | 207 ++---- .../qrcode/DynamicSharingServiceTest.java | 23 +- .../client/sandbox/SandboxPathFactory.java | 9 +- .../api/client/sandbox/YotiSandboxClient.java | 10 +- .../sandbox/docs/DocScanSandboxClient.java | 17 +- .../client/sandbox/YotiSandboxClientTest.java | 3 +- .../docs/DocScanSandboxClientTest.java | 48 +- 41 files changed, 1189 insertions(+), 1521 deletions(-) create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AmlSignedRequestStrategy.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthStrategy.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthTokenStrategy.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DigitalIdentitySignedRequestStrategy.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DocsSignedRequestStrategy.java delete mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/PathFactory.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/ProfileSignedRequestStrategy.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SignedRequestStrategy.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SimpleSignedRequestStrategy.java delete mode 100644 yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/PathFactoryTest.java diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java index 1690a9835..d66520776 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java @@ -23,49 +23,36 @@ public class DigitalIdentityClient { Security.addProvider(new BouncyCastleProvider()); } - private final String sdkId; private final KeyPair keyPair; private final DigitalIdentityService identityService; - DigitalIdentityClient(String sdkId, KeyPairSource keyPair, DigitalIdentityService identityService) { - Validation.notNullOrEmpty(sdkId, "SDK ID"); - Validation.notNull(keyPair, "Application Key Pair"); - - this.sdkId = sdkId; - this.keyPair = loadKeyPair(keyPair); + private DigitalIdentityClient(KeyPair keyPair, DigitalIdentityService identityService) { + this.keyPair = keyPair; this.identityService = identityService; } public ShareSession createShareSession(ShareSessionRequest request) throws DigitalIdentityException { - return identityService.createShareSession(sdkId, keyPair, request); + return identityService.createShareSession(request); } public ShareSession fetchShareSession(String sessionId) throws DigitalIdentityException { - return identityService.fetchShareSession(sdkId, keyPair, sessionId); + return identityService.fetchShareSession(sessionId); } public ShareSessionQrCode createShareQrCode(String sessionId) throws DigitalIdentityException { - return identityService.createShareQrCode(sdkId, keyPair, sessionId); + return identityService.createShareQrCode(sessionId); } public ShareSessionQrCode fetchShareQrCode(String qrCodeId) throws DigitalIdentityException { - return identityService.fetchShareQrCode(sdkId, keyPair, qrCodeId); + return identityService.fetchShareQrCode(qrCodeId); } public Receipt fetchShareReceipt(String receiptId) throws DigitalIdentityException { - return identityService.fetchShareReceipt(sdkId, keyPair, receiptId); + return identityService.fetchShareReceipt(keyPair, receiptId); } public MatchResult fetchMatch(MatchRequest request) throws DigitalIdentityException { - return identityService.fetchMatch(sdkId, keyPair, request); - } - - private KeyPair loadKeyPair(KeyPairSource keyPairSource) throws InitialisationException { - try { - return keyPairSource.getFromStream(new KeyStreamVisitor()); - } catch (IOException ex) { - throw new InitialisationException("Cannot load Key Pair", ex); - } + return identityService.fetchMatch(request); } public static Builder builder() { @@ -94,7 +81,19 @@ public Builder withKeyPairSource(KeyPairSource keyPairSource) { } public DigitalIdentityClient build() { - return new DigitalIdentityClient(sdkId, keyPairSource, DigitalIdentityService.newInstance()); + Validation.notNullOrEmpty(sdkId, "SDK ID"); + Validation.notNull(keyPairSource, "Application Key Pair"); + + KeyPair keyPair = loadKeyPair(keyPairSource); + return new DigitalIdentityClient(keyPair, DigitalIdentityService.newInstance(keyPair, sdkId)); + } + + private KeyPair loadKeyPair(KeyPairSource keyPairSource) throws InitialisationException { + try { + return keyPairSource.getFromStream(new KeyStreamVisitor()); + } catch (IOException ex) { + throw new InitialisationException("Cannot load Key Pair", ex); + } } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/YotiClient.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/YotiClient.java index c4dfce3ae..7d627caab 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/YotiClient.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/YotiClient.java @@ -46,13 +46,13 @@ public class YotiClient { private final DynamicSharingService dynamicSharingService; YotiClient(String applicationId, - KeyPairSource kpSource, + KeyPair keyPair, ReceiptFetcher receiptFetcher, - ActivityDetailsFactory activityDetailsFactory, RemoteAmlService remoteAmlService, + ActivityDetailsFactory activityDetailsFactory, DynamicSharingService dynamicSharingService) throws InitialisationException { this.appId = notNull(applicationId, "Application id"); - this.keyPair = loadKeyPair(notNull(kpSource, "Key pair source")); + this.keyPair = keyPair; this.receiptFetcher = notNull(receiptFetcher, "receiptFetcher"); this.remoteAmlService = notNull(remoteAmlService, "amlService"); this.activityDetailsFactory = notNull(activityDetailsFactory, "activityDetailsFactory"); @@ -80,7 +80,7 @@ public static YotiClient.Builder builder() { * @throws ProfileException aggregate exception signalling issues during the call */ public ActivityDetails getActivityDetails(String encryptedYotiToken) throws ProfileException { - Receipt receipt = receiptFetcher.fetch(encryptedYotiToken, keyPair, appId); + Receipt receipt = receiptFetcher.fetch(encryptedYotiToken, keyPair); return activityDetailsFactory.create(receipt, keyPair.getPrivate()); } @@ -96,7 +96,7 @@ public ActivityDetails getActivityDetails(String encryptedYotiToken) throws Prof */ public AmlResult performAmlCheck(AmlProfile amlProfile) throws AmlException { LOG.debug("Performing aml check..."); - return remoteAmlService.performCheck(keyPair, appId, amlProfile); + return remoteAmlService.performCheck(amlProfile); } /** @@ -113,15 +113,7 @@ public AmlResult performAmlCheck(AmlProfile amlProfile) throws AmlException { */ public ShareUrlResult createShareUrl(DynamicScenario dynamicScenario) throws DynamicShareException { LOG.debug("Request a share url for a dynamicScenario..."); - return dynamicSharingService.createShareUrl(appId, keyPair, dynamicScenario); - } - - private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException { - try { - return kpSource.getFromStream(new KeyStreamVisitor()); - } catch (IOException e) { - throw new InitialisationException("Cannot load key pair", e); - } + return dynamicSharingService.createShareUrl(appId, dynamicScenario); } public static class Builder { @@ -144,14 +136,15 @@ public Builder withKeyPair(KeyPairSource keyPairSource) { public YotiClient build() { checkBuilderState(); + KeyPair keyPair = loadKeyPair(notNull(keyPairSource, "Key pair source")); return new YotiClient( sdkId, - keyPairSource, - ReceiptFetcher.newInstance(), + keyPair, + ReceiptFetcher.newInstance(keyPair, sdkId), + RemoteAmlService.newInstance(keyPair, sdkId), ActivityDetailsFactory.newInstance(), - RemoteAmlService.newInstance(), - DynamicSharingService.newInstance() + DynamicSharingService.newInstance(keyPair) ); } @@ -164,6 +157,14 @@ private void checkBuilderState() { } } + private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException { + try { + return kpSource.getFromStream(new KeyStreamVisitor()); + } catch (IOException e) { + throw new InitialisationException("Cannot load key pair", e); + } + } + } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanClient.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanClient.java index 4faf0d89e..c1deb1014 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanClient.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanClient.java @@ -1,8 +1,5 @@ package com.yoti.api.client.docs; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; -import static com.yoti.api.client.spi.remote.util.Validation.notNullOrEmpty; - import java.io.IOException; import java.security.KeyPair; import java.security.Security; @@ -24,6 +21,9 @@ import com.yoti.api.client.docs.session.retrieve.instructions.InstructionsResponse; import com.yoti.api.client.docs.support.SupportedDocumentsResponse; import com.yoti.api.client.spi.remote.KeyStreamVisitor; +import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; +import com.yoti.api.client.spi.remote.call.factory.AuthTokenStrategy; +import com.yoti.api.client.spi.remote.call.factory.DocsSignedRequestStrategy; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; @@ -42,16 +42,11 @@ public class DocScanClient { Security.addProvider(new BouncyCastleProvider()); } - private final String sdkId; - private final KeyPair keyPair; - + private final AuthStrategy authStrategy; private final DocScanService docScanService; - DocScanClient(final String sdkId, - final KeyPairSource keyPairSource, - DocScanService docScanService) { - this.sdkId = sdkId; - this.keyPair = loadKeyPair(keyPairSource); + private DocScanClient(AuthStrategy authStrategy, DocScanService docScanService) { + this.authStrategy = authStrategy; this.docScanService = docScanService; } @@ -68,7 +63,7 @@ public static DocScanClient.Builder builder() { */ public CreateSessionResult createSession(SessionSpec sessionSpec) throws DocScanException { LOG.debug("Creating a YotiDocs session..."); - return docScanService.createSession(sdkId, keyPair, sessionSpec); + return docScanService.createSession(authStrategy, sessionSpec); } /** @@ -80,7 +75,7 @@ public CreateSessionResult createSession(SessionSpec sessionSpec) throws DocScan */ public GetSessionResult getSession(String sessionId) throws DocScanException { LOG.debug("Retrieving session '{}'", sessionId); - return docScanService.retrieveSession(sdkId, keyPair, sessionId); + return docScanService.retrieveSession(authStrategy, sessionId); } /** @@ -92,7 +87,7 @@ public GetSessionResult getSession(String sessionId) throws DocScanException { */ public void deleteSession(String sessionId) throws DocScanException { LOG.debug("Deleting session '{}'", sessionId); - docScanService.deleteSession(sdkId, keyPair, sessionId); + docScanService.deleteSession(authStrategy, sessionId); } /** @@ -106,7 +101,7 @@ public void deleteSession(String sessionId) throws DocScanException { */ public Media getMediaContent(String sessionId, String mediaId) throws DocScanException { LOG.debug("Retrieving media content '{}' in session '{}'", mediaId, sessionId); - return docScanService.getMediaContent(sdkId, keyPair, sessionId, mediaId); + return docScanService.getMediaContent(authStrategy, sessionId, mediaId); } /** @@ -119,7 +114,7 @@ public Media getMediaContent(String sessionId, String mediaId) throws DocScanExc */ public void deleteMediaContent(String sessionId, String mediaId) throws DocScanException { LOG.debug("Deleting media content '{}' in session '{}'", mediaId, sessionId); - docScanService.deleteMediaContent(sdkId, keyPair, sessionId, mediaId); + docScanService.deleteMediaContent(authStrategy, sessionId, mediaId); } /** @@ -131,7 +126,7 @@ public void deleteMediaContent(String sessionId, String mediaId) throws DocScanE */ public void putIbvInstructions(String sessionId, Instructions instructions) throws DocScanException { LOG.debug("Setting IBV instructions for session '{}'", sessionId); - docScanService.putIbvInstructions(sdkId, keyPair, sessionId, instructions); + docScanService.putIbvInstructions(authStrategy, sessionId, instructions); } /** @@ -143,7 +138,7 @@ public void putIbvInstructions(String sessionId, Instructions instructions) thro */ public Media getIbvInstructionsPdf(String sessionId) throws DocScanException { LOG.debug("Retrieving IBV instructions PDF in session '{}'", sessionId); - return docScanService.getIbvInstructionsPdf(sdkId, keyPair, sessionId); + return docScanService.getIbvInstructionsPdf(authStrategy, sessionId); } /** @@ -155,7 +150,7 @@ public Media getIbvInstructionsPdf(String sessionId) throws DocScanException { */ public ContactProfileResponse fetchInstructionsContactProfile(String sessionId) throws DocScanException { LOG.debug("Fetching instructions contact profile in session '{}'", sessionId); - return docScanService.fetchInstructionsContactProfile(sdkId, keyPair, sessionId); + return docScanService.fetchInstructionsContactProfile(authStrategy, sessionId); } /** @@ -169,7 +164,7 @@ public ContactProfileResponse fetchInstructionsContactProfile(String sessionId) */ public CreateFaceCaptureResourceResponse createFaceCaptureResource(String sessionId, CreateFaceCaptureResourcePayload createFaceCaptureResourcePayload) throws DocScanException { LOG.debug("Creating Face Capture resource in session '{}' for requirement '{}'", sessionId, createFaceCaptureResourcePayload.getRequirementId()); - return docScanService.createFaceCaptureResource(sdkId, keyPair, sessionId, createFaceCaptureResourcePayload); + return docScanService.createFaceCaptureResource(authStrategy, sessionId, createFaceCaptureResourcePayload); } /** @@ -181,7 +176,7 @@ public CreateFaceCaptureResourceResponse createFaceCaptureResource(String sessio */ public void uploadFaceCaptureImage(String sessionId, String resourceId, UploadFaceCaptureImagePayload uploadFaceCaptureImagePayload) throws DocScanException { LOG.debug("Uploading image to Face Capture resource '{}' for session '{}'", resourceId, sessionId); - docScanService.uploadFaceCaptureImage(sdkId, keyPair, sessionId, resourceId, uploadFaceCaptureImagePayload); + docScanService.uploadFaceCaptureImage(authStrategy, sessionId, resourceId, uploadFaceCaptureImagePayload); } /** @@ -193,7 +188,7 @@ public void uploadFaceCaptureImage(String sessionId, String resourceId, UploadFa */ public SupportedDocumentsResponse getSupportedDocuments(boolean includeNonLatin) throws DocScanException { LOG.debug("Getting all supported documents"); - return docScanService.getSupportedDocuments(keyPair, includeNonLatin); + return docScanService.getSupportedDocuments(includeNonLatin); } /** @@ -214,7 +209,7 @@ public SupportedDocumentsResponse getSupportedDocuments() throws DocScanExceptio */ public InstructionsResponse getIbvInstructions(String sessionId) throws DocScanException { LOG.debug("Fetching instructions for session '{}'", sessionId); - return docScanService.getIbvInstructions(sdkId, keyPair, sessionId); + return docScanService.getIbvInstructions(authStrategy, sessionId); } /** @@ -228,7 +223,7 @@ public InstructionsResponse getIbvInstructions(String sessionId) throws DocScanE */ public void triggerIbvEmailNotification(String sessionId) throws DocScanException { LOG.debug("Triggering IBV email notification for session '{}'", sessionId); - docScanService.triggerIbvEmailNotification(sdkId, keyPair, sessionId); + docScanService.triggerIbvEmailNotification(authStrategy, sessionId); } /** @@ -241,7 +236,7 @@ public void triggerIbvEmailNotification(String sessionId) throws DocScanExceptio */ public SessionConfigurationResponse getSessionConfiguration(String sessionId) throws DocScanException { LOG.debug("Fetching configuration for session '{}'", sessionId); - return docScanService.fetchSessionConfiguration(sdkId, keyPair, sessionId); + return docScanService.fetchSessionConfiguration(authStrategy, sessionId); } /** @@ -254,7 +249,7 @@ public SessionConfigurationResponse getSessionConfiguration(String sessionId) th */ public List getTrackedDevices(String sessionId) throws DocScanException { LOG.debug("Fetching tracked devices for session '{}'", sessionId); - return docScanService.getTrackedDevices(sdkId, keyPair, sessionId); + return docScanService.getTrackedDevices(authStrategy, sessionId); } /** @@ -266,25 +261,22 @@ public List getTrackedDevices(String sessionId) throws DocScan */ public void deleteTrackedDevices(String sessionId) throws DocScanException { LOG.debug("Deleting tracked devices for session '{}'", sessionId); - docScanService.deleteTrackedDevices(sdkId, keyPair, sessionId); - } - - private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException { - try { - LOG.debug("Loading key pair from '{}'", kpSource); - return kpSource.getFromStream(new KeyStreamVisitor()); - } catch (IOException e) { - throw new InitialisationException("Cannot load key pair", e); - } + docScanService.deleteTrackedDevices(authStrategy, sessionId); } public static class Builder { private static final DocScanService docScanService = DocScanService.newInstance(); + private String authenticationToken; private String sdkId; private KeyPairSource keyPairSource; + public Builder withAuthenticationToken(String authenticationToken) { + this.authenticationToken = authenticationToken; + return this; + } + public Builder withClientSdkId(String sdkId) { this.sdkId = sdkId; return this; @@ -296,15 +288,37 @@ public Builder withKeyPairSource(KeyPairSource kps) { } public DocScanClient build() { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPairSource, "Application key Pair"); - - return new DocScanClient( - sdkId, - keyPairSource, - docScanService - ); + if (authenticationToken == null) { + validateForSignedRequest(); + KeyPair keyPair = loadKeyPair(keyPairSource); + return new DocScanClient(new DocsSignedRequestStrategy(keyPair, sdkId), docScanService); + } else { + validateAuthToken(); + return new DocScanClient(new AuthTokenStrategy(authenticationToken), docScanService); + } } + + private void validateForSignedRequest() { + if (sdkId == null || sdkId.isEmpty() || keyPairSource == null) { + throw new IllegalStateException("An sdkId and KeyPairSource must be provided when not using an authentication token"); + } + } + + private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException { + try { + LOG.debug("Loading key pair from '{}'", kpSource); + return kpSource.getFromStream(new KeyStreamVisitor()); + } catch (IOException e) { + throw new InitialisationException("Cannot load key pair", e); + } + } + + private void validateAuthToken() { + if (sdkId != null || keyPairSource != null) { + throw new IllegalStateException("Must not supply sdkId or KeyPairSource when using an authentication token"); + } + } + } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java index 3d0bed70a..c52f4aa06 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java @@ -14,7 +14,6 @@ import java.io.IOException; import java.net.URISyntaxException; import java.security.GeneralSecurityException; -import java.security.KeyPair; import java.util.List; import java.util.Locale; import java.util.Map; @@ -37,6 +36,7 @@ import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.YotiHttpResponse; +import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.annotation.JsonInclude; @@ -75,7 +75,7 @@ private DocScanService(UnsignedPathFactory pathFactory, apiUrl = System.getProperty(PROPERTY_YOTI_DOCS_URL, DEFAULT_YOTI_DOCS_URL); } - public static DocScanService newInstance() { + static DocScanService newInstance() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); @@ -88,25 +88,23 @@ public static DocScanService newInstance() { /** * Uses the supplied session specification to create a session * - * @param sdkId the SDK ID - * @param keyPair the {@code KeyPair} - * @param sessionSpec the {@code SessionSpec} + * @param authStrategy the {@code AuthStrategy} + * @param sessionSpec the {@code SessionSpec} * @return the session creation result * @throws DocScanException if there was an error */ - public CreateSessionResult createSession(String sdkId, KeyPair keyPair, SessionSpec sessionSpec) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + CreateSessionResult createSession(AuthStrategy authStrategy, SessionSpec sessionSpec) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNull(sessionSpec, "sessionSpec"); - String path = unsignedPathFactory.createNewYotiDocsSessionPath(sdkId); + String path = unsignedPathFactory.createNewYotiDocsSessionPath(); LOG.info("Creating session at '{}'", path); try { byte[] payload = objectMapper.writeValueAsBytes(sessionSpec); YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_POST) @@ -129,23 +127,21 @@ public CreateSessionResult createSession(String sdkId, KeyPair keyPair, SessionS /** * Retrieves the current state of a given session * - * @param sdkId the SDK ID - * @param keyPair the {@code KeyPair} - * @param sessionId the session ID + * @param authStrategy the {@code AuthStrategy} + * @param sessionId the session ID * @return the session state * @throws DocScanException if there was an error */ - public GetSessionResult retrieveSession(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + GetSessionResult retrieveSession(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createYotiDocsSessionPath(sdkId, sessionId); + String path = unsignedPathFactory.createYotiDocsSessionPath(sessionId); LOG.info("Fetching session from '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) @@ -166,22 +162,20 @@ public GetSessionResult retrieveSession(String sdkId, KeyPair keyPair, String se /** * Deletes a session and all of its associated content * - * @param sdkId the SDK ID - * @param keyPair the {@code KeyPair} - * @param sessionId the session ID + * @param authStrategy the {@code AuthStrategy} + * @param sessionId the session ID * @throws DocScanException if there was an error */ - public void deleteSession(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + void deleteSession(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createYotiDocsSessionPath(sdkId, sessionId); + String path = unsignedPathFactory.createYotiDocsSessionPath(sessionId); LOG.info("Deleting session from '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_DELETE) @@ -202,25 +196,23 @@ public void deleteSession(String sdkId, KeyPair keyPair, String sessionId) throw /** * Retrieves {@link Media} content for a given session and media ID * - * @param sdkId the SDK ID - * @param keyPair the {@code KeyPair} - * @param sessionId the session ID - * @param mediaId the media ID + * @param authStrategy the {@code AuthStrategy} + * @param sessionId the session ID + * @param mediaId the media ID * @return the {@code Media} content, null if 204 No Content * @throws DocScanException if there was an error */ - public Media getMediaContent(String sdkId, KeyPair keyPair, String sessionId, String mediaId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + Media getMediaContent(AuthStrategy authStrategy, String sessionId, String mediaId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); notNullOrEmpty(mediaId, "mediaId"); - String path = unsignedPathFactory.createMediaContentPath(sdkId, sessionId, mediaId); + String path = unsignedPathFactory.createMediaContentPath(sessionId, mediaId); LOG.info("Fetching media from '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) @@ -243,24 +235,22 @@ public Media getMediaContent(String sdkId, KeyPair keyPair, String sessionId, St /** * Deletes media content for a given session and media ID * - * @param sdkId the SDK ID - * @param keyPair the {@code KeyPair} - * @param sessionId the session ID - * @param mediaId the media ID + * @param authStrategy the {@code AuthStrategy} + * @param sessionId the session ID + * @param mediaId the media ID * @throws DocScanException if there was an error */ - public void deleteMediaContent(String sdkId, KeyPair keyPair, String sessionId, String mediaId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + void deleteMediaContent(AuthStrategy authStrategy, String sessionId, String mediaId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); notNullOrEmpty(mediaId, "mediaId"); - String path = unsignedPathFactory.createMediaContentPath(sdkId, sessionId, mediaId); + String path = unsignedPathFactory.createMediaContentPath(sessionId, mediaId); LOG.info("Deleting media at '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_DELETE) @@ -276,20 +266,19 @@ public void deleteMediaContent(String sdkId, KeyPair keyPair, String sessionId, } } - public void putIbvInstructions(String sdkId, KeyPair keyPair, String sessionId, Instructions instructions) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + void putIbvInstructions(AuthStrategy authStrategy, String sessionId, Instructions instructions) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); notNull(instructions, "instructions"); - String path = unsignedPathFactory.createPutIbvInstructionsPath(sdkId, sessionId); + String path = unsignedPathFactory.createPutIbvInstructionsPath(sessionId); LOG.info("Setting IBV instructions at '{}'", path); try { byte[] payload = objectMapper.writeValueAsBytes(instructions); YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_PUT) @@ -306,17 +295,16 @@ public void putIbvInstructions(String sdkId, KeyPair keyPair, String sessionId, } } - public InstructionsResponse getIbvInstructions(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + InstructionsResponse getIbvInstructions(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createFetchIbvInstructionsPath(sdkId, sessionId); + String path = unsignedPathFactory.createFetchIbvInstructionsPath(sessionId); LOG.info("Fetching IBV instructions at '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) @@ -335,23 +323,21 @@ public InstructionsResponse getIbvInstructions(String sdkId, KeyPair keyPair, St /** * Retrieves the current state of a given session * - * @param sdkId the SDK ID - * @param keyPair the {@code KeyPair} - * @param sessionId the session ID + * @param authStrategy the {@code AuthStrategy} + * @param sessionId the session ID * @return the session state * @throws DocScanException if there was an error */ - public ContactProfileResponse fetchInstructionsContactProfile(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + ContactProfileResponse fetchInstructionsContactProfile(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createFetchInstructionsContactProfilePath(sdkId, sessionId); + String path = unsignedPathFactory.createFetchInstructionsContactProfilePath(sessionId); LOG.info("Fetching instruction contact profile from '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) @@ -367,17 +353,16 @@ public ContactProfileResponse fetchInstructionsContactProfile(String sdkId, KeyP } } - public Media getIbvInstructionsPdf(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + Media getIbvInstructionsPdf(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createFetchIbvInstructionsPdfPath(sdkId, sessionId); + String path = unsignedPathFactory.createFetchIbvInstructionsPdfPath(sessionId); LOG.info("Fetching instructions PDF at '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) @@ -397,17 +382,16 @@ public Media getIbvInstructionsPdf(String sdkId, KeyPair keyPair, String session } } - public SessionConfigurationResponse fetchSessionConfiguration(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + SessionConfigurationResponse fetchSessionConfiguration(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createFetchSessionConfigurationPath(sdkId, sessionId); + String path = unsignedPathFactory.createFetchSessionConfigurationPath(sessionId); LOG.info("Fetching session configuration from '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) @@ -423,23 +407,21 @@ public SessionConfigurationResponse fetchSessionConfiguration(String sdkId, KeyP } } - public CreateFaceCaptureResourceResponse createFaceCaptureResource(String sdkId, - KeyPair keyPair, + CreateFaceCaptureResourceResponse createFaceCaptureResource(AuthStrategy authStrategy, String sessionId, CreateFaceCaptureResourcePayload createFaceCaptureResourcePayload) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); notNull(createFaceCaptureResourcePayload, "createFaceCaptureResourcePayload"); - String path = unsignedPathFactory.createNewFaceCaptureResourcePath(sdkId, sessionId); + String path = unsignedPathFactory.createNewFaceCaptureResourcePath(sessionId); LOG.info("Creating new Face Capture resource at '{}'", path); try { byte[] payload = objectMapper.writeValueAsBytes(createFaceCaptureResourcePayload); YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withPayload(payload) @@ -456,15 +438,14 @@ public CreateFaceCaptureResourceResponse createFaceCaptureResource(String sdkId, } } - public void uploadFaceCaptureImage(String sdkId, KeyPair keyPair, String sessionId, String resourceId, UploadFaceCaptureImagePayload faceCaptureImagePayload) + void uploadFaceCaptureImage(AuthStrategy authStrategy, String sessionId, String resourceId, UploadFaceCaptureImagePayload faceCaptureImagePayload) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); notNullOrEmpty(resourceId, "resourceId"); notNull(faceCaptureImagePayload, "faceCaptureImagePayload"); - String path = unsignedPathFactory.createUploadFaceCaptureImagePath(sdkId, sessionId, resourceId); + String path = unsignedPathFactory.createUploadFaceCaptureImagePath(sessionId, resourceId); LOG.info("Uploading image to Face Capture resource at '{}'", path); try { @@ -475,7 +456,7 @@ public void uploadFaceCaptureImage(String sdkId, KeyPair keyPair, String session faceCaptureImagePayload.getImageContents(), ContentType.parse(faceCaptureImagePayload.getImageContentType()), "face-capture-image") - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_PUT) @@ -488,19 +469,15 @@ public void uploadFaceCaptureImage(String sdkId, KeyPair keyPair, String session } } - public SupportedDocumentsResponse getSupportedDocuments(KeyPair keyPair, boolean includeNonLatin) throws DocScanException { - notNull(keyPair, "Application key Pair"); - + SupportedDocumentsResponse getSupportedDocuments(boolean includeNonLatin) throws DocScanException { String path = unsignedPathFactory.createGetSupportedDocumentsPath(includeNonLatin); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) .build(); - return yotiHttpRequest.execute(SupportedDocumentsResponse.class); } catch (GeneralSecurityException | ResourceException ex) { throw new DocScanException("Error executing the GET: " + ex.getMessage(), ex); @@ -509,17 +486,16 @@ public SupportedDocumentsResponse getSupportedDocuments(KeyPair keyPair, boolean } } - public void triggerIbvEmailNotification(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + void triggerIbvEmailNotification(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createTriggerIbvEmailNotificationPath(sdkId, sessionId); + String path = unsignedPathFactory.createTriggerIbvEmailNotificationPath(sessionId); LOG.info("Triggering IBV email notification at '{}'", path); try { yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_POST) @@ -532,17 +508,16 @@ public void triggerIbvEmailNotification(String sdkId, KeyPair keyPair, String se } } - public List getTrackedDevices(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + List getTrackedDevices(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createFetchTrackedDevices(sdkId, sessionId); + String path = unsignedPathFactory.createFetchTrackedDevices(sessionId); LOG.info("Fetching tracked devices at '{}'", path); try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) @@ -556,17 +531,16 @@ public List getTrackedDevices(String sdkId, KeyPair keyPair, S } } - public void deleteTrackedDevices(String sdkId, KeyPair keyPair, String sessionId) throws DocScanException { - notNullOrEmpty(sdkId, "SDK ID"); - notNull(keyPair, "Application key Pair"); + void deleteTrackedDevices(AuthStrategy authStrategy, String sessionId) throws DocScanException { + notNull(authStrategy, "authStrategy"); notNullOrEmpty(sessionId, "sessionId"); - String path = unsignedPathFactory.createDeleteTrackedDevices(sdkId, sessionId); + String path = unsignedPathFactory.createDeleteTrackedDevices(sessionId); LOG.info("Deleting tracked devices at '{}'", path); try { yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_DELETE) @@ -590,5 +564,4 @@ private String findContentType(YotiHttpResponse response) { return contentTypeValues == null || contentTypeValues.isEmpty() ? "" : contentTypeValues.get(0); } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/ReceiptFetcher.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/ReceiptFetcher.java index e55baeea1..4d3cb63b7 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/ReceiptFetcher.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/ReceiptFetcher.java @@ -27,17 +27,17 @@ private ReceiptFetcher(ProfileService profileService) { this.profileService = profileService; } - public static ReceiptFetcher newInstance() { - return new ReceiptFetcher(ProfileService.newInstance()); + public static ReceiptFetcher newInstance(KeyPair keyPair, String appId) { + return new ReceiptFetcher(ProfileService.newInstance(keyPair, appId)); } - public Receipt fetch(String encryptedConnectToken, KeyPair keyPair, String appId) throws ProfileException { + public Receipt fetch(String encryptedConnectToken, KeyPair keyPair) throws ProfileException { LOG.debug("Decrypting connect token: '{}'", encryptedConnectToken); String connectToken = decryptConnectToken(encryptedConnectToken, keyPair.getPrivate()); LOG.debug("Connect token decrypted: '{}'", connectToken); - ProfileResponse profile = profileService.getProfile(keyPair, appId, connectToken); + ProfileResponse profile = profileService.getProfile(keyPair, connectToken); validateReceipt(profile, connectToken); return profile.getReceipt(); } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java index 3aa6915c2..2bc2f9a2f 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java @@ -18,6 +18,7 @@ import java.util.Base64; import com.yoti.api.client.ProfileException; +import com.yoti.api.client.spi.remote.call.factory.ProfileSignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -31,39 +32,41 @@ public class ProfileService { private final UnsignedPathFactory unsignedPathFactory; private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String apiUrl; + private final ProfileSignedRequestStrategy profileSignedRequestStrategy; static { Security.addProvider(new BouncyCastleProvider()); } - public static ProfileService newInstance() { + public static ProfileService newInstance(KeyPair keyPair, String appId) { return new ProfileService( new UnsignedPathFactory(), - new YotiHttpRequestBuilderFactory()); + new YotiHttpRequestBuilderFactory(), + new ProfileSignedRequestStrategy(keyPair, appId)); } - ProfileService(UnsignedPathFactory profilePathFactory, YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { - this.unsignedPathFactory = profilePathFactory; + private ProfileService(UnsignedPathFactory unsignedPathFactory, + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory, + ProfileSignedRequestStrategy profileSignedRequestStrategy) { + this.unsignedPathFactory = unsignedPathFactory; this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; - + this.profileSignedRequestStrategy = profileSignedRequestStrategy; apiUrl = System.getProperty(PROPERTY_YOTI_API_URL, DEFAULT_YOTI_API_URL); } - public Receipt getReceipt(KeyPair keyPair, String appId, String connectToken) throws ProfileException { - return getProfile(keyPair, appId, connectToken).getReceipt(); + public Receipt getReceipt(KeyPair keyPair, String connectToken) throws ProfileException { + return getProfile(keyPair, connectToken).getReceipt(); } - public ProfileResponse getProfile(KeyPair keyPair, String appId, String connectToken) throws ProfileException { + public ProfileResponse getProfile(KeyPair keyPair, String connectToken) throws ProfileException { notNull(keyPair, "Key pair"); - notNull(appId, "Application id"); notNull(connectToken, "Connect token"); - String path = unsignedPathFactory.createProfilePath(appId, connectToken); + String path = unsignedPathFactory.createProfilePath(connectToken); try { String authKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); - - YotiHttpRequest yotiHttpRequest = createSignedRequest(keyPair, path, authKey); + YotiHttpRequest yotiHttpRequest = createSignedRequest(path, authKey); return fetchReceipt(yotiHttpRequest); } catch (IOException ioe) { throw new ProfileException("Error calling service to get profile", ioe); @@ -88,10 +91,10 @@ private ProfileResponse fetchReceipt(YotiHttpRequest yotiHttpRequest) throws IOE } } - YotiHttpRequest createSignedRequest(KeyPair keyPair, String path, String authKey) throws ProfileException { + YotiHttpRequest createSignedRequest(String path, String authKey) throws ProfileException { try { return yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(profileSignedRequestStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java index ae1f62831..a87a5ddfc 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java @@ -22,6 +22,7 @@ private YotiConstants() {} public static final String DIGEST_HEADER = "X-Yoti-Auth-Digest"; public static final String YOTI_SDK_HEADER = "X-Yoti-SDK"; public static final String YOTI_SDK_VERSION_HEADER = YOTI_SDK_HEADER + "-Version"; + public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String CONTENT_TYPE = "Content-Type"; public static final String CONTENT_TYPE_JSON = "application/json"; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java index c742c636c..7e82311f8 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java @@ -14,20 +14,28 @@ import java.security.GeneralSecurityException; import java.security.KeyPair; import java.util.HashMap; +import java.util.List; import java.util.Map; +import com.yoti.api.client.spi.remote.call.factory.AmlSignedRequestStrategy; +import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; +import com.yoti.api.client.spi.remote.call.factory.AuthTokenStrategy; +import com.yoti.api.client.spi.remote.call.factory.DigitalIdentitySignedRequestStrategy; +import com.yoti.api.client.spi.remote.call.factory.DocsSignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.HeadersFactory; -import com.yoti.api.client.spi.remote.call.factory.PathFactory; -import com.yoti.api.client.spi.remote.call.factory.SignedMessageFactory; +import com.yoti.api.client.spi.remote.call.factory.ProfileSignedRequestStrategy; +import com.yoti.api.client.spi.remote.call.factory.SimpleSignedRequestStrategy; import com.yoti.validation.Validation; +import org.apache.http.Header; import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; public class YotiHttpRequestBuilder { - private KeyPair keyPair; + private AuthStrategy authStrategy; private String baseUrl; private String endpoint; private byte[] payload; @@ -35,22 +43,16 @@ public class YotiHttpRequestBuilder { private final Map headers = new HashMap<>(); private String httpMethod; - private final PathFactory pathFactory; - private final SignedMessageFactory signedMessageFactory; private final HeadersFactory headersFactory; private final JsonResourceFetcher jsonResourceFetcher; private final RawResourceFetcher rawResourceFetcher; private final ImageResourceFetcher imageResourceFetcher; private MultipartEntityBuilder multipartEntityBuilder; - YotiHttpRequestBuilder(PathFactory pathFactory, - SignedMessageFactory signedMessageFactory, - HeadersFactory headersFactory, + YotiHttpRequestBuilder(HeadersFactory headersFactory, JsonResourceFetcher jsonResourceFetcher, RawResourceFetcher rawResourceFetcher, ImageResourceFetcher imageResourceFetcher) { - this.pathFactory = pathFactory; - this.signedMessageFactory = signedMessageFactory; this.headersFactory = headersFactory; this.jsonResourceFetcher = jsonResourceFetcher; this.rawResourceFetcher = rawResourceFetcher; @@ -60,11 +62,41 @@ public class YotiHttpRequestBuilder { /** * Proceed building the signed request with a specific key pair * - * @param keyPair the key pair + * @param authStrategy the key pair * @return the updated builder */ - public YotiHttpRequestBuilder withKeyPair(KeyPair keyPair) { - this.keyPair = keyPair; + public YotiHttpRequestBuilder withAuthStrategy(AuthStrategy authStrategy) { + this.authStrategy = authStrategy; + return this; + } + + public YotiHttpRequestBuilder forAuthTokenRequest(String authToken) { + this.authStrategy = new AuthTokenStrategy(authToken); + return this; + } + + public YotiHttpRequestBuilder forDocsSignedRequest(KeyPair keyPair, String sdkId) { + this.authStrategy = new DocsSignedRequestStrategy(keyPair, sdkId); + return this; + } + + public YotiHttpRequestBuilder forAmlSignedRequest(KeyPair keyPair, String appId) { + this.authStrategy = new AmlSignedRequestStrategy(keyPair, appId); + return this; + } + + public YotiHttpRequestBuilder forProfileRequest(KeyPair keyPair, String appId) { + this.authStrategy = new ProfileSignedRequestStrategy(keyPair, appId); + return this; + } + + public YotiHttpRequestBuilder forDigitalIdentityRequest(KeyPair keyPair, String appId) { + this.authStrategy = new DigitalIdentitySignedRequestStrategy(keyPair, appId); + return this; + } + + public YotiHttpRequestBuilder forSignedRequest(KeyPair keyPair) { + this.authStrategy = new SimpleSignedRequestStrategy(keyPair); return this; } @@ -188,14 +220,7 @@ public YotiHttpRequestBuilder withMultipartBinaryBody(String name, byte[] payloa */ public YotiHttpRequest build() throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { validateRequest(); - - if (endpoint.contains("?")) { - endpoint = endpoint.concat("&"); - } else { - endpoint = endpoint.concat("?"); - } - - String builtEndpoint = endpoint + createQueryParameterString(queryParameters); + String builtEndpoint = endpoint + createQueryParameterString(); byte[] finalPayload; if (multipartEntityBuilder == null) { @@ -213,8 +238,8 @@ public YotiHttpRequest build() throws GeneralSecurityException, UnsupportedEncod } } - String digest = createDigest(builtEndpoint, finalPayload); - headers.putAll(headersFactory.create(digest)); + List
authHeaders = authStrategy.createAuthHeaders(httpMethod, builtEndpoint, finalPayload); + headers.putAll(headersFactory.create(authHeaders)); return new YotiHttpRequest( new URI(baseUrl + builtEndpoint), @@ -227,30 +252,38 @@ public YotiHttpRequest build() throws GeneralSecurityException, UnsupportedEncod } private void validateRequest() { - Validation.notNull(keyPair, "keyPair"); + Validation.notNull(authStrategy, "authStrategy"); Validation.notNullOrEmpty(baseUrl, "baseUrl"); Validation.notNullOrEmpty(endpoint, "endpoint"); Validation.notNullOrEmpty(httpMethod, "httpMethod"); } - private String createQueryParameterString(Map queryParameters) throws UnsupportedEncodingException { + private String createQueryParameterString() throws UnsupportedEncodingException { StringBuilder stringBuilder = new StringBuilder(); + for (Map.Entry entry : queryParameters.entrySet()) { + if (stringBuilder.length() > 0) { + stringBuilder.append("&"); + } stringBuilder.append(entry.getKey()); stringBuilder.append("="); stringBuilder.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.toString())); - stringBuilder.append("&"); } - stringBuilder.append(pathFactory.createSignatureParams()); - return stringBuilder.toString(); - } - private String createDigest(String endpoint, byte[] payload) throws GeneralSecurityException { - if (payload != null) { - return signedMessageFactory.create(keyPair.getPrivate(), httpMethod, endpoint, payload); - } else { - return signedMessageFactory.create(keyPair.getPrivate(), httpMethod, endpoint); + for (NameValuePair queryParam : authStrategy.createQueryParams()) { + if (stringBuilder.length() > 0) { + stringBuilder.append("&"); + } + stringBuilder.append(queryParam); } + + String built = stringBuilder.toString(); + if (built.isEmpty()) { + return built; + } + + String prefix = endpoint.contains("?") ? "&" : "?"; + return prefix.concat(built); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java index e97285211..62116e7a1 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java @@ -1,21 +1,15 @@ package com.yoti.api.client.spi.remote.call; import com.yoti.api.client.spi.remote.call.factory.HeadersFactory; -import com.yoti.api.client.spi.remote.call.factory.PathFactory; -import com.yoti.api.client.spi.remote.call.factory.SignedMessageFactory; public class YotiHttpRequestBuilderFactory { - private static final PathFactory pathFactory; - private static final SignedMessageFactory signedMessageFactory; private static final HeadersFactory headersFactory; private static final JsonResourceFetcher jsonResourceFetcher; private static final RawResourceFetcher rawResourceFetcher; private static final ImageResourceFetcher imageResourceFetcher; static { - pathFactory = new PathFactory(); - signedMessageFactory = SignedMessageFactory.newInstance(); headersFactory = new HeadersFactory(); rawResourceFetcher = new RawResourceFetcher(); jsonResourceFetcher = JsonResourceFetcher.newInstance(rawResourceFetcher); @@ -23,7 +17,7 @@ public class YotiHttpRequestBuilderFactory { } public YotiHttpRequestBuilder create() { - return new YotiHttpRequestBuilder(pathFactory, signedMessageFactory, headersFactory, jsonResourceFetcher, rawResourceFetcher, imageResourceFetcher); + return new YotiHttpRequestBuilder(headersFactory, jsonResourceFetcher, rawResourceFetcher, imageResourceFetcher); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java index 7ecbc3741..d0a7c7807 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java @@ -22,6 +22,7 @@ import com.yoti.api.client.spi.remote.call.ResourceException; import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.AmlSignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.databind.ObjectMapper; @@ -32,35 +33,37 @@ public class RemoteAmlService { private final ObjectMapper objectMapper; private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String apiUrl; + private final AmlSignedRequestStrategy amlSignedRequestStrategy; - public static RemoteAmlService newInstance() { + public static RemoteAmlService newInstance(KeyPair keyPair, String appId) { return new RemoteAmlService( new UnsignedPathFactory(), new ObjectMapper(), - new YotiHttpRequestBuilderFactory() + new YotiHttpRequestBuilderFactory(), + new AmlSignedRequestStrategy(keyPair, appId) ); } - RemoteAmlService(UnsignedPathFactory unsignedPathFactory, + private RemoteAmlService(UnsignedPathFactory unsignedPathFactory, ObjectMapper objectMapper, - YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory, + AmlSignedRequestStrategy amlSignedRequestStrategy) { this.unsignedPathFactory = unsignedPathFactory; this.objectMapper = objectMapper; this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; + this.amlSignedRequestStrategy = amlSignedRequestStrategy; apiUrl = System.getProperty(PROPERTY_YOTI_API_URL, DEFAULT_YOTI_API_URL); } - public AmlResult performCheck(KeyPair keyPair, String appId, AmlProfile amlProfile) throws AmlException { - notNull(keyPair, "Key pair"); - notNull(appId, "Application id"); + public AmlResult performCheck(AmlProfile amlProfile) throws AmlException { notNull(amlProfile, "amlProfile"); try { - String resourcePath = unsignedPathFactory.createAmlPath(appId); + String resourcePath = unsignedPathFactory.createAmlPath(); byte[] body = objectMapper.writeValueAsString(amlProfile).getBytes(DEFAULT_CHARSET); - YotiHttpRequest yotiHttpRequest = createSignedRequest(keyPair, resourcePath, body); + YotiHttpRequest yotiHttpRequest = createSignedRequest(resourcePath, body); return yotiHttpRequest.execute(AmlResult.class); } catch (IOException ioException) { throw new AmlException("Error communicating with AML endpoint", ioException); @@ -69,23 +72,23 @@ public AmlResult performCheck(KeyPair keyPair, String appId, AmlProfile amlProfi } } - private AmlException createExceptionFromStatusCode(ResourceException e) { - switch (e.getResponseCode()) { + private AmlException createExceptionFromStatusCode(ResourceException ex) { + switch (ex.getResponseCode()) { case HTTP_BAD_REQUEST: - return new AmlException("Failed validation:\n" + e.getResponseBody(), e); + return new AmlException("Failed validation:\n" + ex.getResponseBody(), ex); case HTTP_UNAUTHORIZED: - return new AmlException("Failed authorization with the given key:\n" + e.getResponseBody(), e); + return new AmlException("Failed authorization with the given key:\n" + ex.getResponseBody(), ex); case HTTP_INTERNAL_ERROR: - return new AmlException("An unexpected error occured on the server:\n" + e.getResponseBody(), e); + return new AmlException("An unexpected error occured on the server:\n" + ex.getResponseBody(), ex); default: - return new AmlException("Unexpected error:\n" + e.getResponseBody(), e); + return new AmlException("Unexpected error:\n" + ex.getResponseBody(), ex); } } - YotiHttpRequest createSignedRequest(KeyPair keyPair, String resourcePath, byte[] body) throws AmlException { + YotiHttpRequest createSignedRequest(String resourcePath, byte[] body) throws AmlException { try { return yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(amlSignedRequestStrategy) .withBaseUrl(apiUrl) .withEndpoint(resourcePath) .withPayload(body) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AmlSignedRequestStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AmlSignedRequestStrategy.java new file mode 100644 index 000000000..4682816e9 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AmlSignedRequestStrategy.java @@ -0,0 +1,35 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; + +public class AmlSignedRequestStrategy extends SignedRequestStrategy { + + private final String sdkId; + + public AmlSignedRequestStrategy(KeyPair keyPair, String sdkId) { + super(keyPair); + this.sdkId = sdkId; + } + + @Override + public List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException { + return Collections.singletonList(createDigestHeader(httpMethod, endpoint, payload)); + } + + @Override + public List createQueryParams() { + List queryParams = new ArrayList<>(); + queryParams.add(new BasicNameValuePair("appId", sdkId)); + queryParams.addAll(createSignedRequestParams()); + return queryParams; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthStrategy.java new file mode 100644 index 000000000..3b675c1c3 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthStrategy.java @@ -0,0 +1,15 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import java.security.GeneralSecurityException; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; + +public interface AuthStrategy { + + List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException; + + List createQueryParams(); + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthTokenStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthTokenStrategy.java new file mode 100644 index 000000000..c67be0c98 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/AuthTokenStrategy.java @@ -0,0 +1,30 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import java.util.Collections; +import java.util.List; + +import com.yoti.api.client.spi.remote.call.YotiConstants; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicHeader; + +public class AuthTokenStrategy implements AuthStrategy { + + private final String authenticationToken; + + public AuthTokenStrategy(String authenticationToken) { + this.authenticationToken = authenticationToken; + } + + @Override + public List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) { + return Collections.singletonList(new BasicHeader(YotiConstants.AUTHORIZATION_HEADER, "Bearer " + authenticationToken)); + } + + @Override + public List createQueryParams() { + return Collections.emptyList(); + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DigitalIdentitySignedRequestStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DigitalIdentitySignedRequestStrategy.java new file mode 100644 index 000000000..9e7a28a50 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DigitalIdentitySignedRequestStrategy.java @@ -0,0 +1,33 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import static com.yoti.api.client.spi.remote.call.YotiConstants.AUTH_ID_HEADER; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.util.Arrays; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicHeader; + +public class DigitalIdentitySignedRequestStrategy extends SignedRequestStrategy { + + private final String sdkId; + + public DigitalIdentitySignedRequestStrategy(KeyPair keyPair, String sdkId) { + super(keyPair); + this.sdkId = sdkId; + } + + @Override + public List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException { + return Arrays.asList(createDigestHeader(httpMethod, endpoint, payload), new BasicHeader(AUTH_ID_HEADER, sdkId)); + } + + @Override + public List createQueryParams() { + return createSignedRequestParams(); + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DocsSignedRequestStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DocsSignedRequestStrategy.java new file mode 100644 index 000000000..ba0362a85 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/DocsSignedRequestStrategy.java @@ -0,0 +1,35 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; + +public class DocsSignedRequestStrategy extends SignedRequestStrategy { + + private final String sdkId; + + public DocsSignedRequestStrategy(KeyPair keyPair, String sdkId) { + super(keyPair); + this.sdkId = sdkId; + } + + @Override + public List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException { + return Collections.singletonList(createDigestHeader(httpMethod, endpoint, payload)); + } + + @Override + public List createQueryParams() { + List queryParams = new ArrayList<>(); + queryParams.add(new BasicNameValuePair("sdkId", sdkId)); + queryParams.addAll(createSignedRequestParams()); + return queryParams; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactory.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactory.java index a359b625c..43a1d4b03 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactory.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactory.java @@ -1,30 +1,26 @@ package com.yoti.api.client.spi.remote.call.factory; -import static com.yoti.api.client.spi.remote.call.YotiConstants.AUTH_KEY_HEADER; -import static com.yoti.api.client.spi.remote.call.YotiConstants.DIGEST_HEADER; import static com.yoti.api.client.spi.remote.call.YotiConstants.JAVA; import static com.yoti.api.client.spi.remote.call.YotiConstants.SDK_VERSION; import static com.yoti.api.client.spi.remote.call.YotiConstants.YOTI_SDK_HEADER; import static com.yoti.api.client.spi.remote.call.YotiConstants.YOTI_SDK_VERSION_HEADER; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.apache.http.Header; + public class HeadersFactory { - public Map create(String digest) { + public Map create(List
authHeaders) { Map headers = new HashMap<>(); - headers.put(DIGEST_HEADER, digest); + for (Header authHeader : authHeaders) { + headers.put(authHeader.getName(), authHeader.getValue()); + } headers.put(YOTI_SDK_HEADER, JAVA); headers.put(YOTI_SDK_VERSION_HEADER, SDK_VERSION); return headers; } - @Deprecated - public Map create(String digest, String authKey) { - Map headers = create(digest); - headers.put(AUTH_KEY_HEADER, authKey); - return headers; - } - } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/PathFactory.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/PathFactory.java deleted file mode 100644 index 9bb9a1fc8..000000000 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/PathFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.yoti.api.client.spi.remote.call.factory; - -import static java.lang.System.nanoTime; -import static java.util.UUID.randomUUID; - -public class PathFactory { - - private static final String SIGNATURE_PARAMS = "nonce=%s×tamp=%s"; - - private UnsignedPathFactory unsignedPathFactory; - - public PathFactory() { - this.unsignedPathFactory = new UnsignedPathFactory(); - } - - public String createSignatureParams() { - return String.format(SIGNATURE_PARAMS, randomUUID(), createTimestamp()); - } - - public String createProfilePath(String appId, String connectToken) { - return unsignedPathFactory.createProfilePath(appId, connectToken) + "&" + createSignatureParams(); - } - - public String createAmlPath(String appId) { - return unsignedPathFactory.createAmlPath(appId) + "&" + createSignatureParams(); - } - - public String createDynamicSharingPath(String appId) { - return unsignedPathFactory.createDynamicSharingPath(appId) + "?" + createSignatureParams(); - } - - public String createNewYotiDocsSessionPath(String appId) { - return unsignedPathFactory.createNewYotiDocsSessionPath(appId) + "&" + createSignatureParams(); - } - - public String createGetYotiDocsSessionPath(String appId, String sessionId) { - return unsignedPathFactory.createYotiDocsSessionPath(appId, sessionId) + "&" + createSignatureParams(); - } - - public String createMediaContentPath(String appId, String sessionId, String mediaId) { - return unsignedPathFactory.createMediaContentPath(appId, sessionId, mediaId) + "&" + createSignatureParams(); - } - - public String createGetSupportedDocumentsPath(boolean includeNonLatin) { - return unsignedPathFactory.createGetSupportedDocumentsPath(includeNonLatin) + "&" + createSignatureParams(); - } - - protected long createTimestamp() { - return nanoTime() / 1000; - } - -} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/ProfileSignedRequestStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/ProfileSignedRequestStrategy.java new file mode 100644 index 000000000..f434baee4 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/ProfileSignedRequestStrategy.java @@ -0,0 +1,35 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; + +public class ProfileSignedRequestStrategy extends SignedRequestStrategy { + + private final String sdkId; + + public ProfileSignedRequestStrategy(KeyPair keyPair, String sdkId) { + super(keyPair); + this.sdkId = sdkId; + } + + @Override + public List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException { + return Collections.singletonList(createDigestHeader(httpMethod, endpoint, payload)); + } + + @Override + public List createQueryParams() { + List queryParams = new ArrayList<>(); + queryParams.add(new BasicNameValuePair("appId", sdkId)); + queryParams.addAll(createSignedRequestParams()); + return queryParams; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SignedRequestStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SignedRequestStrategy.java new file mode 100644 index 000000000..254a21318 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SignedRequestStrategy.java @@ -0,0 +1,49 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import static java.lang.System.nanoTime; +import static java.util.UUID.randomUUID; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.util.ArrayList; +import java.util.List; + +import com.yoti.api.client.spi.remote.call.YotiConstants; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicNameValuePair; + +abstract class SignedRequestStrategy implements AuthStrategy { + + private static final SignedMessageFactory signedMessageFactory; + + static { + signedMessageFactory = SignedMessageFactory.newInstance(); + } + + private final KeyPair keyPair; + + SignedRequestStrategy(KeyPair keyPair) { + this.keyPair = keyPair; + } + + protected Header createDigestHeader(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException { + String digest; + if (payload == null) { + digest = signedMessageFactory.create(keyPair.getPrivate(), httpMethod, endpoint); + } else { + digest = signedMessageFactory.create(keyPair.getPrivate(), httpMethod, endpoint, payload); + } + return new BasicHeader(YotiConstants.DIGEST_HEADER, digest); + } + + protected List createSignedRequestParams() { + List queryParams = new ArrayList<>(); + queryParams.add(new BasicNameValuePair("nonce", randomUUID().toString())); + queryParams.add(new BasicNameValuePair("timestamp", Long.toString(nanoTime() / 1000))); + return queryParams; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SimpleSignedRequestStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SimpleSignedRequestStrategy.java new file mode 100644 index 000000000..8fdf05bce --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/SimpleSignedRequestStrategy.java @@ -0,0 +1,27 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.util.Collections; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; + +public class SimpleSignedRequestStrategy extends SignedRequestStrategy { + + public SimpleSignedRequestStrategy(KeyPair keyPair) { + super(keyPair); + } + + @Override + public List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException { + return Collections.singletonList(createDigestHeader(httpMethod, endpoint, payload)); + } + + @Override + public List createQueryParams() { + return createSignedRequestParams(); + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java index 15ec5eaa6..56e3440ab 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java @@ -5,7 +5,7 @@ public class UnsignedPathFactory { // AML - private static final String AML = "/aml-check?appId=%s"; + private static final String AML = "/aml-check"; // Share V2 private static final String IDENTITY_SESSION_CREATION = "/v2/sessions"; @@ -19,26 +19,26 @@ public class UnsignedPathFactory { private static final String DIGITAL_ID_MATCH = "/v1/matches"; // Share V1 - private static final String PROFILE = "/profile/%s?appId=%s"; + private static final String PROFILE = "/profile/%s"; private static final String QR_CODE = "/qrcodes/apps/%s"; // Docs - private static final String DOCS_CREATE_SESSION = "/sessions?sdkId=%s"; - private static final String DOCS_SESSION = "/sessions/%s?sdkId=%s"; - private static final String DOCS_MEDIA_CONTENT = "/sessions/%s/media/%s/content?sdkId=%s"; - private static final String DOCS_PUT_IBV_INSTRUCTIONS = "/sessions/%s/instructions?sdkId=%s"; - private static final String DOCS_FETCH_IBV_INSTRUCTIONS = "/sessions/%s/instructions?sdkId=%s"; - private static final String DOCS_FETCH_IBV_INSTRUCTIONS_PDF = "/sessions/%s/instructions/pdf?sdkId=%s"; + private static final String DOCS_CREATE_SESSION = "/sessions"; + private static final String DOCS_SESSION = "/sessions/%s"; + private static final String DOCS_MEDIA_CONTENT = "/sessions/%s/media/%s/content"; + private static final String DOCS_PUT_IBV_INSTRUCTIONS = "/sessions/%s/instructions"; + private static final String DOCS_FETCH_IBV_INSTRUCTIONS = "/sessions/%s/instructions"; + private static final String DOCS_FETCH_IBV_INSTRUCTIONS_PDF = "/sessions/%s/instructions/pdf"; private static final String DOCS_SUPPORTED_DOCUMENTS = "/supported-documents?includeNonLatin=%s"; - private static final String DOCS_FETCH_INSTRUCTION_CONTACT_PROFILE = "/sessions/%s/instructions/contact-profile?sdkId=%s"; - private static final String DOCS_FETCH_SESSION_CONFIGURATION = "/sessions/%s/configuration?sdkId=%s"; - private static final String DOCS_NEW_FACE_CAPTURE_RESOURCE = "/sessions/%s/resources/face-capture?sdkId=%s"; - private static final String DOCS_UPLOAD_FACE_CAPTURE_IMAGE = "/sessions/%s/resources/face-capture/%s/image?sdkId=%s"; - private static final String DOCS_TRIGGER_IBV_NOTIFICATION = "/sessions/%s/instructions/email?sdkId=%s"; - private static final String DOCS_TRACKED_DEVICES = "/sessions/%s/tracked-devices?sdkId=%s"; + private static final String DOCS_FETCH_INSTRUCTION_CONTACT_PROFILE = "/sessions/%s/instructions/contact-profile"; + private static final String DOCS_FETCH_SESSION_CONFIGURATION = "/sessions/%s/configuration"; + private static final String DOCS_NEW_FACE_CAPTURE_RESOURCE = "/sessions/%s/resources/face-capture"; + private static final String DOCS_UPLOAD_FACE_CAPTURE_IMAGE = "/sessions/%s/resources/face-capture/%s/image"; + private static final String DOCS_TRIGGER_IBV_NOTIFICATION = "/sessions/%s/instructions/email"; + private static final String DOCS_TRACKED_DEVICES = "/sessions/%s/tracked-devices"; - public String createAmlPath(String appId) { - return format(AML, appId); + public String createAmlPath() { + return format(AML); } public String createIdentitySessionPath() { @@ -73,68 +73,68 @@ public String createIdentityMatchPath() { return DIGITAL_ID_MATCH; } - public String createProfilePath(String appId, String connectToken) { - return format(PROFILE, connectToken, appId); + public String createProfilePath(String connectToken) { + return format(PROFILE, connectToken); } public String createDynamicSharingPath(String appId) { return format(QR_CODE, appId); } - public String createNewYotiDocsSessionPath(String appId) { - return format(DOCS_CREATE_SESSION, appId); + public String createNewYotiDocsSessionPath() { + return DOCS_CREATE_SESSION; } - public String createYotiDocsSessionPath(String appId, String sessionId) { - return format(DOCS_SESSION, sessionId, appId); + public String createYotiDocsSessionPath(String sessionId) { + return format(DOCS_SESSION, sessionId); } - public String createMediaContentPath(String appId, String sessionId, String mediaId) { - return format(DOCS_MEDIA_CONTENT, sessionId, mediaId, appId); + public String createMediaContentPath(String sessionId, String mediaId) { + return format(DOCS_MEDIA_CONTENT, sessionId, mediaId); } - public String createPutIbvInstructionsPath(String appId, String sessionId) { - return format(DOCS_PUT_IBV_INSTRUCTIONS, sessionId, appId); + public String createPutIbvInstructionsPath(String sessionId) { + return format(DOCS_PUT_IBV_INSTRUCTIONS, sessionId); } - public String createFetchIbvInstructionsPath(String appId, String sessionId) { - return format(DOCS_FETCH_IBV_INSTRUCTIONS, sessionId, appId); + public String createFetchIbvInstructionsPath(String sessionId) { + return format(DOCS_FETCH_IBV_INSTRUCTIONS, sessionId); } - public String createFetchIbvInstructionsPdfPath(String sdkId, String sessionId) { - return format(DOCS_FETCH_IBV_INSTRUCTIONS_PDF, sessionId, sdkId); + public String createFetchIbvInstructionsPdfPath(String sessionId) { + return format(DOCS_FETCH_IBV_INSTRUCTIONS_PDF, sessionId); } public String createGetSupportedDocumentsPath(boolean includeNonLatin) { return format(DOCS_SUPPORTED_DOCUMENTS, includeNonLatin); } - public String createFetchInstructionsContactProfilePath(String appId, String sessionId) { - return format(DOCS_FETCH_INSTRUCTION_CONTACT_PROFILE, sessionId, appId); + public String createFetchInstructionsContactProfilePath(String sessionId) { + return format(DOCS_FETCH_INSTRUCTION_CONTACT_PROFILE, sessionId); } - public String createFetchSessionConfigurationPath(String sdkId, String sessionId) { - return format(DOCS_FETCH_SESSION_CONFIGURATION, sessionId, sdkId); + public String createFetchSessionConfigurationPath(String sessionId) { + return format(DOCS_FETCH_SESSION_CONFIGURATION, sessionId); } - public String createNewFaceCaptureResourcePath(String sdkId, String sessionId) { - return format(DOCS_NEW_FACE_CAPTURE_RESOURCE, sessionId, sdkId); + public String createNewFaceCaptureResourcePath(String sessionId) { + return format(DOCS_NEW_FACE_CAPTURE_RESOURCE, sessionId); } - public String createUploadFaceCaptureImagePath(String sdkId, String sessionId, String resourceId) { - return format(DOCS_UPLOAD_FACE_CAPTURE_IMAGE, sessionId, resourceId, sdkId); + public String createUploadFaceCaptureImagePath(String sessionId, String resourceId) { + return format(DOCS_UPLOAD_FACE_CAPTURE_IMAGE, sessionId, resourceId); } - public String createTriggerIbvEmailNotificationPath(String sdkId, String sessionId) { - return format(DOCS_TRIGGER_IBV_NOTIFICATION, sessionId, sdkId); + public String createTriggerIbvEmailNotificationPath(String sessionId) { + return format(DOCS_TRIGGER_IBV_NOTIFICATION, sessionId); } - public String createFetchTrackedDevices(String sdkId, String sessionId) { - return format(DOCS_TRACKED_DEVICES, sessionId, sdkId); + public String createFetchTrackedDevices(String sessionId) { + return format(DOCS_TRACKED_DEVICES, sessionId); } - public String createDeleteTrackedDevices(String sdkId, String sessionId) { - return format(DOCS_TRACKED_DEVICES, sessionId, sdkId); + public String createDeleteTrackedDevices(String sessionId) { + return format(DOCS_TRACKED_DEVICES, sessionId); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java index 5c0bb9450..5fced1179 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java @@ -2,7 +2,6 @@ import static com.yoti.api.client.spi.remote.call.HttpMethod.HTTP_GET; import static com.yoti.api.client.spi.remote.call.HttpMethod.HTTP_POST; -import static com.yoti.api.client.spi.remote.call.YotiConstants.AUTH_ID_HEADER; import static com.yoti.api.client.spi.remote.call.YotiConstants.CONTENT_TYPE; import static com.yoti.api.client.spi.remote.call.YotiConstants.CONTENT_TYPE_JSON; import static com.yoti.api.client.spi.remote.call.YotiConstants.DEFAULT_IDENTITY_URL; @@ -25,6 +24,7 @@ import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.DigitalIdentitySignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.yoti.json.ResourceMapper; import com.yoti.validation.Validation; @@ -41,41 +41,38 @@ public class DigitalIdentityService { private final UnsignedPathFactory pathFactory; private final YotiHttpRequestBuilderFactory requestBuilderFactory; private final ReceiptParser receiptParser; - + private final DigitalIdentitySignedRequestStrategy authStrategy; private final String apiUrl; - public DigitalIdentityService( + private DigitalIdentityService( UnsignedPathFactory pathFactory, YotiHttpRequestBuilderFactory requestBuilderFactory, - ReceiptParser receiptParser) { + ReceiptParser receiptParser, + DigitalIdentitySignedRequestStrategy authStrategy) { this.pathFactory = pathFactory; this.requestBuilderFactory = requestBuilderFactory; this.receiptParser = receiptParser; - + this.authStrategy = authStrategy; this.apiUrl = System.getProperty(PROPERTY_YOTI_API_URL, DEFAULT_IDENTITY_URL); } - public static DigitalIdentityService newInstance() { + public static DigitalIdentityService newInstance(KeyPair keyPair, String sdkId) { return new DigitalIdentityService( new UnsignedPathFactory(), new YotiHttpRequestBuilderFactory(), - ReceiptParser.newInstance() + ReceiptParser.newInstance(), + new DigitalIdentitySignedRequestStrategy(keyPair, sdkId) ); } - public ShareSession createShareSession(String sdkId, KeyPair keyPair, ShareSessionRequest shareSessionRequest) - throws DigitalIdentityException { - Validation.notNullOrEmpty(sdkId, "SDK ID"); - Validation.notNull(keyPair, "Application Key Pair"); + public ShareSession createShareSession(ShareSessionRequest shareSessionRequest) throws DigitalIdentityException { Validation.notNull(shareSessionRequest, "Share Session request"); String path = pathFactory.createIdentitySessionPath(); - LOG.debug("Requesting share session creation for SDK ID '{}' at '{}'", sdkId, path); - try { byte[] payload = ResourceMapper.writeValueAsString(shareSessionRequest); - return createSignedRequest(sdkId, keyPair, path, HTTP_POST, payload).execute(ShareSession.class); + return createSignedRequest(path, HTTP_POST, payload).execute(ShareSession.class); } catch (IOException ex) { throw new DigitalIdentityException("Error while parsing the share session creation request ", ex); } catch (URISyntaxException ex) { @@ -87,18 +84,13 @@ public ShareSession createShareSession(String sdkId, KeyPair keyPair, ShareSessi } } - public ShareSession fetchShareSession(String sdkId, KeyPair keyPair, String sessionId) - throws DigitalIdentityException { - Validation.notNullOrEmpty(sdkId, "SDK ID"); - Validation.notNull(keyPair, "Application Key Pair"); + public ShareSession fetchShareSession(String sessionId) throws DigitalIdentityException { Validation.notNull(sessionId, "Session ID"); - String path = pathFactory.createIdentitySessionRetrievalPath(sessionId); - LOG.debug("Requesting share session '{}' at '{}'", sessionId, path); try { - return createSignedRequest(sdkId, keyPair, path).execute(ShareSession.class); + return createSignedRequest(path).execute(ShareSession.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session '{%s}' ", sessionId), @@ -107,10 +99,7 @@ public ShareSession fetchShareSession(String sdkId, KeyPair keyPair, String sess } } - public ShareSessionQrCode createShareQrCode(String sdkId, KeyPair keyPair, String sessionId) - throws DigitalIdentityException { - Validation.notNullOrEmpty(sdkId, "SDK ID"); - Validation.notNull(keyPair, "Application Key Pair"); + public ShareSessionQrCode createShareQrCode(String sessionId) throws DigitalIdentityException { Validation.notNullOrEmpty(sessionId, "Session ID"); String path = pathFactory.createIdentitySessionQrCodePath(sessionId); @@ -118,7 +107,7 @@ public ShareSessionQrCode createShareQrCode(String sdkId, KeyPair keyPair, Strin LOG.debug("Requesting share session '{}' QR code creation at '{}'", sessionId, path); try { - return createSignedRequest(sdkId, keyPair, path, HTTP_POST, EMPTY_JSON).execute(ShareSessionQrCode.class); + return createSignedRequest(path, HTTP_POST, EMPTY_JSON).execute(ShareSessionQrCode.class); } catch (GeneralSecurityException ex) { throw new DigitalIdentityException("Error while signing the share QR code creation request ", ex); } catch (IOException | URISyntaxException | ResourceException ex) { @@ -126,10 +115,7 @@ public ShareSessionQrCode createShareQrCode(String sdkId, KeyPair keyPair, Strin } } - public ShareSessionQrCode fetchShareQrCode(String sdkId, KeyPair keyPair, String qrCodeId) - throws DigitalIdentityException { - Validation.notNullOrEmpty(sdkId, "SDK ID"); - Validation.notNull(keyPair, "Application Key Pair"); + public ShareSessionQrCode fetchShareQrCode(String qrCodeId) throws DigitalIdentityException { Validation.notNullOrEmpty(qrCodeId, "QR Code ID"); String path = pathFactory.createIdentitySessionQrCodeRetrievalPath(qrCodeId); @@ -137,7 +123,7 @@ public ShareSessionQrCode fetchShareQrCode(String sdkId, KeyPair keyPair, String LOG.debug("Requesting share session QR code '{} at '{}'", qrCodeId, path); try { - return createSignedRequest(sdkId, keyPair, path).execute(ShareSessionQrCode.class); + return createSignedRequest(path).execute(ShareSessionQrCode.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session QR code '{%s}' ", qrCodeId), @@ -146,25 +132,24 @@ public ShareSessionQrCode fetchShareQrCode(String sdkId, KeyPair keyPair, String } } - public Receipt fetchShareReceipt(String sdkId, KeyPair keyPair, String receiptId) throws DigitalIdentityException { - WrappedReceipt wrappedReceipt = doFetchShareReceipt(sdkId, keyPair, receiptId); + public Receipt fetchShareReceipt(KeyPair keyPair, String receiptId) throws DigitalIdentityException { + WrappedReceipt wrappedReceipt = doFetchShareReceipt(receiptId); return Optional.ofNullable(wrappedReceipt.getError()) .map(ignored -> receiptParser.create(wrappedReceipt)) .orElseGet(() -> { - ReceiptItemKey receiptKey = fetchShareReceiptKey(sdkId, keyPair, wrappedReceipt); + ReceiptItemKey receiptKey = fetchShareReceiptKey(wrappedReceipt); return receiptParser.create(wrappedReceipt, receiptKey, keyPair.getPrivate()); }); } - private WrappedReceipt doFetchShareReceipt(String sdkId, KeyPair keyPair, String receiptId) { + private WrappedReceipt doFetchShareReceipt(String receiptId) { String path = pathFactory.createIdentitySessionReceiptRetrievalPath(receiptId); - LOG.debug("Requesting share session receipt '{}' at '{}'", receiptId, path); try { - return createSignedRequest(sdkId, keyPair, path).execute(WrappedReceipt.class); + return createSignedRequest(path).execute(WrappedReceipt.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session QR code '{%s}' ", receiptId), @@ -173,16 +158,13 @@ private WrappedReceipt doFetchShareReceipt(String sdkId, KeyPair keyPair, String } } - private ReceiptItemKey fetchShareReceiptKey(String sdkId, KeyPair keyPair, WrappedReceipt wrappedReceipt) - throws DigitalIdentityException { + private ReceiptItemKey fetchShareReceiptKey(WrappedReceipt wrappedReceipt) throws DigitalIdentityException { String wrappedItemKeyId = wrappedReceipt.getWrappedItemKeyId(); - String path = pathFactory.createIdentitySessionReceiptKeyRetrievalPath(wrappedItemKeyId); - LOG.debug("Requesting share session receipt item key '{}' at '{}'", wrappedItemKeyId, path); try { - return createSignedRequest(sdkId, keyPair, path).execute(ReceiptItemKey.class); + return createSignedRequest(path).execute(ReceiptItemKey.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session receipt key '{%s}' ", wrappedItemKeyId), @@ -191,19 +173,14 @@ private ReceiptItemKey fetchShareReceiptKey(String sdkId, KeyPair keyPair, Wrapp } } - public MatchResult fetchMatch(String sdkId, KeyPair keyPair, MatchRequest matchRequest) - throws DigitalIdentityException { - Validation.notNullOrEmpty(sdkId, "SDK ID"); - Validation.notNull(keyPair, "Application Key Pair"); + public MatchResult fetchMatch(MatchRequest matchRequest) throws DigitalIdentityException { Validation.notNull(matchRequest, "DID Match request"); String path = pathFactory.createIdentityMatchPath(); - LOG.debug("Requesting digital ID Match for SDK ID '{}' at '{}'", sdkId, path); - try { byte[] payload = ResourceMapper.writeValueAsString(matchRequest); - return createSignedRequest(sdkId, keyPair, path, HTTP_POST, payload).execute(MatchResult.class); + return createSignedRequest(path, HTTP_POST, payload).execute(MatchResult.class); } catch (IOException ex) { throw new DigitalIdentityException("Error while parsing the DID Match request", ex); } catch (URISyntaxException ex) { @@ -215,18 +192,16 @@ public MatchResult fetchMatch(String sdkId, KeyPair keyPair, MatchRequest matchR } } - YotiHttpRequest createSignedRequest(String sdkId, KeyPair keyPair, String path) - throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { - return createSignedRequest(sdkId, keyPair, path, HTTP_GET, null); + YotiHttpRequest createSignedRequest(String path) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { + return createSignedRequest(path, HTTP_GET, null); } - YotiHttpRequest createSignedRequest(String sdkId, KeyPair keyPair, String path, String method, byte[] payload) + YotiHttpRequest createSignedRequest(String path, String method, byte[] payload) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { YotiHttpRequestBuilder request = requestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) - .withHeader(AUTH_ID_HEADER, sdkId) .withHttpMethod(method); return Optional.ofNullable(payload) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java index acc452140..190bca431 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java @@ -17,6 +17,7 @@ import com.yoti.api.client.spi.remote.call.ResourceException; import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.SimpleSignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.databind.ObjectMapper; @@ -25,11 +26,12 @@ public final class DynamicSharingService { - public static DynamicSharingService newInstance() { + public static DynamicSharingService newInstance(KeyPair keyPair) { return new DynamicSharingService( new UnsignedPathFactory(), new ObjectMapper(), - new YotiHttpRequestBuilderFactory() + new YotiHttpRequestBuilderFactory(), + new SimpleSignedRequestStrategy(keyPair) ); } @@ -38,22 +40,24 @@ public static DynamicSharingService newInstance() { private final UnsignedPathFactory unsignedPathFactory; private final ObjectMapper objectMapper; private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; + private final SimpleSignedRequestStrategy simpleSignedRequestStrategy; private final String apiUrl; - DynamicSharingService(UnsignedPathFactory unsignedPathFactory, + private DynamicSharingService(UnsignedPathFactory unsignedPathFactory, ObjectMapper objectMapper, - YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory, + SimpleSignedRequestStrategy simpleSignedRequestStrategy) { this.unsignedPathFactory = unsignedPathFactory; this.objectMapper = objectMapper; this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; + this.simpleSignedRequestStrategy = simpleSignedRequestStrategy; apiUrl = System.getProperty(PROPERTY_YOTI_API_URL, DEFAULT_YOTI_API_URL); } - public ShareUrlResult createShareUrl(String appId, KeyPair keyPair, DynamicScenario dynamicScenario) throws DynamicShareException { + public ShareUrlResult createShareUrl(String appId, DynamicScenario dynamicScenario) throws DynamicShareException { notNull(appId, "Application id"); - notNull(keyPair, "Application key Pair"); notNull(dynamicScenario, "Dynamic scenario"); String path = unsignedPathFactory.createDynamicSharingPath(appId); @@ -62,7 +66,7 @@ public ShareUrlResult createShareUrl(String appId, KeyPair keyPair, DynamicScena try { byte[] body = objectMapper.writeValueAsString(dynamicScenario).getBytes(DEFAULT_CHARSET); - YotiHttpRequest yotiHttpRequest = createSignedRequest(keyPair, path, body); + YotiHttpRequest yotiHttpRequest = createSignedRequest(path, body); return yotiHttpRequest.execute(ShareUrlResult.class); } catch (ResourceException ex) { @@ -72,10 +76,10 @@ public ShareUrlResult createShareUrl(String appId, KeyPair keyPair, DynamicScena } } - YotiHttpRequest createSignedRequest(KeyPair keyPair, String path, byte[] body) throws DynamicShareException { + YotiHttpRequest createSignedRequest(String path, byte[] body) throws DynamicShareException { try { return yotiHttpRequestBuilderFactory.create() - .withKeyPair(keyPair) + .withAuthStrategy(simpleSignedRequestStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withPayload(body) diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java index 4745cfa7f..687b45302 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java @@ -1,12 +1,12 @@ package com.yoti.api.client; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.Answers.RETURNS_DEEP_STUBS; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -15,16 +15,17 @@ import com.yoti.api.client.identity.MatchRequest; import com.yoti.api.client.identity.ShareSessionRequest; -import com.yoti.api.client.spi.remote.KeyStreamVisitor; import com.yoti.api.client.spi.remote.call.identity.DigitalIdentityException; import com.yoti.api.client.spi.remote.call.identity.DigitalIdentityService; import com.yoti.api.client.spi.remote.util.CryptoUtil; import org.bouncycastle.openssl.PEMException; -import org.junit.*; +import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.junit.*; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class DigitalIdentityClientTest { @@ -34,9 +35,10 @@ public class DigitalIdentityClientTest { private static final String A_SESSION_ID = "aSessionId"; private static final String A_RECEIPT_ID = "aReceiptId"; - @Mock KeyPairSource keyPairSource; - @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPair; - @Mock DigitalIdentityService identityService; + @InjectMocks DigitalIdentityClient testObj; + + @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPairMock; + @Mock DigitalIdentityService identityServiceMock; @Mock ShareSessionRequest shareSessionRequest; @Mock MatchRequest matchRequest; @@ -118,21 +120,13 @@ public void build_InvalidKeyPair_InitialisationException() { @Test public void client_CreateShareSessionException_DigitalIdentityException() throws IOException { - when(keyPairSource.getFromStream(any(KeyStreamVisitor.class))).thenReturn(keyPair); - - DigitalIdentityClient identityClient = new DigitalIdentityClient( - AN_SDK_ID, - keyPairSource, - identityService - ); - String exMessage = "Create Share Session Error"; - when(identityService.createShareSession(AN_SDK_ID, keyPair, shareSessionRequest)) + when(identityServiceMock.createShareSession(shareSessionRequest)) .thenThrow(new DigitalIdentityException(exMessage)); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityClient.createShareSession(shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); assertThat(ex.getMessage(), equalTo(exMessage)); @@ -140,21 +134,13 @@ public void client_CreateShareSessionException_DigitalIdentityException() throws @Test public void client_FetchShareSessionException_DigitalIdentityException() throws IOException { - when(keyPairSource.getFromStream(any(KeyStreamVisitor.class))).thenReturn(keyPair); - - DigitalIdentityClient identityClient = new DigitalIdentityClient( - AN_SDK_ID, - keyPairSource, - identityService - ); - String exMessage = "Fetch Share Session Error"; - when(identityService.fetchShareSession(AN_SDK_ID, keyPair, A_SESSION_ID)) + when(identityServiceMock.fetchShareSession(A_SESSION_ID)) .thenThrow(new DigitalIdentityException(exMessage)); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityClient.fetchShareSession(A_SESSION_ID) + () -> testObj.fetchShareSession(A_SESSION_ID) ); assertThat(ex.getMessage(), equalTo(exMessage)); @@ -162,21 +148,13 @@ public void client_FetchShareSessionException_DigitalIdentityException() throws @Test public void client_CreateShareQrCodeException_DigitalIdentityException() throws IOException { - when(keyPairSource.getFromStream(any(KeyStreamVisitor.class))).thenReturn(keyPair); - - DigitalIdentityClient identityClient = new DigitalIdentityClient( - AN_SDK_ID, - keyPairSource, - identityService - ); - String exMessage = "Create Share QR Error"; - when(identityService.createShareQrCode(AN_SDK_ID, keyPair, A_SESSION_ID)) + when(identityServiceMock.createShareQrCode(A_SESSION_ID)) .thenThrow(new DigitalIdentityException(exMessage)); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityClient.createShareQrCode(A_SESSION_ID) + () -> testObj.createShareQrCode(A_SESSION_ID) ); assertThat(ex.getMessage(), equalTo(exMessage)); @@ -184,21 +162,13 @@ public void client_CreateShareQrCodeException_DigitalIdentityException() throws @Test public void client_FetchShareQrCodeException_DigitalIdentityException() throws IOException { - when(keyPairSource.getFromStream(any(KeyStreamVisitor.class))).thenReturn(keyPair); - - DigitalIdentityClient identityClient = new DigitalIdentityClient( - AN_SDK_ID, - keyPairSource, - identityService - ); - String exMessage = "Fetch Share QR Error"; - when(identityService.fetchShareQrCode(AN_SDK_ID, keyPair, A_QR_CODE_ID)) + when(identityServiceMock.fetchShareQrCode(A_QR_CODE_ID)) .thenThrow(new DigitalIdentityException(exMessage)); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityClient.fetchShareQrCode(A_QR_CODE_ID) + () -> testObj.fetchShareQrCode(A_QR_CODE_ID) ); assertThat(ex.getMessage(), equalTo(exMessage)); @@ -206,21 +176,13 @@ public void client_FetchShareQrCodeException_DigitalIdentityException() throws I @Test public void client_FetchShareReceiptException_DigitalIdentityException() throws IOException { - when(keyPairSource.getFromStream(any(KeyStreamVisitor.class))).thenReturn(keyPair); - - DigitalIdentityClient identityClient = new DigitalIdentityClient( - AN_SDK_ID, - keyPairSource, - identityService - ); - String exMessage = "Fetch Share Receipt Error"; - when(identityService.fetchShareReceipt(AN_SDK_ID, keyPair, A_RECEIPT_ID)) + when(identityServiceMock.fetchShareReceipt(keyPairMock, A_RECEIPT_ID)) .thenThrow(new DigitalIdentityException(exMessage)); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityClient.fetchShareReceipt(A_RECEIPT_ID) + () -> testObj.fetchShareReceipt(A_RECEIPT_ID) ); assertThat(ex.getMessage(), equalTo(exMessage)); @@ -228,21 +190,13 @@ public void client_FetchShareReceiptException_DigitalIdentityException() throws @Test public void client_FetchDigitalIdMatchException_DigitalIdentityException() throws IOException { - when(keyPairSource.getFromStream(any(KeyStreamVisitor.class))).thenReturn(keyPair); - - DigitalIdentityClient identityClient = new DigitalIdentityClient( - AN_SDK_ID, - keyPairSource, - identityService - ); - String exMessage = "Fetch digital identity match error"; - when(identityService.fetchMatch(AN_SDK_ID, keyPair, matchRequest)) + when(identityServiceMock.fetchMatch(matchRequest)) .thenThrow(new DigitalIdentityException(exMessage)); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityClient.fetchMatch(matchRequest) + () -> testObj.fetchMatch(matchRequest) ); assertThat(ex.getMessage(), equalTo(exMessage)); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/YotiClientTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/YotiClientTest.java index 19a52dbdf..42b1a6132 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/YotiClientTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/YotiClientTest.java @@ -3,11 +3,11 @@ import static com.yoti.api.client.spi.remote.util.CryptoUtil.base64Url; import static com.yoti.api.client.spi.remote.util.CryptoUtil.encryptAsymmetric; import static com.yoti.api.client.spi.remote.util.CryptoUtil.generateKeyPairFrom; -import static com.yoti.api.client.spi.remote.util.CryptoUtil.generateSymmetricKey; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.StringContains.containsString; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; @@ -20,9 +20,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.security.Key; import java.security.KeyPair; -import java.security.PrivateKey; import com.yoti.api.client.spi.remote.ActivityDetailsFactory; import com.yoti.api.client.spi.remote.ReceiptFetcher; @@ -52,30 +50,24 @@ public class YotiClientTest { @Mock Receipt receiptMock; @Mock ActivityDetails activityDetailsMock; String encryptedToken; - KeyPairSource validKeyPairSource; - byte[] validReceiptKey; + @Mock KeyPair keyPairMock; @Before public void setUp() throws Exception { - Key receiptKey = generateSymmetricKey(); KeyPair keyPair = generateKeyPairFrom(CryptoUtil.KEY_PAIR_PEM); - validReceiptKey = encryptAsymmetric(receiptKey.getEncoded(), keyPair.getPublic()); - encryptedToken = base64Url(encryptAsymmetric(TOKEN.getBytes(), keyPair.getPublic())); - validKeyPairSource = new StaticKeyPairSource(CryptoUtil.KEY_PAIR_PEM); } @Test public void getActivityDetails_shouldFailWithExceptionFromReceiptFetcher() throws Exception { ProfileException profileException = new ProfileException("Test exception"); - when(receiptFetcherMock.fetch(eq(encryptedToken), any(KeyPair.class), eq(APP_ID))).thenThrow(profileException); + when(receiptFetcherMock.fetch(eq(encryptedToken), any(KeyPair.class))).thenThrow(profileException); try { - YotiClient testObj = new YotiClient(APP_ID, validKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, - sharingServiceMock); + YotiClient testObj = new YotiClient(APP_ID, keyPairMock, receiptFetcherMock, remoteAmlServiceMock, activityDetailsFactoryMock, sharingServiceMock); testObj.getActivityDetails(encryptedToken); - } catch (ProfileException e) { - assertSame(profileException, e); + } catch (ProfileException ex) { + assertSame(profileException, ex); return; } fail("Expected an Exception"); @@ -84,65 +76,57 @@ public void getActivityDetails_shouldFailWithExceptionFromReceiptFetcher() throw @Test public void getActivityDetails_shouldFailWithExceptionFromActivityDetailsFactory() throws Exception { ProfileException profileException = new ProfileException("Test exception"); - when(receiptFetcherMock.fetch(eq(encryptedToken), any(KeyPair.class), eq(APP_ID))).thenReturn(receiptMock); - when(activityDetailsFactoryMock.create(eq(receiptMock), any(PrivateKey.class))).thenThrow(profileException); + when(receiptFetcherMock.fetch(encryptedToken, keyPairMock)).thenReturn(receiptMock); + when(activityDetailsFactoryMock.create(receiptMock, keyPairMock.getPrivate())).thenThrow(profileException); - try { - YotiClient testObj = new YotiClient(APP_ID, validKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, - sharingServiceMock); - testObj.getActivityDetails(encryptedToken); - } catch (ProfileException e) { - assertSame(profileException, e); - verify(activityDetailsFactoryMock).create(eq(receiptMock), any(PrivateKey.class)); - return; - } - fail("Expected an Exception"); + YotiClient testObj = new YotiClient(APP_ID, keyPairMock, receiptFetcherMock, remoteAmlServiceMock, activityDetailsFactoryMock, sharingServiceMock); + ProfileException thrown = assertThrows(ProfileException.class, () -> testObj.getActivityDetails(encryptedToken)); + + assertSame(profileException, thrown); + verify(activityDetailsFactoryMock).create(receiptMock, keyPairMock.getPrivate()); } @Test public void getActivityDetails_shouldReturnActivityDetails() throws Exception { - when(receiptFetcherMock.fetch(eq(encryptedToken), any(KeyPair.class), eq(APP_ID))).thenReturn(receiptMock); - when(activityDetailsFactoryMock.create(eq(receiptMock), any(PrivateKey.class))).thenReturn(activityDetailsMock); + when(receiptFetcherMock.fetch(encryptedToken, keyPairMock)).thenReturn(receiptMock); + when(activityDetailsFactoryMock.create(receiptMock, keyPairMock.getPrivate())).thenReturn(activityDetailsMock); - YotiClient testObj = new YotiClient(APP_ID, validKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, - sharingServiceMock); + YotiClient testObj = new YotiClient(APP_ID, keyPairMock, receiptFetcherMock, remoteAmlServiceMock, activityDetailsFactoryMock, sharingServiceMock); ActivityDetails result = testObj.getActivityDetails(encryptedToken); assertSame(activityDetailsMock, result); } @Test - public void constructor_shouldFailWhenStreamExceptionLoadingKeys() { + public void builder_shouldFailWhenStreamExceptionLoadingKeys() { KeyPairSource badKeyPairSource = new StaticKeyPairSource(true); + YotiClient.Builder builder = YotiClient.builder() + .withClientSdkId(APP_ID) + .withKeyPair(badKeyPairSource); - try { - new YotiClient(APP_ID, badKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, sharingServiceMock); - } catch (InitialisationException e) { - assertTrue(e.getCause() instanceof IOException); - assertThat(e.getCause().getMessage(), containsString("Test stream exception")); - return; - } - fail("Expected an Exception"); + InitialisationException thrown = assertThrows(InitialisationException.class, builder::build); + + assertTrue(thrown.getCause() instanceof IOException); + assertThat(thrown.getCause().getMessage(), containsString("Test stream exception")); } @Test - public void constructor_shouldFailWhenKeyPairSourceExceptionLoadingKeys() { + public void builder_shouldFailWhenKeyPairSourceExceptionLoadingKeys() { KeyPairSource badKeyPairSource = new StaticKeyPairSource(false); + YotiClient.Builder builder = YotiClient.builder() + .withClientSdkId(APP_ID) + .withKeyPair(badKeyPairSource); - try { - new YotiClient(APP_ID, badKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, sharingServiceMock); - } catch (InitialisationException e) { - assertTrue(e.getCause() instanceof IOException); - assertThat(e.getCause().getMessage(), containsString("Test source exception")); - return; - } - fail("Expected an Exception"); + InitialisationException thrown = assertThrows(InitialisationException.class, builder::build); + + assertTrue(thrown.getCause() instanceof IOException); + assertThat(thrown.getCause().getMessage(), containsString("Test source exception")); } @Test public void constructor_shouldFailWithNullApplicationId() { try { - new YotiClient(null, validKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, sharingServiceMock); + new YotiClient(null, null, null, null, null, null); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("Application id")); return; @@ -150,21 +134,10 @@ public void constructor_shouldFailWithNullApplicationId() { fail("Expected an Exception"); } - @Test - public void constructor_shouldFailWithNullKeyPairSource() { - try { - new YotiClient(APP_ID, null, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, sharingServiceMock); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("Key pair source")); - return; - } - fail("Expected an Exception"); - } - @Test public void constructor_shouldFailWithNullReceiptFetcher() { try { - new YotiClient(APP_ID, validKeyPairSource, null, activityDetailsFactoryMock, remoteAmlServiceMock, sharingServiceMock); + new YotiClient(APP_ID, keyPairMock, null, null, null, null); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("receiptFetcher")); return; @@ -175,7 +148,7 @@ public void constructor_shouldFailWithNullReceiptFetcher() { @Test public void constructor_shouldFailWithNullActivityDetailsFactory() { try { - new YotiClient(APP_ID, validKeyPairSource, receiptFetcherMock, null, remoteAmlServiceMock, sharingServiceMock); + new YotiClient(APP_ID, keyPairMock, receiptFetcherMock, remoteAmlServiceMock, null, null); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("activityDetailsFactory")); return; @@ -186,7 +159,7 @@ public void constructor_shouldFailWithNullActivityDetailsFactory() { @Test public void constructor_shouldFailWithNullAmlService() { try { - new YotiClient(APP_ID, validKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, null, sharingServiceMock); + new YotiClient(APP_ID, keyPairMock, receiptFetcherMock, null, null, null); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("amlService")); return; @@ -195,30 +168,28 @@ public void constructor_shouldFailWithNullAmlService() { } @Test - public void constructor_shouldFailWithNoKeyPair() { + public void builder_shouldFailWithNoKeyPair() { KeyPairSource invalidKeyPairSource = new StaticKeyPairSource("no-key-pair-in-file"); + YotiClient.Builder builder = YotiClient.builder() + .withClientSdkId(APP_ID) + .withKeyPair(invalidKeyPairSource); - try { - new YotiClient(APP_ID, invalidKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, sharingServiceMock); - } catch (InitialisationException e) { - assertThat(e.getMessage(), containsString("No key pair found in the provided source")); - return; - } - fail("Expected an Exception"); + InitialisationException thrown = assertThrows(InitialisationException.class, builder::build); + + assertThat(thrown.getMessage(), containsString("No key pair found in the provided source")); } @Test - public void constructor_shouldFailWithInvalidKeyPair() { + public void builder_shouldFailWithInvalidKeyPair() { KeyPairSource invalidKeyPairSource = new StaticKeyPairSource(CryptoUtil.INVALID_KEY_PAIR_PEM); + YotiClient.Builder builder = YotiClient.builder() + .withClientSdkId(APP_ID) + .withKeyPair(invalidKeyPairSource); - try { - new YotiClient(APP_ID, invalidKeyPairSource, receiptFetcherMock, activityDetailsFactoryMock, remoteAmlServiceMock, sharingServiceMock); - } catch (InitialisationException e) { - assertThat(e.getMessage(), containsString("Cannot load key pair")); - assertTrue(e.getCause() instanceof PEMException); - return; - } - fail("Expected an Exception"); + InitialisationException thrown = assertThrows(InitialisationException.class, builder::build); + + assertThat(thrown.getMessage(), containsString("Cannot load key pair")); + assertTrue(thrown.getCause() instanceof PEMException); } private static class StaticKeyPairSource implements KeyPairSource { diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientBuilderTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientBuilderTest.java index 21ac4dd6b..e0bc1c24a 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientBuilderTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientBuilderTest.java @@ -5,8 +5,10 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThrows; -import static org.junit.Assert.fail; +import java.io.IOException; + +import com.yoti.api.client.InitialisationException; import com.yoti.api.client.KeyPairSource; import com.yoti.api.client.common.StaticKeyPairSource; import com.yoti.api.client.spi.remote.util.CryptoUtil; @@ -17,6 +19,7 @@ public class DocScanClientBuilderTest { private static final String SOME_APPLICATION_ID = "someAppId"; + private static final String SOME_AUTH_TOKEN = "someAuthToken"; private KeyPairSource validKeyPairSource; @@ -26,30 +29,71 @@ public void setUp() { } @Test - public void build_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> DocScanClient.builder().build()); + public void shouldThrowExceptionWhenSdkIdIsNull() { + DocScanClient.Builder builder = DocScanClient.builder(); + + IllegalStateException ex = assertThrows(IllegalStateException.class, builder::build); + + assertThat(ex.getMessage(), containsString("sdkId")); + } + + @Test + public void shouldThrowExceptionWhenSdkIdIsEmpty() { + DocScanClient.Builder builder = DocScanClient.builder() + .withClientSdkId(""); + + IllegalStateException ex = assertThrows(IllegalStateException.class, builder::build); + + assertThat(ex.getMessage(), containsString("sdkId")); + } + + @Test + public void shouldThrowExceptionWhenKeyPairSourceIsNull() { + DocScanClient.Builder builder = DocScanClient.builder() + .withClientSdkId(SOME_APPLICATION_ID); + + IllegalStateException ex = assertThrows(IllegalStateException.class, builder::build); + + assertThat(ex.getMessage(), containsString("KeyPairSource")); + } + + @Test + public void shouldThrowExceptionWhenSdkIdIsGivenAlongWithAuthToken() { + DocScanClient.Builder builder = DocScanClient.builder() + .withClientSdkId(SOME_APPLICATION_ID) + .withAuthenticationToken(SOME_AUTH_TOKEN); + + IllegalStateException ex = assertThrows(IllegalStateException.class, builder::build); - assertThat(ex.getMessage(), containsString("SDK ID")); + assertThat(ex.getMessage(), containsString("sdkId or KeyPairSource")); } @Test - public void build_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> DocScanClient.builder().withClientSdkId("").build()); + public void shouldThrowExceptionWhenKeyPairSourceIsGivenAlongWithAuthToken() { + DocScanClient.Builder builder = DocScanClient.builder() + .withKeyPairSource(validKeyPairSource) + .withAuthenticationToken(SOME_AUTH_TOKEN); + + IllegalStateException ex = assertThrows(IllegalStateException.class, builder::build); - assertThat(ex.getMessage(), containsString("SDK ID")); + assertThat(ex.getMessage(), containsString("sdkId or KeyPairSource")); } @Test - public void build_shouldThrowExceptionWhenKeyPairSourceIsNull() { - DocScanClient.Builder builder = DocScanClient.builder().withClientSdkId(SOME_APPLICATION_ID); + public void shouldFailWhenStreamExceptionLoadingKeys() { + KeyPairSource badKeyPairSource = new StaticKeyPairSource(true); + DocScanClient.Builder builder = DocScanClient.builder() + .withClientSdkId(SOME_APPLICATION_ID) + .withKeyPairSource(badKeyPairSource); - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> builder.build()); + InitialisationException ex = assertThrows(InitialisationException.class, builder::build); - assertThat(ex.getMessage(), containsString("Application key Pair")); + IOException ioException = (IOException) ex.getCause(); + assertThat(ioException.getMessage(), containsString("Test stream exception")); } @Test - public void build_shouldCorrectlyBuildDocScanClient() { + public void shouldCorrectlyBuildDocScanClientForUsingSignedRequests() { DocScanClient result = DocScanClient.builder() .withClientSdkId(SOME_APPLICATION_ID) .withKeyPairSource(validKeyPairSource) @@ -58,4 +102,13 @@ public void build_shouldCorrectlyBuildDocScanClient() { assertThat(result, is(notNullValue())); } + @Test + public void shouldCorrectlyBuildDocScanClientForUsingAuthTokens() { + DocScanClient result = DocScanClient.builder() + .withAuthenticationToken(SOME_AUTH_TOKEN) + .build(); + + assertThat(result, is(notNullValue())); + } + } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientTest.java index 265275b17..d85ec9184 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanClientTest.java @@ -1,64 +1,39 @@ package com.yoti.api.client.docs; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; -import java.io.IOException; -import java.security.KeyPair; - -import com.yoti.api.client.InitialisationException; -import com.yoti.api.client.KeyPairSource; -import com.yoti.api.client.common.StaticKeyPairSource; import com.yoti.api.client.docs.session.create.SessionSpec; import com.yoti.api.client.docs.session.instructions.Instructions; -import com.yoti.api.client.spi.remote.util.CryptoUtil; +import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class DocScanClientTest { - private static final String APP_ID = "appId"; private static final String SOME_SESSION_ID = "someSessionId"; private static final String SOME_MEDIA_ID = "someMediaId"; + @InjectMocks DocScanClient testObj; + @Mock DocScanService docScanServiceMock; + @Mock AuthStrategy authStrategyMock; @Mock SessionSpec sessionSpecMock; @Mock Instructions instructionsMock; - private KeyPairSource validKeyPairSource; - - @Before - public void setUp() { - validKeyPairSource = new StaticKeyPairSource(CryptoUtil.KEY_PAIR_PEM); - } - - @Test - public void constructor_shouldFailWhenStreamExceptionLoadingKeys() { - KeyPairSource badKeyPairSource = new StaticKeyPairSource(true); - - InitialisationException ex = assertThrows(InitialisationException.class, () -> new DocScanClient(APP_ID, badKeyPairSource, docScanServiceMock)); - - assertThat(ex.getCause(), is(instanceOf(IOException.class))); - assertThat(ex.getCause().getMessage(), containsString("Test stream exception")); - } @Test public void createDocScanSession_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - when(docScanServiceMock.createSession(eq(APP_ID), any(KeyPair.class), eq(sessionSpecMock))).thenThrow(original); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + when(docScanServiceMock.createSession(authStrategyMock, sessionSpecMock)).thenThrow(original); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.createSession(sessionSpecMock)); @@ -68,8 +43,7 @@ public void createDocScanSession_shouldFailWithExceptionFromYotiDocsService() th @Test public void getDocScanSession_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - when(docScanServiceMock.retrieveSession(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID))).thenThrow(original); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + when(docScanServiceMock.retrieveSession(authStrategyMock, SOME_SESSION_ID)).thenThrow(original); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.getSession(SOME_SESSION_ID)); @@ -79,8 +53,7 @@ public void getDocScanSession_shouldFailWithExceptionFromYotiDocsService() throw @Test public void getDocScanMedia_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - when(docScanServiceMock.getMediaContent(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID), eq(SOME_MEDIA_ID))).thenThrow(original); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + when(docScanServiceMock.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)).thenThrow(original); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.getMediaContent(SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -90,8 +63,7 @@ public void getDocScanMedia_shouldFailWithExceptionFromYotiDocsService() throws @Test public void deleteDocScanMedia_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).deleteMediaContent(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID), eq(SOME_MEDIA_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).deleteMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.deleteMediaContent(SOME_SESSION_ID, SOME_MEDIA_ID)); @@ -101,8 +73,7 @@ public void deleteDocScanMedia_shouldFailWithExceptionFromYotiDocsService() thro @Test public void deleteDocScanSession_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).deleteSession(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).deleteSession(authStrategyMock, SOME_SESSION_ID); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.deleteSession(SOME_SESSION_ID)); @@ -112,8 +83,7 @@ public void deleteDocScanSession_shouldFailWithExceptionFromYotiDocsService() th @Test public void putIbvInstructions_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).putIbvInstructions(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID), eq(instructionsMock)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock); DocScanException exception = assertThrows(DocScanException.class, () -> testObj.putIbvInstructions(SOME_SESSION_ID, instructionsMock)); @@ -123,8 +93,7 @@ public void putIbvInstructions_shouldFailWithExceptionFromYotiDocsService() thro @Test public void getIbvInstructions_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).getIbvInstructions(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).getIbvInstructions(authStrategyMock, SOME_SESSION_ID); DocScanException exception = assertThrows(DocScanException.class, () -> testObj.getIbvInstructions(SOME_SESSION_ID)); @@ -134,8 +103,7 @@ public void getIbvInstructions_shouldFailWithExceptionFromYotiDocsService() thro @Test public void getIbvInstructionsPdf_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).getIbvInstructionsPdf(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID); DocScanException exception = assertThrows(DocScanException.class, () -> testObj.getIbvInstructionsPdf(SOME_SESSION_ID)); @@ -145,8 +113,7 @@ public void getIbvInstructionsPdf_shouldFailWithExceptionFromYotiDocsService() t @Test public void fetchInstructionsContactProfile_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).fetchInstructionsContactProfile(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID); DocScanException exception = assertThrows(DocScanException.class, () -> testObj.fetchInstructionsContactProfile(SOME_SESSION_ID)); @@ -156,8 +123,7 @@ public void fetchInstructionsContactProfile_shouldFailWithExceptionFromYotiDocsS @Test public void triggerIbvEmailNotification_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).triggerIbvEmailNotification(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID); DocScanException exception = assertThrows(DocScanException.class, () -> testObj.triggerIbvEmailNotification(SOME_SESSION_ID)); @@ -167,8 +133,7 @@ public void triggerIbvEmailNotification_shouldFailWithExceptionFromYotiDocsServi @Test public void getSessionConfiguration_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).fetchSessionConfiguration(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID); DocScanException exception = assertThrows(DocScanException.class, () -> testObj.getSessionConfiguration(SOME_SESSION_ID)); @@ -178,8 +143,7 @@ public void getSessionConfiguration_shouldFailWithExceptionFromYotiDocsService() @Test public void getSupportedDocuments_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).getSupportedDocuments(any(KeyPair.class), any(Boolean.class)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).getSupportedDocuments(false); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.getSupportedDocuments()); @@ -189,8 +153,7 @@ public void getSupportedDocuments_shouldFailWithExceptionFromYotiDocsService() t @Test public void getTrackedDevices_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).getTrackedDevices(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).getTrackedDevices(authStrategyMock, SOME_SESSION_ID); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.getTrackedDevices(SOME_SESSION_ID)); @@ -200,8 +163,7 @@ public void getTrackedDevices_shouldFailWithExceptionFromYotiDocsService() throw @Test public void deleteTrackedDevices_shouldFailWithExceptionFromYotiDocsService() throws Exception { DocScanException original = new DocScanException("Test exception"); - doThrow(original).when(docScanServiceMock).deleteTrackedDevices(eq(APP_ID), any(KeyPair.class), eq(SOME_SESSION_ID)); - DocScanClient testObj = new DocScanClient(APP_ID, validKeyPairSource, docScanServiceMock); + doThrow(original).when(docScanServiceMock).deleteTrackedDevices(authStrategyMock, SOME_SESSION_ID); DocScanException thrown = assertThrows(DocScanException.class, () -> testObj.deleteTrackedDevices(SOME_SESSION_ID)); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java index 0dba44137..6840034b0 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java @@ -6,8 +6,6 @@ import static com.yoti.api.client.spi.remote.call.YotiConstants.CONTENT_TYPE_JSON; import static com.yoti.api.client.spi.remote.call.YotiConstants.DEFAULT_YOTI_DOCS_URL; import static com.yoti.api.client.spi.remote.call.YotiConstants.PROPERTY_YOTI_DOCS_URL; -import static com.yoti.api.client.spi.remote.util.CryptoUtil.KEY_PAIR_PEM; -import static com.yoti.api.client.spi.remote.util.CryptoUtil.generateKeyPairFrom; import static junit.framework.TestCase.assertSame; import static org.hamcrest.MatcherAssert.assertThat; @@ -28,7 +26,6 @@ import java.io.InputStream; import java.net.URISyntaxException; import java.security.GeneralSecurityException; -import java.security.KeyPair; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -57,12 +54,12 @@ import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.YotiHttpResponse; +import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; @@ -75,7 +72,6 @@ @RunWith(MockitoJUnitRunner.class) public class DocScanServiceTest { - private static final String SOME_APP_ID = "someAppId"; private static final String SOME_SESSION_ID = "someSessionId"; private static final String SOME_PATH = "somePath"; private static final String SOME_MEDIA_ID = "someMediaId"; @@ -86,14 +82,14 @@ public class DocScanServiceTest { private static final byte[] IMAGE_BODY = "some-image-body".getBytes(); private static final ObjectMapper MAPPER = new ObjectMapper(); - private static KeyPair KEY_PAIR; - @Spy @InjectMocks DocScanService docScanService; @Mock UnsignedPathFactory unsignedPathFactoryMock; @Mock ObjectMapper objectMapperMock; - @Mock YotiHttpRequest yotiHttpRequestMock; @Mock(answer = Answers.RETURNS_SELF) YotiHttpRequestBuilder yotiHttpRequestBuilderMock; + + @Mock AuthStrategy authStrategyMock; + @Mock YotiHttpRequest yotiHttpRequestMock; @Mock YotiHttpResponse yotiHttpResponseMock; @Mock YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactoryMock; @Mock SupportedDocumentsResponse supportedDocumentsResponseMock; @@ -101,33 +97,21 @@ public class DocScanServiceTest { @Mock CreateFaceCaptureResourcePayload createFaceCaptureResourcePayloadMock; @Mock UploadFaceCaptureImagePayload uploadFaceCaptureImagePayloadMock; - @BeforeClass - public static void setUpClass() throws Exception { - KEY_PAIR = generateKeyPairFrom(KEY_PAIR_PEM); - } - @Before public void setUp() { when(yotiHttpRequestBuilderFactoryMock.create()).thenReturn(yotiHttpRequestBuilderMock); } @Test - public void createSession_shouldThrowExceptionWhenMissingAppId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createSession(null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void createSession_shouldThrowExceptionWhenMissingKeyPair() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createSession(SOME_APP_ID, null, null)); + public void createSession_shouldThrowExceptionWhenMissingAuthStrategy() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createSession(null, null)); - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void createSession_shouldThrowExceptionWhenMissingSessionSpec() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createSession(authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionSpec")); } @@ -138,7 +122,7 @@ public void createSession_shouldWrapGeneralSecurityException() throws Exception SessionSpec sessionSpecMock = mock(SessionSpec.class); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); @@ -151,7 +135,7 @@ public void createSession_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(CreateSessionResult.class)).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error posting the request: Failed Request")); @@ -164,7 +148,7 @@ public void createSession_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(CreateSessionResult.class)).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -176,7 +160,7 @@ public void createSession_shouldWrapURISyntaxException() throws Exception { SessionSpec sessionSpecMock = mock(SessionSpec.class); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), uriSyntaxException); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); @@ -189,7 +173,7 @@ public void createSession_shouldWrapGeneralException() { SessionSpec sessionSpecMock = mock(SessionSpec.class); doAnswer(i -> {throw someException;}).when(yotiHttpRequestBuilderFactoryMock).create(); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), someException); assertThat(ex.getMessage(), containsString("Error creating the session: Some exception we weren't expecting")); @@ -202,12 +186,12 @@ public void createSession_shouldCallSignedRequestBuilderWithCorrectMethods() thr when(objectMapperMock.writeValueAsBytes(sessionSpecMock)).thenReturn(SOME_SESSION_SPEC_BYTES); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(CreateSessionResult.class)).thenReturn(createSessionResultMock); - when(unsignedPathFactoryMock.createNewYotiDocsSessionPath(SOME_APP_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createNewYotiDocsSessionPath()).thenReturn(SOME_PATH); - CreateSessionResult result = docScanService.createSession(SOME_APP_ID, KEY_PAIR, sessionSpecMock); + CreateSessionResult result = docScanService.createSession(authStrategyMock, sessionSpecMock); assertThat(result, is(createSessionResultMock)); - verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_POST); @@ -216,36 +200,22 @@ public void createSession_shouldCallSignedRequestBuilderWithCorrectMethods() thr } @Test - public void retrieveSession_shouldThrowExceptionWhenAppIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void retrieveSession_shouldThrowExceptionWhenAppIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession("", null, null)); + public void retrieveSession_shouldThrowExceptionWhenMissingAuthStrategy() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(null, null)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void retrieveSession_shouldThrowExceptionWhenMissingKeyPair() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(SOME_APP_ID, null, null)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void retrieveSession_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void retrieveSession_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(authStrategyMock, "")); assertThat(ex.getMessage(), containsString("sessionId")); } @@ -255,7 +225,7 @@ public void retrieveSession_shouldWrapGeneralSecurityException() throws Exceptio GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); @@ -267,7 +237,7 @@ public void retrieveSession_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(GetSessionResult.class)).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); @@ -279,7 +249,7 @@ public void retrieveSession_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(GetSessionResult.class)).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -290,7 +260,7 @@ public void retrieveSession_shouldWrapGeneralException() { Exception someException = new Exception("Some exception we weren't expecting"); doAnswer(i -> {throw someException;}).when(yotiHttpRequestBuilderFactoryMock).create(); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.retrieveSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), someException); assertThat(ex.getMessage(), containsString("Error retrieving the session: Some exception we weren't expecting")); @@ -301,48 +271,34 @@ public void retrieveSession_shouldCallSignedRequestBuilderWithCorrectMethods() t GetSessionResult docScanSessionResponseMock = mock(GetSessionResult.class); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(GetSessionResult.class)).thenReturn(docScanSessionResponseMock); - when(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_SESSION_ID)).thenReturn(SOME_PATH); - GetSessionResult result = docScanService.retrieveSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); + GetSessionResult result = docScanService.retrieveSession(authStrategyMock, SOME_SESSION_ID); assertThat(result, is(docScanSessionResponseMock)); - verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_GET); } @Test - public void deleteSession_shouldThrowExceptionWhenAppIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession(null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void deleteSession_shouldThrowExceptionWhenAppIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession("", null, null)); + public void deleteSession_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession(null, null)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void deleteSession_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession(SOME_APP_ID, null, null)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void deleteSession_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession(authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void deleteSession_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteSession(authStrategyMock, "")); assertThat(ex.getMessage(), containsString("sessionId")); } @@ -352,7 +308,7 @@ public void deleteSession_shouldWrapGeneralSecurityException() throws Exception GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); @@ -364,7 +320,7 @@ public void deleteSession_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the DELETE: Failed Request")); @@ -376,7 +332,7 @@ public void deleteSession_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -387,7 +343,7 @@ public void deleteSession_shouldWrapGeneralException() { Exception someException = new Exception("Some exception we weren't expecting"); doAnswer(i -> {throw someException;}).when(yotiHttpRequestBuilderFactoryMock).create(); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteSession(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), someException); assertThat(ex.getMessage(), containsString("Error deleting the session: Some exception we weren't expecting")); @@ -396,61 +352,47 @@ public void deleteSession_shouldWrapGeneralException() { @Test public void deleteSession_shouldBuildSignedRequest() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); - when(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_SESSION_ID)).thenReturn(SOME_PATH); - docScanService.deleteSession(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); + docScanService.deleteSession(authStrategyMock, SOME_SESSION_ID); - verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); } @Test - public void getMediaContent_shouldThrowExceptionWhenApplicationIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(null, null, null, null)); + public void getMediaContent_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(null, null, null)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void getMediaContent_shouldThrowExceptionWhenApplicationIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent("", null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void getMediaContent_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(SOME_APP_ID, null, null, null)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void getMediaContent_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, null, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(authStrategyMock, null, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void getMediaContent_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, "", null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(authStrategyMock, "", null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void getMediaContent_shouldThrowExceptionWhenMediaIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, null)); assertThat(ex.getMessage(), containsString("mediaId")); } @Test public void getMediaContent_shouldThrowExceptionWhenMediaIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, "")); assertThat(ex.getMessage(), containsString("mediaId")); } @@ -460,7 +402,7 @@ public void getMediaContent_shouldWrapGeneralSecurityException() throws Exceptio GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); @@ -472,7 +414,7 @@ public void getMediaContent_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); @@ -484,7 +426,7 @@ public void getMediaContent_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -495,7 +437,7 @@ public void getMediaContent_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), uriSyntaxException); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); @@ -506,11 +448,11 @@ public void getMediaContent_shouldBuildSignedRequest() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); YotiHttpResponse yotiHttpResponseMock = mock(YotiHttpResponse.class, RETURNS_DEEP_STUBS); when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); - when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createMediaContentPath(SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); - docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); + docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID); - verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_GET); @@ -522,9 +464,9 @@ public void getMediaContent_shouldReturnMedia() throws Exception { when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); when(yotiHttpResponseMock.getResponseHeaders()).thenReturn(createHeadersMap(CONTENT_TYPE, CONTENT_TYPE_JSON)); when(yotiHttpResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); - when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createMediaContentPath(SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); - Media result = docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); + Media result = docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID); assertThat(result.getMimeType(), is(CONTENT_TYPE_JSON)); assertThat(result.getContent(), is(IMAGE_BODY)); @@ -535,9 +477,9 @@ public void getMediaContent_shouldReturnNullForNoContent() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); when(yotiHttpResponseMock.getResponseCode()).thenReturn(204); - when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createMediaContentPath(SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); - Media result = docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); + Media result = docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID); assertThat(result, is(nullValue())); } @@ -548,9 +490,9 @@ public void getMediaContent_shouldNotBeCaseSensitive() throws Exception { when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); when(yotiHttpResponseMock.getResponseHeaders()).thenReturn(createHeadersMap("content-type", "image/png")); when(yotiHttpResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); - when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createMediaContentPath(SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); - Media result = docScanService.getMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); + Media result = docScanService.getMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID); assertThat(result.getMimeType(), is("image/png")); assertThat(result.getContent(), is(IMAGE_BODY)); @@ -563,50 +505,36 @@ private Map> createHeadersMap(String key, String value) { } @Test - public void deleteMediaContent_shouldThrowExceptionWhenApplicationIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(null, null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void deleteMediaContent_shouldThrowExceptionWhenApplicationIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent("", null, null, null)); + public void deleteMediaContent_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(null, null, null)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void deleteMediaContent_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, null, null, null)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void deleteMediaContent_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, null, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(authStrategyMock, null, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void deleteMediaContent_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, "", null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(authStrategyMock, "", null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void deleteMediaContent_shouldThrowExceptionWhenMediaIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(authStrategyMock, SOME_SESSION_ID, null)); assertThat(ex.getMessage(), containsString("mediaId")); } @Test public void deleteMediaContent_shouldThrowExceptionWhenMediaIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteMediaContent(authStrategyMock, SOME_SESSION_ID, "")); assertThat(ex.getMessage(), containsString("mediaId")); } @@ -616,7 +544,7 @@ public void deleteMediaContent_shouldWrapGeneralSecurityException() throws Excep GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); @@ -628,7 +556,7 @@ public void deleteMediaContent_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the DELETE: Failed Request")); @@ -640,7 +568,7 @@ public void deleteMediaContent_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -651,7 +579,7 @@ public void deleteMediaContent_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID)); assertSame(ex.getCause(), uriSyntaxException); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); @@ -660,11 +588,11 @@ public void deleteMediaContent_shouldWrapURISyntaxException() throws Exception { @Test public void deleteMediaContent_shouldBuildSignedRequest() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); - when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createMediaContentPath(SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); - docScanService.deleteMediaContent(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_MEDIA_ID); + docScanService.deleteMediaContent(authStrategyMock, SOME_SESSION_ID, SOME_MEDIA_ID); - verify(yotiHttpRequestBuilderMock).withKeyPair(KEY_PAIR); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); @@ -693,43 +621,29 @@ public void shouldNotFailForUnknownChecks() throws Exception { } @Test - public void putIbvInstructions_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(null, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void putIbvInstructions_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions("", KEY_PAIR, SOME_SESSION_ID, instructionsMock)); + public void putIbvInstructions_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(null, SOME_SESSION_ID, instructionsMock)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void putIbvInstructions_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, null, SOME_SESSION_ID, instructionsMock)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void putIbvInstructions_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, null, instructionsMock)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(authStrategyMock, null, instructionsMock)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void putIbvInstructions_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, "", instructionsMock)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(authStrategyMock, "", instructionsMock)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void putIbvInstructions_shouldThrowExceptionWhenInstructionsIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, null)); assertThat(ex.getMessage(), containsString("instructions")); } @@ -739,7 +653,7 @@ public void putIbvInstructions_shouldWrapGeneralSecurityException() throws Excep GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -750,7 +664,7 @@ public void putIbvInstructions_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock)); assertThat(ex.getMessage(), containsString("Error executing the PUT: Failed Request")); } @@ -761,7 +675,7 @@ public void putIbvInstructions_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -771,42 +685,28 @@ public void putIbvInstructions_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, instructionsMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } @Test - public void getIbvInstructions_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions(null, KEY_PAIR, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void getIbvInstructions_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions("", KEY_PAIR, SOME_SESSION_ID)); + public void getIbvInstructions_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions(null, SOME_SESSION_ID)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void getIbvInstructions_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, null, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void getIbvInstructions_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions(authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void getIbvInstructions_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructions(authStrategyMock, "")); assertThat(ex.getMessage(), containsString("sessionId")); } @@ -816,7 +716,7 @@ public void getIbvInstructions_shouldWrapGeneralSecurityException() throws Excep GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -827,7 +727,7 @@ public void getIbvInstructions_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(InstructionsResponse.class)).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -838,7 +738,7 @@ public void getIbvInstructions_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(InstructionsResponse.class)).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -848,42 +748,30 @@ public void getIbvInstructions_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } @Test - public void getIbvInstructionsPdf_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf(null, KEY_PAIR, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void getIbvInstructionsPdf_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf("", KEY_PAIR, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void getIbvInstructionsPdf_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, null, SOME_SESSION_ID)); + public void getIbvInstructionsPdf_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf(null, SOME_SESSION_ID)); - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void getIbvInstructionsPdf_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf( + authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void getIbvInstructionsPdf_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf( + authStrategyMock, "")); assertThat(ex.getMessage(), containsString("sessionId")); } @@ -893,7 +781,7 @@ public void getIbvInstructionsPdf_shouldWrapGeneralSecurityException() throws Ex GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -904,7 +792,7 @@ public void getIbvInstructionsPdf_shouldWrapResourceException() throws Exception when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -915,7 +803,7 @@ public void getIbvInstructionsPdf_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -925,7 +813,7 @@ public void getIbvInstructionsPdf_shouldWrapURISyntaxException() throws Exceptio URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } @@ -936,9 +824,9 @@ public void getIbvInstructionsPdf_shouldReturnMedia() throws Exception { when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); when(yotiHttpResponseMock.getResponseHeaders()).thenReturn(createHeadersMap(CONTENT_TYPE, CONTENT_TYPE_JSON)); when(yotiHttpResponseMock.getResponseBody()).thenReturn(IMAGE_BODY); - when(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_SESSION_ID)).thenReturn(SOME_PATH); - Media result = docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); + Media result = docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID); assertThat(result.getMimeType(), is(CONTENT_TYPE_JSON)); assertThat(result.getContent(), is(IMAGE_BODY)); @@ -949,44 +837,32 @@ public void getIbvInstructionsPdf_shouldReturnNullForNoContent() throws Exceptio when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); when(yotiHttpResponseMock.getResponseCode()).thenReturn(204); - when(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_SESSION_ID)).thenReturn(SOME_PATH); - Media result = docScanService.getIbvInstructionsPdf(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); + Media result = docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID); assertThat(result, is(nullValue())); } @Test - public void fetchInstructionsContactProfile_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile(null, KEY_PAIR, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchInstructionsContactProfile_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile("", KEY_PAIR, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchInstructionsContactProfile_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, null, SOME_SESSION_ID)); + public void fetchInstructionsContactProfile_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile(null, SOME_SESSION_ID)); - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void fetchInstructionsContactProfile_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile( + authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void fetchInstructionsContactProfile_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile( + authStrategyMock, "")); assertThat(ex.getMessage(), containsString("sessionId")); } @@ -996,7 +872,7 @@ public void fetchInstructionsContactProfile_shouldWrapGeneralSecurityException() GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -1007,7 +883,7 @@ public void fetchInstructionsContactProfile_shouldWrapResourceException() throws when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(ContactProfileResponse.class)).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -1018,7 +894,7 @@ public void fetchInstructionsContactProfile_shouldWrapIOException() throws Excep when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(ContactProfileResponse.class)).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1028,42 +904,30 @@ public void fetchInstructionsContactProfile_shouldWrapURISyntaxException() throw URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } @Test - public void fetchSessionConfiguration_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration(null, KEY_PAIR, SOME_SESSION_ID)); + public void fetchSessionConfiguration_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration(null, SOME_SESSION_ID)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchSessionConfiguration_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration("", KEY_PAIR, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchSessionConfiguration_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, null, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void fetchSessionConfiguration_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration( + authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void fetchSessionConfiguration_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration( + authStrategyMock, "")); assertThat(ex.getMessage(), containsString("sessionId")); } @@ -1073,7 +937,7 @@ public void fetchSessionConfiguration_shouldWrapGeneralSecurityException() throw GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -1084,7 +948,7 @@ public void fetchSessionConfiguration_shouldWrapResourceException() throws Excep when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(SessionConfigurationResponse.class)).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -1095,7 +959,7 @@ public void fetchSessionConfiguration_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(SessionConfigurationResponse.class)).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1105,49 +969,38 @@ public void fetchSessionConfiguration_shouldWrapURISyntaxException() throws Exce URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } @Test - public void createFaceCaptureResource_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource(null, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); + public void createFaceCaptureResource_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource(null, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void createFaceCaptureResource_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource("", KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void createFaceCaptureResource_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, null, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void createFaceCaptureResource_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, null, createFaceCaptureResourcePayloadMock)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource( + authStrategyMock, null, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void createFaceCaptureResource_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, "", createFaceCaptureResourcePayloadMock)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource( + authStrategyMock, "", createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void createFaceCaptureResource_shouldThrowExceptionWhenPayloadIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createFaceCaptureResource( + authStrategyMock, SOME_SESSION_ID, null)); assertThat(ex.getMessage(), containsString("createFaceCaptureResourcePayload")); } @@ -1157,7 +1010,7 @@ public void createFaceCaptureResource_shouldWrapGeneralSecurityException() throw GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(authStrategyMock, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -1168,7 +1021,7 @@ public void createFaceCaptureResource_shouldWrapResourceException() throws Excep when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(CreateFaceCaptureResourceResponse.class)).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(authStrategyMock, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("Error executing the POST: Failed Request")); } @@ -1179,7 +1032,7 @@ public void createFaceCaptureResource_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(CreateFaceCaptureResourceResponse.class)).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(authStrategyMock, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1189,63 +1042,54 @@ public void createFaceCaptureResource_shouldWrapURISyntaxException() throws Exce URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(authStrategyMock, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } @Test - public void uploadFaceCaptureImage_shouldFailForNullSdkId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(null, null, null, null, null)); + public void uploadFaceCaptureImage_shouldFailForNullAuthStrategy() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(null, null, null, null)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void uploadFaceCaptureImage_shouldFailForEmptySdkId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage("", null, null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void uploadFaceCaptureImage_shouldFailForNullKeyPair() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, null, null, null, null)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void uploadFaceCaptureImage_shouldFailForNullSessionId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, null, null,null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage( + authStrategyMock, null, null,null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void uploadFaceCaptureImage_shouldFailForEmptySessionId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, "", null, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage( + authStrategyMock, "", null, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void uploadFaceCaptureImage_shouldFailForNullResourceId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, null,null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage( + authStrategyMock, SOME_SESSION_ID, null,null)); assertThat(ex.getMessage(), containsString("resourceId")); } @Test public void uploadFaceCaptureImage_shouldFailForEmptyResourceId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, "", null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage( + authStrategyMock, SOME_SESSION_ID, "", null)); assertThat(ex.getMessage(), containsString("resourceId")); } @Test public void uploadFaceCaptureImage_shouldFailForNullPayload() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage( + authStrategyMock, SOME_SESSION_ID, SOME_RESOURCE_ID, null)); assertThat(ex.getMessage(), containsString("faceCaptureImagePayload")); } @@ -1254,11 +1098,11 @@ public void uploadFaceCaptureImage_shouldFailForNullPayload() { public void uploadFaceCaptureImage_shouldWrapGeneralSecurityException() throws Exception { when(uploadFaceCaptureImagePayloadMock.getImageContents()).thenReturn(IMAGE_BODY); when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); - when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(authStrategyMock, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error executing the PUT: some gse")); @@ -1268,11 +1112,11 @@ public void uploadFaceCaptureImage_shouldWrapGeneralSecurityException() throws E public void uploadFaceCaptureImage_shouldWrapURISyntaxException() throws Exception { when(uploadFaceCaptureImagePayloadMock.getImageContents()).thenReturn(IMAGE_BODY); when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); - when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(authStrategyMock, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); assertSame(ex.getCause(), uriSyntaxException); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); @@ -1282,12 +1126,12 @@ public void uploadFaceCaptureImage_shouldWrapURISyntaxException() throws Excepti public void uploadFaceCaptureImage_shouldWrapIOException() throws Exception { when(uploadFaceCaptureImagePayloadMock.getImageContents()).thenReturn(IMAGE_BODY); when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); - when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); IOException ioException = new IOException("some IO exception"); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(authStrategyMock, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: some IO exception")); @@ -1297,48 +1141,36 @@ public void uploadFaceCaptureImage_shouldWrapIOException() throws Exception { public void uploadFaceCaptureImage_shouldWrapResourceException() throws Exception { when(uploadFaceCaptureImagePayloadMock.getImageContents()).thenReturn(IMAGE_BODY); when(uploadFaceCaptureImagePayloadMock.getImageContentType()).thenReturn(SOME_IMAGE_CONTENT_TYPE); - when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_APP_ID, SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createUploadFaceCaptureImagePath(SOME_SESSION_ID, SOME_RESOURCE_ID)).thenReturn(SOME_PATH); ResourceException resourceException = new ResourceException(400, "Failed Request", "Some response from API"); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.uploadFaceCaptureImage(authStrategyMock, SOME_SESSION_ID, SOME_RESOURCE_ID, uploadFaceCaptureImagePayloadMock)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the PUT: Failed Request")); } @Test - public void triggerIbvEmailNotification_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification(null, KEY_PAIR, SOME_SESSION_ID)); + public void triggerIbvEmailNotification_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification(null, SOME_SESSION_ID)); - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void triggerIbvEmailNotification_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification("", KEY_PAIR, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void triggerIbvEmailNotification_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, null, SOME_SESSION_ID)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); + assertThat(ex.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void triggerIbvEmailNotification_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification( + authStrategyMock, null)); assertThat(ex.getMessage(), containsString("sessionId")); } @Test public void triggerIbvEmailNotification_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.triggerIbvEmailNotification( + authStrategyMock, "")); assertThat(ex.getMessage(), containsString("sessionId")); } @@ -1348,7 +1180,7 @@ public void triggerIbvEmailNotification_shouldWrapGeneralSecurityException() thr GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the POST: some gse")); } @@ -1359,7 +1191,7 @@ public void triggerIbvEmailNotification_shouldWrapResourceException() throws Exc when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the POST: Failed Request")); } @@ -1370,7 +1202,7 @@ public void triggerIbvEmailNotification_shouldWrapIOException() throws Exception when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1380,24 +1212,17 @@ public void triggerIbvEmailNotification_shouldWrapURISyntaxException() throws Ex URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } - @Test - public void getSupportedDocuments_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getSupportedDocuments(null, false)); - - assertThat(ex.getMessage(), containsString("Application key Pair")); - } - @Test public void getSupportedDocuments_shouldWrapGeneralSecurityException() throws Exception { GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(false)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error executing the GET: some gse")); @@ -1409,7 +1234,7 @@ public void getSupportedDocuments_shouldWrapResourceException() throws Exception when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(SupportedDocumentsResponse.class)).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(false)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); @@ -1421,7 +1246,7 @@ public void getSupportedDocuments_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(SupportedDocumentsResponse.class)).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(false)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -1432,7 +1257,7 @@ public void getSupportedDocuments_shouldWrapURISyntaxException() throws Exceptio URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(KEY_PAIR, false)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(false)); assertSame(ex.getCause(), uriSyntaxException); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); @@ -1444,38 +1269,28 @@ public void getSupportedDocuments_shouldReturnSupportedDocuments() throws Except when(yotiHttpRequestMock.execute(SupportedDocumentsResponse.class)).thenReturn(supportedDocumentsResponseMock); when(unsignedPathFactoryMock.createGetSupportedDocumentsPath(false)).thenReturn(SOME_PATH); - SupportedDocumentsResponse result = docScanService.getSupportedDocuments(KEY_PAIR, false); + SupportedDocumentsResponse result = docScanService.getSupportedDocuments(false); assertThat(result, is(instanceOf(SupportedDocumentsResponse.class))); } @Test - public void getTrackedDevices_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices(null, KEY_PAIR, SOME_SESSION_ID)); - assertThat(exception.getMessage(), containsString("SDK ID")); - } - - @Test - public void getTrackedDevices_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices("", KEY_PAIR, SOME_SESSION_ID)); - assertThat(exception.getMessage(), containsString("SDK ID")); - } - - @Test - public void getTrackedDevices_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, null, SOME_SESSION_ID)); - assertThat(exception.getMessage(), containsString("Application key Pair")); + public void getTrackedDevices_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices(null, SOME_SESSION_ID)); + assertThat(exception.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void getTrackedDevices_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices( + authStrategyMock, null)); assertThat(exception.getMessage(), containsString("sessionId")); } @Test public void getTrackedDevices_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.getTrackedDevices( + authStrategyMock, "")); assertThat(exception.getMessage(), containsString("sessionId")); } @@ -1484,7 +1299,7 @@ public void getTrackedDevices_shouldWrapGeneralSecurityException() throws Except GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error executing the GET: some gse")); @@ -1496,7 +1311,7 @@ public void getTrackedDevices_shouldWrapResourceException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); @@ -1508,7 +1323,7 @@ public void getTrackedDevices_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -1519,7 +1334,7 @@ public void getTrackedDevices_shouldWrapURISyntaxException() throws Exception { URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), uriSyntaxException); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); @@ -1530,40 +1345,30 @@ public void getTrackedDevices_shouldReturnTrackedDevices() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); MetadataResponse metadataResponseMock = mock(MetadataResponse.class); when(yotiHttpRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenReturn(Collections.singletonList(metadataResponseMock)); - when(unsignedPathFactoryMock.createFetchTrackedDevices(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(unsignedPathFactoryMock.createFetchTrackedDevices(SOME_SESSION_ID)).thenReturn(SOME_PATH); - List result = docScanService.getTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID); + List result = docScanService.getTrackedDevices(authStrategyMock, SOME_SESSION_ID); assertThat(result.get(0), is(metadataResponseMock)); } @Test - public void deleteTrackedDevices_shouldThrowExceptionWhenSdkIdIsNull() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices(null, KEY_PAIR, SOME_SESSION_ID)); - assertThat(exception.getMessage(), containsString("SDK ID")); - } - - @Test - public void deleteTrackedDevices_shouldThrowExceptionWhenSdkIdIsEmpty() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices("", KEY_PAIR, SOME_SESSION_ID)); - assertThat(exception.getMessage(), containsString("SDK ID")); - } - - @Test - public void deleteTrackedDevices_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, null, SOME_SESSION_ID)); - assertThat(exception.getMessage(), containsString("Application key Pair")); + public void deleteTrackedDevices_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices(null, SOME_SESSION_ID)); + assertThat(exception.getMessage(), containsString("'authStrategy' must not be null.")); } @Test public void deleteTrackedDevices_shouldThrowExceptionWhenSessionIdIsNull() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, null)); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices( + authStrategyMock, null)); assertThat(exception.getMessage(), containsString("sessionId")); } @Test public void deleteTrackedDevices_shouldThrowExceptionWhenSessionIdIsEmpty() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, "")); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> docScanService.deleteTrackedDevices( + authStrategyMock, "")); assertThat(exception.getMessage(), containsString("sessionId")); } @@ -1572,7 +1377,7 @@ public void deleteTrackedDevices_shouldWrapGeneralSecurityException() throws Exc GeneralSecurityException gse = new GeneralSecurityException("some gse"); when(yotiHttpRequestBuilderMock.build()).thenThrow(gse); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error executing the GET: some gse")); @@ -1584,7 +1389,7 @@ public void deleteTrackedDevices_shouldWrapResourceException() throws Exception when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(resourceException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); @@ -1596,7 +1401,7 @@ public void deleteTrackedDevices_shouldWrapIOException() throws Exception { when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); when(yotiHttpRequestMock.execute()).thenThrow(ioException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -1607,7 +1412,7 @@ public void deleteTrackedDevices_shouldWrapURISyntaxException() throws Exception URISyntaxException uriSyntaxException = new URISyntaxException("someUrl", "Failed to build URI"); when(yotiHttpRequestBuilderMock.build()).thenThrow(uriSyntaxException); - DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(SOME_APP_ID, KEY_PAIR, SOME_SESSION_ID)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.deleteTrackedDevices(authStrategyMock, SOME_SESSION_ID)); assertSame(ex.getCause(), uriSyntaxException); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/ReceiptFetcherTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/ReceiptFetcherTest.java index 5ee4bc815..4b6a2911a 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/ReceiptFetcherTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/ReceiptFetcherTest.java @@ -6,14 +6,16 @@ import static org.bouncycastle.util.encoders.Base64.decode; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.hamcrest.core.StringContains.containsString; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; import java.security.KeyPair; import java.security.PublicKey; @@ -30,10 +32,12 @@ import com.yoti.api.client.spi.remote.util.CryptoUtil; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.*; +import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.junit.*; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ReceiptFetcherTest { @@ -62,7 +66,7 @@ public void setUp() throws Exception { @Test public void shouldFailForNullToken() { try { - testObj.fetch(null, keyPair, APP_ID); + testObj.fetch(null, keyPair); } catch (ProfileException ex) { assertThat(ex.getMessage(), containsString("Cannot decrypt connect token")); assertTrue(ex.getCause() instanceof NullPointerException); @@ -74,7 +78,7 @@ public void shouldFailForNullToken() { @Test public void shouldFailForNonBase64Token() { try { - testObj.fetch(TOKEN, keyPair, APP_ID); + testObj.fetch(TOKEN, keyPair); } catch (ProfileException ex) { assertThat(ex.getMessage(), containsString("Cannot decrypt connect token")); assertTrue(ex.getCause() instanceof IllegalArgumentException); @@ -86,7 +90,7 @@ public void shouldFailForNonBase64Token() { @Test public void shouldFailForBadlyEncryptedToken() { try { - testObj.fetch(Base64.getEncoder().encodeToString(TOKEN.getBytes()), keyPair, APP_ID); + testObj.fetch(Base64.getEncoder().encodeToString(TOKEN.getBytes()), keyPair); } catch (ProfileException ex) { assertThat(ex.getMessage(), containsString("Cannot decrypt connect token")); assertTrue(ex.getCause() instanceof ProfileException); @@ -99,10 +103,10 @@ public void shouldFailForBadlyEncryptedToken() { @Test public void shouldFailWithExceptionFromProfileService() throws Exception { ProfileException profileException = new ProfileException("Test exception"); - when(profileService.getProfile(any(KeyPair.class), anyString(), anyString())).thenThrow(profileException); + when(profileService.getProfile(any(KeyPair.class), anyString())).thenThrow(profileException); try { - testObj.fetch(encryptedToken, keyPair, APP_ID); + testObj.fetch(encryptedToken, keyPair); } catch (ProfileException ex) { assertSame(profileException, ex); return; @@ -112,10 +116,10 @@ public void shouldFailWithExceptionFromProfileService() throws Exception { @Test public void shouldFailWhenNoProfileReturned() throws Exception { - when(profileService.getProfile(any(KeyPair.class), anyString(), anyString())).thenReturn(null); + when(profileService.getProfile(any(KeyPair.class), anyString())).thenReturn(null); try { - testObj.fetch(encryptedToken, keyPair, APP_ID); + testObj.fetch(encryptedToken, keyPair); } catch (ProfileException e) { assertThat(e.getMessage(), containsString("No profile")); assertThat(e.getMessage(), containsString(TOKEN)); @@ -126,11 +130,11 @@ public void shouldFailWhenNoProfileReturned() throws Exception { @Test public void shouldFailWhenNoReceiptReturned() throws Exception { - when(profileService.getProfile(any(KeyPair.class), anyString(), anyString())) + when(profileService.getProfile(any(KeyPair.class), anyString())) .thenReturn(new ProfileResponse.ProfileResponseBuilder().build()); try { - testObj.fetch(encryptedToken, keyPair, APP_ID); + testObj.fetch(encryptedToken, keyPair); } catch (ProfileException e) { assertThat(e.getMessage(), containsString("No profile")); assertThat(e.getMessage(), containsString(TOKEN)); @@ -154,10 +158,10 @@ public void shouldFailForFailureReceiptWithErrorCode() throws Exception { .setReceipt(receipt) .setError(error) .build(); - when(profileService.getProfile(keyPair, APP_ID, TOKEN)).thenReturn(profileResponse); + when(profileService.getProfile(keyPair, TOKEN)).thenReturn(profileResponse); try { - testObj.fetch(encryptedToken, keyPair, APP_ID); + testObj.fetch(encryptedToken, keyPair); } catch (ActivityFailureException ex) { String exMsg = ex.getMessage(); assertThat(exMsg, containsString(ENCODED_RECEIPT_STRING)); @@ -182,10 +186,10 @@ public void shouldFailForFailureReceiptWithNoErrorCode() throws Exception { .build(); ProfileResponse profileResponse = new ProfileResponse.ProfileResponseBuilder().setReceipt(receipt).build(); - when(profileService.getProfile(keyPair, APP_ID, TOKEN)).thenReturn(profileResponse); + when(profileService.getProfile(keyPair, TOKEN)).thenReturn(profileResponse); try { - testObj.fetch(encryptedToken, keyPair, APP_ID); + testObj.fetch(encryptedToken, keyPair); } catch (ActivityFailureException ex) { assertThat(ex.getMessage(), containsString(ENCODED_RECEIPT_STRING)); assertThat(ex.getMessage(), not(containsString("error"))); @@ -215,10 +219,10 @@ public void shouldFailForFailureReceiptWithErrorReason() throws Exception { .setReceipt(receipt) .setError(error) .build(); - when(profileService.getProfile(keyPair, APP_ID, TOKEN)).thenReturn(profileResponse); + when(profileService.getProfile(keyPair, TOKEN)).thenReturn(profileResponse); try { - testObj.fetch(encryptedToken, keyPair, APP_ID); + testObj.fetch(encryptedToken, keyPair); } catch (ActivityFailureException ex) { String exMsg = ex.getMessage(); assertThat(exMsg, containsString(ENCODED_RECEIPT_STRING)); @@ -242,9 +246,9 @@ public void shouldReturnSuccessReceipt() throws Exception { .build(); ProfileResponse profileResponse = new ProfileResponse.ProfileResponseBuilder().setReceipt(receipt).build(); - when(profileService.getProfile(keyPair, APP_ID, TOKEN)).thenReturn(profileResponse); + when(profileService.getProfile(keyPair, TOKEN)).thenReturn(profileResponse); - Receipt result = testObj.fetch(encryptedToken, keyPair, APP_ID); + Receipt result = testObj.fetch(encryptedToken, keyPair); assertSame(result, receipt); } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java index c567f9f23..a4277fe8a 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java @@ -13,6 +13,7 @@ import java.util.Base64; import com.yoti.api.client.ProfileException; +import com.yoti.api.client.spi.remote.call.factory.ProfileSignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import org.junit.Before; @@ -45,6 +46,7 @@ public class ProfileServiceTest { @Mock UnsignedPathFactory unsignedPathFactory; + @Mock ProfileSignedRequestStrategy profileSignedRequestStrategyMock; @Mock YotiHttpRequest yotiHttpRequest; @BeforeClass @@ -55,26 +57,27 @@ public static void setUpClass() throws Exception { @Before public void setUp() { - when(unsignedPathFactory.createProfilePath(APP_ID, TOKEN)).thenReturn(GENERATED_PROFILE_PATH); + when(unsignedPathFactory.createProfilePath(TOKEN)).thenReturn(GENERATED_PROFILE_PATH); } @Test public void shouldReturnReceiptForCorrectRequest() throws Exception { - doReturn(yotiHttpRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + doReturn(yotiHttpRequest).when(testObj).createSignedRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); when(yotiHttpRequest.execute(ProfileResponse.class)).thenReturn(PROFILE_RESPONSE); - Receipt result = testObj.getReceipt(KEY_PAIR, APP_ID, TOKEN); + Receipt result = testObj.getReceipt(KEY_PAIR, TOKEN); + assertSame(RECEIPT, result); } @Test public void shouldThrowExceptionForIOError() throws Exception { IOException ioException = new IOException("Test exception"); - doReturn(yotiHttpRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + doReturn(yotiHttpRequest).when(testObj).createSignedRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); when(yotiHttpRequest.execute(ProfileResponse.class)).thenThrow(ioException); try { - testObj.getReceipt(KEY_PAIR, APP_ID, TOKEN); + testObj.getReceipt(KEY_PAIR, TOKEN); fail("Expected a ProfileException"); } catch (ProfileException e) { assertSame(ioException, e.getCause()); @@ -84,11 +87,11 @@ public void shouldThrowExceptionForIOError() throws Exception { @Test public void shouldThrowExceptionWithResourceExceptionCause() throws Throwable { ResourceException resourceException = new ResourceException(404, "Not Found", "Test exception"); - doReturn(yotiHttpRequest).when(testObj).createSignedRequest(KEY_PAIR, GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + doReturn(yotiHttpRequest).when(testObj).createSignedRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); when(yotiHttpRequest.execute(ProfileResponse.class)).thenThrow(resourceException); try { - testObj.getReceipt(KEY_PAIR, APP_ID, TOKEN); + testObj.getReceipt(KEY_PAIR, TOKEN); fail("Expected a ProfileException"); } catch (ProfileException e) { assertSame(resourceException, e.getCause()); @@ -97,17 +100,12 @@ public void shouldThrowExceptionWithResourceExceptionCause() throws Throwable { @Test(expected = IllegalArgumentException.class) public void shouldFailWithNullKeyPair() throws Exception { - testObj.getReceipt(null, APP_ID, TOKEN); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldFailWithNullAppId() throws Exception { - testObj.getReceipt(KEY_PAIR, null, TOKEN); + testObj.getReceipt(null, TOKEN); } @Test(expected = IllegalArgumentException.class) public void shouldFailWithNullConnectToken() throws Exception { - testObj.getReceipt(KEY_PAIR, APP_ID, null); + testObj.getReceipt(KEY_PAIR, null); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderTest.java index ea8e09c5e..c6dc3fc17 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderTest.java @@ -1,11 +1,11 @@ package com.yoti.api.client.spi.remote.call; +import static java.util.Arrays.asList; + import static com.yoti.api.client.spi.remote.call.HttpMethod.HTTP_GET; import static com.yoti.api.client.spi.remote.call.YotiConstants.CONTENT_TYPE; import static com.yoti.api.client.spi.remote.call.YotiConstants.DEFAULT_YOTI_API_URL; import static com.yoti.api.client.spi.remote.call.YotiConstants.DIGEST_HEADER; -import static com.yoti.api.client.spi.remote.util.CryptoUtil.KEY_PAIR_PEM; -import static com.yoti.api.client.spi.remote.util.CryptoUtil.generateKeyPairFrom; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -16,37 +16,33 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.IOException; import java.io.OutputStream; -import java.security.KeyPair; -import java.security.PrivateKey; import java.security.Security; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; +import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; import com.yoti.api.client.spi.remote.call.factory.HeadersFactory; -import com.yoti.api.client.spi.remote.call.factory.PathFactory; -import com.yoti.api.client.spi.remote.call.factory.SignedMessageFactory; import org.apache.http.Header; -import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicNameValuePair; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; @@ -62,14 +58,13 @@ public class YotiHttpRequestBuilderTest { private static final Map SIGNED_REQUEST_HEADERS; private static final String SOME_BASE_URL = "someBaseUrl"; private static final byte[] SOME_BYTES = "someBytes".getBytes(); - private static final String SIGNATURE_PARAMS_STRING = "nonce=someNonce×tamp=someTimestamp"; + private static final String SIGNATURE_PARAMS_STRING = "timestamp=someTimestamp"; private static final String SOME_MULTIPART_BODY_NAME = "someMultipartBodyName"; private static final byte[] SOME_MULTIPART_BODY = new byte[]{ 1, 2, 3, 4 }; private static final ContentType SOME_MULTIPART_CONTENT_TYPE = ContentType.IMAGE_JPEG; private static final String SOME_MULTIPART_FILE_NAME = "someMultipartFileName"; private static final String SOME_MULTIPART_BOUNDARY = "someMultipartBoundary"; private static final byte[] SOME_BUILT_MULTIPART_BODY = new byte[]{ 5, 6, 7, 8 }; - private static KeyPair KEY_PAIR; static { Security.addProvider(new BouncyCastleProvider()); @@ -78,22 +73,14 @@ public class YotiHttpRequestBuilderTest { SIGNED_REQUEST_HEADERS.put(YotiConstants.DIGEST_HEADER, SOME_SIGNATURE); } - @BeforeClass - public static void setUpClass() throws Exception { - KEY_PAIR = generateKeyPairFrom(KEY_PAIR_PEM); - } - @InjectMocks YotiHttpRequestBuilder yotiHttpRequestBuilder; - @Mock PathFactory pathFactoryMock; - @Mock SignedMessageFactory signedMessageFactoryMock; @Mock HeadersFactory headersFactoryMock; @Mock MultipartEntityBuilder multipartEntityBuilderMock; - @Captor ArgumentCaptor pathCaptor; @Mock(answer = Answers.RETURNS_SELF) HttpEntity httpEntityMock; - @Mock Header headerMock; - @Mock HeaderElement headerElementMock; + List
authHeaders = Collections.singletonList(mock(Header.class)); + @Mock AuthStrategy authStrategyMock; @Test public void withHttpMethod_shouldThrowExceptionWhenSuppliedWithUnsupportedHttpMethod() { @@ -108,11 +95,11 @@ public void withHttpMethod_shouldThrowExceptionWhenSuppliedWithUnsupportedHttpMe } @Test - public void build_shouldThrowExceptionWhenMissingKeyPair() throws Exception { + public void build_shouldThrowExceptionWhenMissingAuthStrategy() throws Exception { try { yotiHttpRequestBuilder.build(); } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("keyPair")); + assertThat(e.getMessage(), containsString("'authStrategy' must not be null")); return; } fail("Expected an IllegalArgumentException"); @@ -121,7 +108,7 @@ public void build_shouldThrowExceptionWhenMissingKeyPair() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingBaseUrl() throws Exception { try { - yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .build(); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("baseUrl")); @@ -133,7 +120,7 @@ public void build_shouldThrowExceptionWhenMissingBaseUrl() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingEndpoint() throws Exception { try { - yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .build(); } catch (IllegalArgumentException e) { @@ -146,7 +133,7 @@ public void build_shouldThrowExceptionWhenMissingEndpoint() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingHttpMethod() throws Exception { try { - yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .build(); @@ -159,9 +146,9 @@ public void build_shouldThrowExceptionWhenMissingHttpMethod() throws Exception { @Test public void build_shouldCreateSignedRequestWithCustomQueryParameter() throws Exception { - when(pathFactoryMock.createSignatureParams()).thenReturn(SIGNATURE_PARAMS_STRING); + when(authStrategyMock.createQueryParams()).thenReturn(asList(new BasicNameValuePair("timestamp", "someTimestamp"))); - YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -169,11 +156,12 @@ public void build_shouldCreateSignedRequestWithCustomQueryParameter() throws Exc .build(); assertThat(result.getUri().getQuery(), containsString(SIGNATURE_PARAMS_STRING)); + assertThat(result.getUri().getQuery(), containsString("someQueryParam=someParamValue")); } @Test public void build_shouldCreateSignedRequestWithProvidedHttpHeader() throws Exception { - YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(DEFAULT_YOTI_API_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -184,18 +172,19 @@ public void build_shouldCreateSignedRequestWithProvidedHttpHeader() throws Excep } @Test - public void build_shouldIgnoreAnyProvidedSignedRequestHeaders() throws Exception { - when(pathFactoryMock.createSignatureParams()).thenReturn(SIGNATURE_PARAMS_STRING); - when(signedMessageFactoryMock.create(any(PrivateKey.class), anyString(), anyString())).thenReturn(SOME_SIGNATURE); - when(headersFactoryMock.create(SOME_SIGNATURE)).thenReturn(SIGNED_REQUEST_HEADERS); + public void build_shouldIgnoreAnyProvidedAuthenticationHeaders() throws Exception { + when(authStrategyMock.createQueryParams()).thenReturn(asList(new BasicNameValuePair("timestamp", "someTimestamp"))); + when(authStrategyMock.createAuthHeaders(HTTP_GET, SOME_ENDPOINT + "?" + SIGNATURE_PARAMS_STRING, null)).thenReturn(authHeaders); + when(headersFactoryMock.create(authHeaders)).thenReturn(SIGNED_REQUEST_HEADERS); - YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(DEFAULT_YOTI_API_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) .withHeader(DIGEST_HEADER, "customHeaderValue") .build(); + verify(authStrategyMock).createAuthHeaders(HTTP_GET, SOME_ENDPOINT + "?" + SIGNATURE_PARAMS_STRING, null); assertThat(result.getHeaders(), hasEntry(DIGEST_HEADER, SOME_SIGNATURE)); } @@ -257,7 +246,7 @@ public void withMultipartBinaryBody_shouldThrowWhenFileNameIsEmpty() { @Test public void shouldRemoveTrailingSlashesFromBaseUrl() throws Exception { - YotiHttpRequest simpleYotiHttpRequest = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest simpleYotiHttpRequest = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL + "////////////") .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -268,19 +257,18 @@ public void shouldRemoveTrailingSlashesFromBaseUrl() throws Exception { @Test public void shouldCreateSignedRequestSuccessfullyWithRequiredFieldsOnly() throws Exception { - when(pathFactoryMock.createSignatureParams()).thenReturn(SIGNATURE_PARAMS_STRING); - when(signedMessageFactoryMock.create(any(PrivateKey.class), anyString(), anyString())).thenReturn(SOME_SIGNATURE); - when(headersFactoryMock.create(SOME_SIGNATURE)).thenReturn(SIGNED_REQUEST_HEADERS); + when(authStrategyMock.createQueryParams()).thenReturn(asList(new BasicNameValuePair("timestamp", "someTimestamp"))); + String fullPath = SOME_ENDPOINT + "?" + SIGNATURE_PARAMS_STRING; + when(authStrategyMock.createAuthHeaders(HTTP_GET, fullPath, null)).thenReturn(authHeaders); + when(headersFactoryMock.create(authHeaders)).thenReturn(SIGNED_REQUEST_HEADERS); - YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) .build(); - verify(signedMessageFactoryMock).create(eq(KEY_PAIR.getPrivate()), eq(HTTP_GET), pathCaptor.capture()); - assertThat(pathCaptor.getValue(), is(SOME_ENDPOINT + "?" + SIGNATURE_PARAMS_STRING)); - assertThat(result.getUri().toString(), is(SOME_BASE_URL + pathCaptor.getValue())); + assertThat(result.getUri().toString(), is(SOME_BASE_URL + fullPath)); assertThat(result.getMethod(), is(HTTP_GET)); assertThat(result.getHeaders().get(DIGEST_HEADER), containsString(SOME_SIGNATURE)); assertThat(result.getHeaders(), hasEntry(DIGEST_HEADER, SOME_SIGNATURE)); @@ -288,12 +276,13 @@ public void shouldCreateSignedRequestSuccessfullyWithRequiredFieldsOnly() throws } @Test - public void shouldCreatedSignedRequestSuccessfullyWithAllProperties() throws Exception { - when(pathFactoryMock.createSignatureParams()).thenReturn(SIGNATURE_PARAMS_STRING); - when(signedMessageFactoryMock.create(any(PrivateKey.class), anyString(), anyString(), any(byte[].class))).thenReturn(SOME_SIGNATURE); - when(headersFactoryMock.create(SOME_SIGNATURE)).thenReturn(SIGNED_REQUEST_HEADERS); + public void shouldCreateSignedRequestSuccessfullyWithAllProperties() throws Exception { + String fullPath = SOME_ENDPOINT + "?someQueryParam=someParamValue&someKey=someValue"; + when(authStrategyMock.createAuthHeaders(HTTP_GET, fullPath, SOME_BYTES)).thenReturn(authHeaders); + when(authStrategyMock.createQueryParams()).thenReturn(asList(new BasicNameValuePair("someKey","someValue"))); + when(headersFactoryMock.create(authHeaders)).thenReturn(SIGNED_REQUEST_HEADERS); - YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -302,9 +291,7 @@ public void shouldCreatedSignedRequestSuccessfullyWithAllProperties() throws Exc .withPayload(SOME_BYTES) .build(); - verify(signedMessageFactoryMock).create(eq(KEY_PAIR.getPrivate()), eq(HTTP_GET), pathCaptor.capture(), eq(SOME_BYTES)); - assertThat(pathCaptor.getValue(), is(SOME_ENDPOINT + "?someQueryParam=someParamValue&" + SIGNATURE_PARAMS_STRING)); - assertThat(result.getUri().toString(), is(SOME_BASE_URL + pathCaptor.getValue())); + assertThat(result.getUri().toString(), is(SOME_BASE_URL + fullPath)); assertThat(result.getMethod(), is(HTTP_GET)); assertThat(result.getHeaders().get(DIGEST_HEADER), containsString(SOME_SIGNATURE)); assertThat(result.getHeaders(), hasEntry(DIGEST_HEADER, SOME_SIGNATURE)); @@ -314,14 +301,8 @@ public void shouldCreatedSignedRequestSuccessfullyWithAllProperties() throws Exc @Test public void shouldSetContentTypeToMultipartWhenUserHasSetRequestTypeToMultipart() throws Exception { - when(pathFactoryMock.createSignatureParams()).thenReturn(SIGNATURE_PARAMS_STRING); - when(signedMessageFactoryMock.create(any(PrivateKey.class), anyString(), anyString(), any(byte[].class))).thenReturn(SOME_SIGNATURE); - when(headersFactoryMock.create(SOME_SIGNATURE)).thenReturn(SIGNED_REQUEST_HEADERS); when(multipartEntityBuilderMock.build()).thenReturn(httpEntityMock); - - when(headerElementMock.toString()).thenReturn(SOME_MULTIPART_CONTENT_TYPE.toString()); - when(headerMock.getElements()).thenReturn(new HeaderElement[]{ headerElementMock }); - when(httpEntityMock.getContentType()).thenReturn(headerMock); + when(httpEntityMock.getContentType()).thenReturn(new BasicHeader("Content-Type", SOME_MULTIPART_CONTENT_TYPE.toString())); // This is to overcome where we can't mock the OutputStream // in the getMultipartBodyAsBytes() method @@ -335,7 +316,7 @@ public void shouldSetContentTypeToMultipartWhenUserHasSetRequestTypeToMultipart( try (MockedStatic ms = Mockito.mockStatic(MultipartEntityBuilder.class)) { ms.when(MultipartEntityBuilder::create).thenReturn(multipartEntityBuilderMock); - YotiHttpRequest result = yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withMultipartBoundary(SOME_MULTIPART_BOUNDARY) .withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, SOME_MULTIPART_FILE_NAME) .withBaseUrl(SOME_BASE_URL) @@ -350,12 +331,8 @@ public void shouldSetContentTypeToMultipartWhenUserHasSetRequestTypeToMultipart( @Test public void shouldThrowIllegalArgumentExceptionWhenThereIsAnErrorBuildingTheMultipartBody() throws Exception { - when(pathFactoryMock.createSignatureParams()).thenReturn(SIGNATURE_PARAMS_STRING); when(multipartEntityBuilderMock.build()).thenReturn(httpEntityMock); - - when(headerElementMock.toString()).thenReturn(SOME_MULTIPART_CONTENT_TYPE.toString()); - when(headerMock.getElements()).thenReturn(new HeaderElement[]{headerElementMock}); - when(httpEntityMock.getContentType()).thenReturn(headerMock); + when(httpEntityMock.getContentType()).thenReturn(new BasicHeader(CONTENT_TYPE, SOME_MULTIPART_CONTENT_TYPE.toString())); IOException ioException = new IOException(); doThrow(ioException).when(httpEntityMock).writeTo(any(OutputStream.class)); @@ -364,7 +341,7 @@ public void shouldThrowIllegalArgumentExceptionWhenThereIsAnErrorBuildingTheMult ms.when(MultipartEntityBuilder::create).thenReturn(multipartEntityBuilderMock); IllegalStateException exception = assertThrows(IllegalStateException.class, () -> { - yotiHttpRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withMultipartBoundary(SOME_MULTIPART_BOUNDARY) .withMultipartBinaryBody(SOME_MULTIPART_BODY_NAME, SOME_MULTIPART_BODY, SOME_MULTIPART_CONTENT_TYPE, SOME_MULTIPART_FILE_NAME) .withBaseUrl(SOME_BASE_URL) diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java index 8c22c18c0..1345fb793 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java @@ -4,12 +4,10 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; -import static org.mockito.Answers.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; import java.io.IOException; -import java.security.KeyPair; import java.util.HashMap; import java.util.Map; @@ -34,7 +32,6 @@ @RunWith(MockitoJUnitRunner.class) public class RemoteAmlServiceTest { - private static final String SOME_APP_ID = "someAppId"; private static final String GENERATED_PATH = "generatedPath"; private static final String SERIALIZED_BODY = "serializedBody"; private static final byte[] BODY_BYTES = SERIALIZED_BODY.getBytes(); @@ -46,7 +43,6 @@ public class RemoteAmlServiceTest { @Mock ObjectMapper objectMapperMock; @Mock AmlProfile amlProfileMock; - @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPairMock; @Mock YotiHttpRequest yotiHttpRequestMock; @Mock AmlResult amlResultMock; @@ -57,16 +53,16 @@ public static void setUpClass() { @Before public void setUp() { - when(unsignedPathFactoryMock.createAmlPath(SOME_APP_ID)).thenReturn(GENERATED_PATH); + when(unsignedPathFactoryMock.createAmlPath()).thenReturn(GENERATED_PATH); } @Test public void shouldPerformAmlCheck() throws Exception { when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(GENERATED_PATH, BODY_BYTES); when(yotiHttpRequestMock.execute(AmlResult.class)).thenReturn(amlResultMock); - AmlResult result = testObj.performCheck(keyPairMock, SOME_APP_ID, amlProfileMock); + AmlResult result = testObj.performCheck(amlProfileMock); assertSame(result, amlResultMock); } @@ -75,11 +71,11 @@ public void shouldPerformAmlCheck() throws Exception { public void shouldWrapIOException() throws Exception { IOException ioException = new IOException(); when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(GENERATED_PATH, BODY_BYTES); when(yotiHttpRequestMock.execute(AmlResult.class)).thenThrow(ioException); try { - testObj.performCheck(keyPairMock, SOME_APP_ID, amlProfileMock); + testObj.performCheck(amlProfileMock); fail("Expected AmlException"); } catch (AmlException e) { assertSame(ioException, e.getCause()); @@ -90,11 +86,11 @@ public void shouldWrapIOException() throws Exception { public void shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(HTTP_UNAUTHORIZED, "Unauthorized", "failed verification"); when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(GENERATED_PATH, BODY_BYTES); when(yotiHttpRequestMock.execute(AmlResult.class)).thenThrow(resourceException); try { - testObj.performCheck(keyPairMock, SOME_APP_ID, amlProfileMock); + testObj.performCheck(amlProfileMock); fail("Expected AmlException"); } catch (AmlException e) { assertSame(resourceException, e.getCause()); @@ -107,26 +103,16 @@ public void shouldWrapJsonProcessingException() throws Exception { when(objectMapperMock.writeValueAsString(amlProfileMock)).thenThrow(jsonProcessingException); try { - testObj.performCheck(keyPairMock, SOME_APP_ID, amlProfileMock); + testObj.performCheck(amlProfileMock); fail("Expected AmlException"); } catch (AmlException e) { assertSame(jsonProcessingException, e.getCause()); } } - @Test(expected = IllegalArgumentException.class) - public void shouldFailWithNullKeyPair() throws Exception { - testObj.performCheck(null, SOME_APP_ID, amlProfileMock); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldFailWithNullAppId() throws Exception { - testObj.performCheck(keyPairMock, null, amlProfileMock); - } - @Test(expected = IllegalArgumentException.class) public void shouldFailWithNullAmlProfile() throws Exception { - testObj.performCheck(keyPairMock, SOME_APP_ID, null); + testObj.performCheck(null); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactoryTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactoryTest.java index 8f7d97ecb..aab3d3d4b 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactoryTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/HeadersFactoryTest.java @@ -1,7 +1,5 @@ package com.yoti.api.client.spi.remote.call.factory; -import static com.yoti.api.client.spi.remote.call.YotiConstants.AUTH_KEY_HEADER; -import static com.yoti.api.client.spi.remote.call.YotiConstants.DIGEST_HEADER; import static com.yoti.api.client.spi.remote.call.YotiConstants.JAVA; import static com.yoti.api.client.spi.remote.call.YotiConstants.SDK_VERSION; import static com.yoti.api.client.spi.remote.call.YotiConstants.YOTI_SDK_HEADER; @@ -10,34 +8,29 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsMapContaining.hasEntry; +import java.util.Collections; import java.util.Map; -import org.junit.*; +import org.apache.http.Header; +import org.apache.http.message.BasicHeader; +import org.junit.Test; public class HeadersFactoryTest { - private static final String SOME_DIGEST = "someDigest"; private static final String SOME_KEY = "someKey"; + private static final String SOME_VALUE = "someValue"; HeadersFactory testObj = new HeadersFactory(); @Test - public void shouldCreateWithDigest() { - Map result = testObj.create(SOME_DIGEST); + public void shouldCreate() { + Header header = new BasicHeader(SOME_KEY, SOME_VALUE); - assertThat(result, hasEntry(DIGEST_HEADER, SOME_DIGEST)); - assertThat(result, hasEntry(YOTI_SDK_HEADER, JAVA)); - assertThat(result, hasEntry(YOTI_SDK_VERSION_HEADER, SDK_VERSION)); - } - - @Test - public void shouldCreateWithDigestAndKey() { - Map result = testObj.create(SOME_DIGEST, SOME_KEY); + Map result = testObj.create(Collections.singletonList(header)); - assertThat(result, hasEntry(DIGEST_HEADER, SOME_DIGEST)); + assertThat(result, hasEntry(SOME_KEY, SOME_VALUE)); assertThat(result, hasEntry(YOTI_SDK_HEADER, JAVA)); assertThat(result, hasEntry(YOTI_SDK_VERSION_HEADER, SDK_VERSION)); - assertThat(result, hasEntry(AUTH_KEY_HEADER, SOME_KEY)); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/PathFactoryTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/PathFactoryTest.java deleted file mode 100644 index 0c36f4874..000000000 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/factory/PathFactoryTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.yoti.api.client.spi.remote.call.factory; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.net.URI; - -import org.junit.Test; - -public class PathFactoryTest { - - private static final String SOME_APP_ID = "someAppId"; - private static final String SOME_TOKEN = "someToken"; - private static final String SOME_SESSION_ID = "someSessionId"; - private static final String SOME_MEDIA_ID = "someMediaId"; - - private static PathFactory testObj = new PathFactory(); - - @Test - public void shouldCreateProfilePath() { - String result = testObj.createProfilePath(SOME_APP_ID, SOME_TOKEN); - - URI uri = URI.create(result); - assertEquals("/profile/" + SOME_TOKEN, uri.getPath()); - assertTrue(uri.getQuery().contains("appId=" + SOME_APP_ID)); - assertTrue(uri.getQuery().matches("(.*)nonce=(?i)[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}(.*)")); - assertTrue(uri.getQuery().contains("timestamp=")); - } - - @Test - public void shouldCreateAmlPath() { - String result = testObj.createAmlPath(SOME_APP_ID); - - URI uri = URI.create(result); - assertEquals("/aml-check", uri.getPath()); - assertTrue(uri.getQuery().contains("appId=" + SOME_APP_ID)); - assertTrue(uri.getQuery().matches("(.*)nonce=(?i)[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}(.*)")); - assertTrue(uri.getQuery().contains("timestamp=")); - } - - @Test - public void shouldCreateDynamicSharingPath() { - String result = testObj.createDynamicSharingPath(SOME_APP_ID); - - URI uri = URI.create(result); - assertEquals("/qrcodes/apps/" + SOME_APP_ID, uri.getPath()); - assertTrue(uri.getQuery().matches("(.*)nonce=(?i)[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}(.*)")); - assertTrue(uri.getQuery().contains("timestamp=")); - } - - @Test - public void shouldCreateNewYotiDocsSessionPath() { - String result = testObj.createNewYotiDocsSessionPath(SOME_APP_ID); - - URI uri = URI.create(result); - assertEquals("/sessions", uri.getPath()); - assertTrue(uri.getQuery().contains("sdkId=" + SOME_APP_ID)); - assertTrue(uri.getQuery().matches("(.*)nonce=(?i)[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}(.*)")); - assertTrue(uri.getQuery().contains("timestamp=")); - } - - @Test - public void shouldCreateYotiDocsSessionPath() { - String result = testObj.createGetYotiDocsSessionPath(SOME_APP_ID, SOME_SESSION_ID); - - URI uri = URI.create(result); - assertEquals("/sessions/" + SOME_SESSION_ID, uri.getPath()); - assertTrue(uri.getQuery().contains("sdkId=" + SOME_APP_ID)); - assertTrue(uri.getQuery().matches("(.*)nonce=(?i)[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}(.*)")); - assertTrue(uri.getQuery().contains("timestamp=")); - } - - @Test - public void shouldCreateMediaContentPath() { - String result = testObj.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID); - - URI uri = URI.create(result); - assertEquals("/sessions/" + SOME_SESSION_ID + "/media/" + SOME_MEDIA_ID + "/content", uri.getPath()); - assertTrue(uri.getQuery().contains("sdkId=" + SOME_APP_ID)); - assertTrue(uri.getQuery().matches("(.*)nonce=(?i)[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}(.*)")); - assertTrue(uri.getQuery().contains("timestamp=")); - } - - @Test - public void shouldCreateSupportedDocumentsPath() { - String result = testObj.createGetSupportedDocumentsPath(true); - - URI uri = URI.create(result); - assertEquals("/supported-documents", uri.getPath()); - assertTrue(uri.getQuery().contains("includeNonLatin=true")); - assertTrue(uri.getQuery().matches("(.*)nonce=(?i)[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}(.*)")); - assertTrue(uri.getQuery().contains("timestamp=")); - } - -} diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java index d80182b21..be48b6ab7 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java @@ -13,7 +13,6 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; -import java.security.KeyPair; import com.yoti.api.client.identity.MatchRequest; import com.yoti.api.client.identity.MatchResult; @@ -22,6 +21,7 @@ import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.DigitalIdentitySignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.yoti.json.ResourceMapper; @@ -33,7 +33,6 @@ import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; -import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) @@ -47,62 +46,33 @@ public class DigitalIdentityServiceTest { private static final String POST = "POST"; private static final byte[] A_BODY_BYTES = "aBody".getBytes(StandardCharsets.UTF_8); - @Spy @InjectMocks DigitalIdentityService identityService; + @InjectMocks DigitalIdentityService identityService; + + @Mock UnsignedPathFactory unsignedPathFactoryMock; + @Mock YotiHttpRequestBuilderFactory requestBuilderFactoryMock; + @Mock DigitalIdentitySignedRequestStrategy authStrategyMock; - @Mock UnsignedPathFactory unsignedPathFactory; @Mock(answer = RETURNS_DEEP_STUBS) YotiHttpRequestBuilder yotiHttpRequestBuilder; - @Mock YotiHttpRequestBuilderFactory requestBuilderFactory; - @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPair; @Mock YotiHttpRequest yotiHttpRequest; - @Mock ShareSessionRequest shareSessionRequest; @Mock ShareSession shareSession; - @Mock MatchRequest matchRequest; @Mock MatchResult matchResult; @Before public void setUp() { - when(unsignedPathFactory.createIdentitySessionPath()).thenReturn(SESSION_CREATION_PATH); - when(unsignedPathFactory.createIdentityMatchPath()).thenReturn(DIGITAL_ID_MATCH_PATH); - } - - @Test - public void createShareSession_NullSdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.createShareSession(null, keyPair, shareSessionRequest) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void createShareSession_EmptySdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.createShareSession("", keyPair, shareSessionRequest) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } + when(requestBuilderFactoryMock.create()).thenReturn(yotiHttpRequestBuilder); - @Test - public void createShareSession_NullKeyPair_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.createShareSession(SDK_ID, null, shareSessionRequest) - ); - - assertThat(ex.getMessage(), containsString("Application Key Pair")); + when(unsignedPathFactoryMock.createIdentitySessionPath()).thenReturn(SESSION_CREATION_PATH); + when(unsignedPathFactoryMock.createIdentityMatchPath()).thenReturn(DIGITAL_ID_MATCH_PATH); } @Test public void createShareSession_NullShareSessionRequest_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, null) + () -> identityService.createShareSession(null) ); assertThat(ex.getMessage(), containsString("Share Session request")); @@ -117,7 +87,7 @@ public void createShareSession_SerializingWrongPayload_Exception() { DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> identityService.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -130,16 +100,14 @@ public void createShareSession_SerializingWrongPayload_Exception() { public void createShareSession_BuildingRequestWithWrongUri_Exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); - when(identityService.createSignedRequest(SDK_ID, keyPair, SESSION_CREATION_PATH, POST, A_BODY_BYTES)) - .thenThrow(causeEx); + when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> identityService.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -153,16 +121,15 @@ public void createShareSession_BuildingRequestWithWrongQueryParams_Exception() t try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); + String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); - when(identityService.createSignedRequest(SDK_ID, keyPair, SESSION_CREATION_PATH, POST, A_BODY_BYTES)) - .thenThrow(causeEx); + when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> identityService.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -176,16 +143,15 @@ public void createShareSession_BuildingRequestWithWrongDigest_Exception() throws try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); + String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); - when(identityService.createSignedRequest(SDK_ID, keyPair, SESSION_CREATION_PATH, POST, A_BODY_BYTES)) - .thenThrow(causeEx); + when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> identityService.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -198,134 +164,41 @@ public void createShareSession_BuildingRequestWithWrongDigest_Exception() throws public void createShareSession_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); - - when(identityService.createSignedRequest(SDK_ID, keyPair, SESSION_CREATION_PATH, POST, A_BODY_BYTES)) - .thenReturn(yotiHttpRequest); - + + when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenReturn(yotiHttpRequest); when(yotiHttpRequest.execute(ShareSession.class)).thenReturn(shareSession); - ShareSession result = identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest); + ShareSession result = identityService.createShareSession(shareSessionRequest); + assertSame(shareSession, result); } } - @Test - public void createShareQrCode_NullSdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.createShareQrCode(null, keyPair, SESSION_ID) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void createShareQrCode_EmptySdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.createShareQrCode("", keyPair, SESSION_ID) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void createShareQrCode_NullKeyPair_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.createShareQrCode(SDK_ID, null, SESSION_ID) - ); - - assertThat(ex.getMessage(), containsString("Application Key Pair")); - } - @Test public void createShareQrCode_NullSessionId_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.createShareQrCode(SDK_ID, keyPair, null) + () -> identityService.createShareQrCode(null) ); assertThat(ex.getMessage(), containsString("Session ID")); } - @Test - public void fetchShareQrCode_NullSdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.fetchShareQrCode(null, keyPair, QR_CODE_ID) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchShareQrCode_EmptySdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.fetchShareQrCode("", keyPair, QR_CODE_ID) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchShareQrCode_NullKeyPair_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.fetchShareQrCode(SDK_ID, null, QR_CODE_ID) - ); - - assertThat(ex.getMessage(), containsString("Application Key Pair")); - } - @Test public void fetchShareQrCode_NullSessionId_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.fetchShareQrCode(SDK_ID, keyPair, null) + () -> identityService.fetchShareQrCode(null) ); assertThat(ex.getMessage(), containsString("QR Code ID")); } - @Test - public void fetchMatch_NullSdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.fetchMatch(null, keyPair, matchRequest) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchMatch_EmptySdkId_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.fetchMatch("", keyPair, matchRequest) - ); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } - - @Test - public void fetchMatch_NullKeyPair_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.fetchMatch(SDK_ID, null, matchRequest) - ); - - assertThat(ex.getMessage(), containsString("Application Key Pair")); - } - @Test public void fetchMatch_NullMatchRequest_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, null) + () -> identityService.fetchMatch(null) ); assertThat(ex.getMessage(), notNullValue()); @@ -340,7 +213,7 @@ public void fetchMatch_SerializingWrongPayload_Exception() { DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + () -> identityService.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -353,16 +226,15 @@ public void fetchMatch_SerializingWrongPayload_Exception() { public void fetchMatch_BuildingRequestWithWrongEndpoint_Exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); + String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); - when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) - .thenThrow(causeEx); + when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + () -> identityService.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -376,16 +248,16 @@ public void fetchMatch_BuildingRequestWithWrongQueryParams_Exception() throws Ex try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); + String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); - when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + () -> identityService.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -399,16 +271,16 @@ public void fetchMatch_BuildingRequestWithWrongDigest_Exception() throws Excepti try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); + String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); - when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + () -> identityService.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -422,14 +294,13 @@ public void fetchMatch_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(requestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilder); - - when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + + when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenReturn(yotiHttpRequest); when(yotiHttpRequest.execute(MatchResult.class)).thenReturn(matchResult); - MatchResult result = identityService.fetchMatch(SDK_ID, keyPair, matchRequest); + MatchResult result = identityService.fetchMatch(matchRequest); assertSame(matchResult, result); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java index 009fa8ea5..f56e1af25 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java @@ -60,17 +60,12 @@ public void setUp() { @Test(expected = IllegalArgumentException.class) public void shouldFailWithNullAppId() throws Exception { - testObj.createShareUrl(null, keyPairMock, simpleDynamicScenarioMock); - } - - @Test(expected = IllegalArgumentException.class) - public void shouldFailWithNullKeyPair() throws Exception { - testObj.createShareUrl(APP_ID, null, simpleDynamicScenarioMock); + testObj.createShareUrl(null, simpleDynamicScenarioMock); } @Test(expected = IllegalArgumentException.class) public void shouldFailWithNullDynamicScenario() throws Exception { - testObj.createShareUrl(APP_ID, keyPairMock, null); + testObj.createShareUrl(APP_ID, null); } @Test @@ -79,7 +74,7 @@ public void shouldThrowDynamicShareExceptionWhenParsingFails() throws Exception when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenThrow(jsonProcessingException); try { - testObj.createShareUrl(APP_ID, keyPairMock, simpleDynamicScenarioMock); + testObj.createShareUrl(APP_ID, simpleDynamicScenarioMock); fail("Expected a DynamicShareException"); } catch (DynamicShareException ex) { assertSame(jsonProcessingException, ex.getCause()); @@ -90,11 +85,11 @@ public void shouldThrowDynamicShareExceptionWhenParsingFails() throws Exception public void shouldThrowExceptionForIOError() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); IOException ioException = new IOException(); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenThrow(ioException); try { - testObj.createShareUrl(APP_ID, keyPairMock, simpleDynamicScenarioMock); + testObj.createShareUrl(APP_ID, simpleDynamicScenarioMock); fail("Expected a DynamicShareException"); } catch (DynamicShareException ex) { assertSame(ioException, ex.getCause()); @@ -105,11 +100,11 @@ public void shouldThrowExceptionForIOError() throws Exception { public void shouldThrowExceptionWithResourceExceptionCause() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); ResourceException resourceException = new ResourceException(404, "Not Found", "Test exception"); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenThrow(resourceException); try { - testObj.createShareUrl(APP_ID, keyPairMock, simpleDynamicScenarioMock); + testObj.createShareUrl(APP_ID, simpleDynamicScenarioMock); fail("Expected a DynamicShareException"); } catch (DynamicShareException ex) { assertSame(resourceException, ex.getCause()); @@ -119,10 +114,10 @@ public void shouldThrowExceptionWithResourceExceptionCause() throws Exception { @Test public void shouldReturnReceiptForCorrectRequest() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenReturn(shareUrlResultMock); - ShareUrlResult result = testObj.createShareUrl(APP_ID, keyPairMock, simpleDynamicScenarioMock); + ShareUrlResult result = testObj.createShareUrl(APP_ID, simpleDynamicScenarioMock); assertSame(shareUrlResultMock, result); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/SandboxPathFactory.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/SandboxPathFactory.java index 1cf115f8c..cb5213401 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/SandboxPathFactory.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/SandboxPathFactory.java @@ -1,16 +1,13 @@ package com.yoti.api.client.sandbox; import static java.lang.String.format; -import static java.util.UUID.randomUUID; -import com.yoti.api.client.spi.remote.call.factory.PathFactory; +public class SandboxPathFactory { -public class SandboxPathFactory extends PathFactory { - - private static final String CREATE_SANDBOX_TOKEN_PATH = "/apps/%s/tokens?timestamp=%s&nonce=%s"; + private static final String CREATE_SANDBOX_TOKEN_PATH = "/apps/%s/tokens"; public String createSandboxPath(String appId) { - return format(CREATE_SANDBOX_TOKEN_PATH, appId, createTimestamp(), randomUUID()); + return format(CREATE_SANDBOX_TOKEN_PATH, appId); } } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java index 74ab2dc17..06be9b5cb 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/YotiSandboxClient.java @@ -21,6 +21,7 @@ import com.yoti.api.client.spi.remote.call.YotiConstants; import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.SimpleSignedRequestStrategy; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; @@ -32,7 +33,7 @@ public class YotiSandboxClient { private static final String DEFAULT_SANDBOX_API_URL = DEFAULT_YOTI_HOST + YOTI_SANDBOX_PATH_PREFIX; private final String appId; - private final KeyPair keyPair; + private final SimpleSignedRequestStrategy authStrategy; private final String sandboxBasePath; private final ObjectMapper mapper; private final SandboxPathFactory sandboxPathFactory; @@ -47,9 +48,10 @@ public static YotiSandboxClientBuilder builder() { KeyPair keyPair, SandboxPathFactory pathFactory, ObjectMapper mapper, - ResourceFetcher resourceFetcher, YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { + ResourceFetcher resourceFetcher, + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.appId = appId; - this.keyPair = keyPair; + this.authStrategy = new SimpleSignedRequestStrategy(keyPair); this.sandboxPathFactory = pathFactory; this.mapper = mapper; this.resourceFetcher = resourceFetcher; @@ -66,7 +68,7 @@ public String setupSharingProfile(YotiTokenRequest yotiTokenRequest) { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withBaseUrl(sandboxBasePath) .withEndpoint(requestPath) - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withHttpMethod(HTTP_POST) .withPayload(body) .build(); diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java index d5c7f40d0..c41fd7150 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java @@ -19,6 +19,7 @@ import com.yoti.api.client.spi.remote.call.ResourceException; import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.DocsSignedRequestStrategy; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; @@ -33,14 +34,14 @@ public class DocScanSandboxClient { private final ObjectMapper mapper; private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String sdkId; - private final KeyPair keyPair; + private final DocsSignedRequestStrategy authStrategy; - DocScanSandboxClient(String sdkId, - KeyPair keyPair, + private DocScanSandboxClient(String sdkId, + DocsSignedRequestStrategy authStrategy, ObjectMapper mapper, YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.sdkId = sdkId; - this.keyPair = keyPair; + this.authStrategy = authStrategy; this.mapper = mapper; this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; this.docScanBaseUrl = System.getProperty(PROPERTY_YOTI_DOCS_URL, DEFAULT_DOC_SCAN_SANDBOX_API_URL); @@ -66,10 +67,9 @@ public void configureSessionResponse(String sessionId, ResponseConfig responseCo YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withBaseUrl(docScanBaseUrl) .withEndpoint(path) - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withHttpMethod(HttpMethod.HTTP_PUT) .withPayload(body) - .withQueryParameter("sdkId", sdkId) .build(); yotiHttpRequest.execute(); @@ -92,7 +92,7 @@ public void configureApplicationResponse(ResponseConfig sandboxExpectation) thro YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .withBaseUrl(docScanBaseUrl) .withEndpoint(path) - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withHttpMethod(HttpMethod.HTTP_PUT) .withPayload(body) .build(); @@ -132,7 +132,8 @@ public DocScanSandboxClient build() { notNullOrEmpty(sdkId, "sdkId"); notNull(keyPair, "keyPair"); - return new DocScanSandboxClient(sdkId, keyPair, new ObjectMapper(), new YotiHttpRequestBuilderFactory()); + return new DocScanSandboxClient(sdkId, new DocsSignedRequestStrategy(keyPair, sdkId), new ObjectMapper(), new YotiHttpRequestBuilderFactory()); } } + } diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java index 2742c65c3..a4a9ebda2 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/YotiSandboxClientTest.java @@ -58,8 +58,7 @@ public class YotiSandboxClientTest { public void setUp() throws Exception { when(yotiHttpRequestBuilderFactoryMock.create()).thenReturn(yotiHttpRequestBuilderMock); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); - testObj = new YotiSandboxClient(SOME_APP_ID, keyPairMock, sandboxPathFactoryMock, objectMapperMock, resourceFetcherMock, - yotiHttpRequestBuilderFactoryMock); + testObj = new YotiSandboxClient(SOME_APP_ID, keyPairMock, sandboxPathFactoryMock, objectMapperMock, resourceFetcherMock, yotiHttpRequestBuilderFactoryMock); } @Test diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java index a0e76ee2d..b6e4b4583 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClientTest.java @@ -4,7 +4,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -18,6 +18,7 @@ import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.DocsSignedRequestStrategy; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; @@ -26,7 +27,6 @@ import org.mockito.Answers; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) @@ -37,15 +37,17 @@ public class DocScanSandboxClientTest { private static final String SOME_SDK_ID = "someSdkId"; private static final String SOME_SESSION_ID = "someSessionId"; + @InjectMocks DocScanSandboxClient testObj; + @Mock YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; + @Mock ObjectMapper objectMapperMock; + @Mock DocsSignedRequestStrategy authStrategyMock; + @Mock(answer = Answers.RETURNS_SELF) YotiHttpRequestBuilder yotiHttpRequestBuilderMock; @Mock YotiHttpRequest yotiHttpRequestMock; @Mock ResponseConfig responseConfigMock; - @Mock ObjectMapper objectMapperMock; @Mock KeyPair keyPairMock; - @Spy @InjectMocks DocScanSandboxClient docScanSandboxClient; - @Before public void setUp() { when(yotiHttpRequestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilderMock); @@ -54,35 +56,25 @@ public void setUp() { @Test public void configureSessionResponse_shouldWrapIoException() throws Exception { IOException ioException = new IOException("Some error"); - when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); - when(yotiHttpRequestMock.execute()).thenThrow(ioException); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); + + SandboxException thrown = assertThrows(SandboxException.class, () -> testObj.configureSessionResponse(SOME_SESSION_ID, responseConfigMock)); - try { - docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); - } catch (SandboxException ex) { - assertThat(ex.getMessage(), containsString("Some error")); - return; - } - fail("Expected an exception"); + assertThat(thrown.getMessage(), containsString("Some error")); } @Test public void configureSessionResponse_shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(400, "Some error", "There was some error"); - when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); - when(yotiHttpRequestMock.execute()).thenThrow(resourceException); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); + + SandboxException thrown = assertThrows(SandboxException.class, () -> testObj.configureSessionResponse(SOME_SESSION_ID, responseConfigMock)); - try { - docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); - } catch (SandboxException ex) { - assertThat(ex.getMessage(), containsString("Some error")); - return; - } - fail("Expected an exception"); + assertThat(thrown.getMessage(), containsString("Some error")); } @Test @@ -90,10 +82,10 @@ public void configureSessionResponse_shouldCallSignedRequestBuilderWithCorrectVa when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); - docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); + testObj.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(yotiHttpRequestBuilderMock).withKeyPair(keyPairMock); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); verify(yotiHttpRequestBuilderMock).withEndpoint("/sessions/" + SOME_SESSION_ID + "/response-config"); verify(yotiHttpRequestBuilderMock).withPayload(SOME_BYTES); } @@ -103,12 +95,12 @@ public void configureApplicationResponse_shouldCallSignedRequestBuilderWithCorre when(objectMapperMock.writeValueAsBytes(responseConfigMock)).thenReturn(SOME_BYTES); when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); - FieldSetter.setField(docScanSandboxClient, "sdkId", SOME_SDK_ID); + FieldSetter.setField(testObj, "sdkId", SOME_SDK_ID); - docScanSandboxClient.configureApplicationResponse(responseConfigMock); + testObj.configureApplicationResponse(responseConfigMock); verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(yotiHttpRequestBuilderMock).withKeyPair(keyPairMock); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); verify(yotiHttpRequestBuilderMock).withEndpoint("/apps/" + SOME_SDK_ID + "/response-config"); verify(yotiHttpRequestBuilderMock).withPayload(SOME_BYTES); } From 42a101513bb377b0749244893aef655e2b878d18 Mon Sep 17 00:00:00 2001 From: Michael Buck Date: Thu, 11 Dec 2025 09:36:35 +0000 Subject: [PATCH 12/28] SDK-2771: [MB] Tidy up DigitalIdentityServiceTest --- .../identity/DigitalIdentityServiceTest.java | 64 ++++++++----------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java index be48b6ab7..7bf57793c 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java @@ -38,19 +38,15 @@ @RunWith(MockitoJUnitRunner.class) public class DigitalIdentityServiceTest { - private static final String SDK_ID = "anSdkId"; - private static final String SESSION_ID = "aSessionId"; - private static final String QR_CODE_ID = "aQrCodeId"; private static final String SESSION_CREATION_PATH = "aSessionCreationPath"; private static final String DIGITAL_ID_MATCH_PATH = "aDigitalIdMatchPath"; private static final String POST = "POST"; private static final byte[] A_BODY_BYTES = "aBody".getBytes(StandardCharsets.UTF_8); - @InjectMocks DigitalIdentityService identityService; + @InjectMocks DigitalIdentityService testObj; @Mock UnsignedPathFactory unsignedPathFactoryMock; @Mock YotiHttpRequestBuilderFactory requestBuilderFactoryMock; - @Mock DigitalIdentitySignedRequestStrategy authStrategyMock; @Mock(answer = RETURNS_DEEP_STUBS) YotiHttpRequestBuilder yotiHttpRequestBuilder; @@ -72,7 +68,7 @@ public void setUp() { public void createShareSession_NullShareSessionRequest_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.createShareSession(null) + () -> testObj.createShareSession(null) ); assertThat(ex.getMessage(), containsString("Share Session request")); @@ -87,7 +83,7 @@ public void createShareSession_SerializingWrongPayload_Exception() { DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -103,11 +99,11 @@ public void createShareSession_BuildingRequestWithWrongUri_Exception() throws Ex String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); - when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -121,15 +117,13 @@ public void createShareSession_BuildingRequestWithWrongQueryParams_Exception() t try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - - String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); - when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -143,15 +137,13 @@ public void createShareSession_BuildingRequestWithWrongDigest_Exception() throws try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - - String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); - when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -164,11 +156,11 @@ public void createShareSession_BuildingRequestWithWrongDigest_Exception() throws public void createShareSession_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - - when(identityService.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenReturn(yotiHttpRequest); + + when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenReturn(yotiHttpRequest); when(yotiHttpRequest.execute(ShareSession.class)).thenReturn(shareSession); - ShareSession result = identityService.createShareSession(shareSessionRequest); + ShareSession result = testObj.createShareSession(shareSessionRequest); assertSame(shareSession, result); } @@ -178,7 +170,7 @@ public void createShareSession_SessionRequest_exception() throws Exception { public void createShareQrCode_NullSessionId_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.createShareQrCode(null) + () -> testObj.createShareQrCode(null) ); assertThat(ex.getMessage(), containsString("Session ID")); @@ -188,7 +180,7 @@ public void createShareQrCode_NullSessionId_Exception() { public void fetchShareQrCode_NullSessionId_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.fetchShareQrCode(null) + () -> testObj.fetchShareQrCode(null) ); assertThat(ex.getMessage(), containsString("QR Code ID")); @@ -198,7 +190,7 @@ public void fetchShareQrCode_NullSessionId_Exception() { public void fetchMatch_NullMatchRequest_Exception() { IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, - () -> identityService.fetchMatch(null) + () -> testObj.fetchMatch(null) ); assertThat(ex.getMessage(), notNullValue()); @@ -213,7 +205,7 @@ public void fetchMatch_SerializingWrongPayload_Exception() { DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -226,15 +218,14 @@ public void fetchMatch_SerializingWrongPayload_Exception() { public void fetchMatch_BuildingRequestWithWrongEndpoint_Exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); - when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -248,16 +239,14 @@ public void fetchMatch_BuildingRequestWithWrongQueryParams_Exception() throws Ex try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - - String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); - when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -271,16 +260,14 @@ public void fetchMatch_BuildingRequestWithWrongDigest_Exception() throws Excepti try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - - String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); - when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -294,13 +281,12 @@ public void fetchMatch_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - - when(identityService.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenReturn(yotiHttpRequest); - when(yotiHttpRequest.execute(MatchResult.class)).thenReturn(matchResult); - MatchResult result = identityService.fetchMatch(matchRequest); + MatchResult result = testObj.fetchMatch(matchRequest); + assertSame(matchResult, result); } } From f20b97047d7049a100b79aa1e936cbc347f5edac Mon Sep 17 00:00:00 2001 From: Michael Buck Date: Fri, 12 Dec 2025 14:28:10 +0000 Subject: [PATCH 13/28] SDK-2771: [MB] Address SonarQube quality concern surrounding use of regex --- .../client/spi/remote/call/YotiHttpRequestBuilder.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java index 7e82311f8..9f1c408c7 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilder.java @@ -107,7 +107,13 @@ public YotiHttpRequestBuilder forSignedRequest(KeyPair keyPair) { * @return the updated builder */ public YotiHttpRequestBuilder withBaseUrl(String baseUrl) { - this.baseUrl = baseUrl.replaceAll("([/]+)$", ""); + int index; + for (index = baseUrl.length() - 1; index >= 0; index--) { + if (baseUrl.charAt(index) != '/') { + break; + } + } + this.baseUrl = baseUrl.substring(0, index + 1); return this; } From f6a4967b6cc38dedfe44665b07bba9f1d8f21395 Mon Sep 17 00:00:00 2001 From: Michael Buck Date: Mon, 15 Dec 2025 14:32:32 +0000 Subject: [PATCH 14/28] SDK-2771: Rename some internal methods createSignedRequest->createRequest --- .../spi/remote/call/ProfileService.java | 4 ++-- .../spi/remote/call/aml/RemoteAmlService.java | 4 ++-- .../call/identity/DigitalIdentityService.java | 20 +++++++++---------- .../call/qrcode/DynamicSharingService.java | 4 ++-- .../spi/remote/call/ProfileServiceTest.java | 6 +++--- .../remote/call/aml/RemoteAmlServiceTest.java | 6 +++--- .../identity/DigitalIdentityServiceTest.java | 17 ++++++++-------- .../qrcode/DynamicSharingServiceTest.java | 6 +++--- 8 files changed, 33 insertions(+), 34 deletions(-) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java index 2bc2f9a2f..b018efe31 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/ProfileService.java @@ -66,7 +66,7 @@ public ProfileResponse getProfile(KeyPair keyPair, String connectToken) throws P try { String authKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); - YotiHttpRequest yotiHttpRequest = createSignedRequest(path, authKey); + YotiHttpRequest yotiHttpRequest = createRequest(path, authKey); return fetchReceipt(yotiHttpRequest); } catch (IOException ioe) { throw new ProfileException("Error calling service to get profile", ioe); @@ -91,7 +91,7 @@ private ProfileResponse fetchReceipt(YotiHttpRequest yotiHttpRequest) throws IOE } } - YotiHttpRequest createSignedRequest(String path, String authKey) throws ProfileException { + YotiHttpRequest createRequest(String path, String authKey) throws ProfileException { try { return yotiHttpRequestBuilderFactory.create() .withAuthStrategy(profileSignedRequestStrategy) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java index d0a7c7807..eeac2314e 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlService.java @@ -63,7 +63,7 @@ public AmlResult performCheck(AmlProfile amlProfile) throws AmlException { String resourcePath = unsignedPathFactory.createAmlPath(); byte[] body = objectMapper.writeValueAsString(amlProfile).getBytes(DEFAULT_CHARSET); - YotiHttpRequest yotiHttpRequest = createSignedRequest(resourcePath, body); + YotiHttpRequest yotiHttpRequest = createRequest(resourcePath, body); return yotiHttpRequest.execute(AmlResult.class); } catch (IOException ioException) { throw new AmlException("Error communicating with AML endpoint", ioException); @@ -85,7 +85,7 @@ private AmlException createExceptionFromStatusCode(ResourceException ex) { } } - YotiHttpRequest createSignedRequest(String resourcePath, byte[] body) throws AmlException { + YotiHttpRequest createRequest(String resourcePath, byte[] body) throws AmlException { try { return yotiHttpRequestBuilderFactory.create() .withAuthStrategy(amlSignedRequestStrategy) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java index 5fced1179..22a6c4055 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java @@ -72,7 +72,7 @@ public ShareSession createShareSession(ShareSessionRequest shareSessionRequest) try { byte[] payload = ResourceMapper.writeValueAsString(shareSessionRequest); - return createSignedRequest(path, HTTP_POST, payload).execute(ShareSession.class); + return createRequest(path, HTTP_POST, payload).execute(ShareSession.class); } catch (IOException ex) { throw new DigitalIdentityException("Error while parsing the share session creation request ", ex); } catch (URISyntaxException ex) { @@ -90,7 +90,7 @@ public ShareSession fetchShareSession(String sessionId) throws DigitalIdentityEx LOG.debug("Requesting share session '{}' at '{}'", sessionId, path); try { - return createSignedRequest(path).execute(ShareSession.class); + return createRequest(path).execute(ShareSession.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session '{%s}' ", sessionId), @@ -107,7 +107,7 @@ public ShareSessionQrCode createShareQrCode(String sessionId) throws DigitalIden LOG.debug("Requesting share session '{}' QR code creation at '{}'", sessionId, path); try { - return createSignedRequest(path, HTTP_POST, EMPTY_JSON).execute(ShareSessionQrCode.class); + return createRequest(path, HTTP_POST, EMPTY_JSON).execute(ShareSessionQrCode.class); } catch (GeneralSecurityException ex) { throw new DigitalIdentityException("Error while signing the share QR code creation request ", ex); } catch (IOException | URISyntaxException | ResourceException ex) { @@ -123,7 +123,7 @@ public ShareSessionQrCode fetchShareQrCode(String qrCodeId) throws DigitalIdenti LOG.debug("Requesting share session QR code '{} at '{}'", qrCodeId, path); try { - return createSignedRequest(path).execute(ShareSessionQrCode.class); + return createRequest(path).execute(ShareSessionQrCode.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session QR code '{%s}' ", qrCodeId), @@ -149,7 +149,7 @@ private WrappedReceipt doFetchShareReceipt(String receiptId) { LOG.debug("Requesting share session receipt '{}' at '{}'", receiptId, path); try { - return createSignedRequest(path).execute(WrappedReceipt.class); + return createRequest(path).execute(WrappedReceipt.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session QR code '{%s}' ", receiptId), @@ -164,7 +164,7 @@ private ReceiptItemKey fetchShareReceiptKey(WrappedReceipt wrappedReceipt) throw LOG.debug("Requesting share session receipt item key '{}' at '{}'", wrappedItemKeyId, path); try { - return createSignedRequest(path).execute(ReceiptItemKey.class); + return createRequest(path).execute(ReceiptItemKey.class); } catch (Exception ex) { throw new DigitalIdentityException( String.format("Error while fetching the share session receipt key '{%s}' ", wrappedItemKeyId), @@ -180,7 +180,7 @@ public MatchResult fetchMatch(MatchRequest matchRequest) throws DigitalIdentityE try { byte[] payload = ResourceMapper.writeValueAsString(matchRequest); - return createSignedRequest(path, HTTP_POST, payload).execute(MatchResult.class); + return createRequest(path, HTTP_POST, payload).execute(MatchResult.class); } catch (IOException ex) { throw new DigitalIdentityException("Error while parsing the DID Match request", ex); } catch (URISyntaxException ex) { @@ -192,11 +192,11 @@ public MatchResult fetchMatch(MatchRequest matchRequest) throws DigitalIdentityE } } - YotiHttpRequest createSignedRequest(String path) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { - return createSignedRequest(path, HTTP_GET, null); + YotiHttpRequest createRequest(String path) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { + return createRequest(path, HTTP_GET, null); } - YotiHttpRequest createSignedRequest(String path, String method, byte[] payload) + YotiHttpRequest createRequest(String path, String method, byte[] payload) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { YotiHttpRequestBuilder request = requestBuilderFactory.create() .withAuthStrategy(authStrategy) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java index 190bca431..55cb0c597 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingService.java @@ -66,7 +66,7 @@ public ShareUrlResult createShareUrl(String appId, DynamicScenario dynamicScenar try { byte[] body = objectMapper.writeValueAsString(dynamicScenario).getBytes(DEFAULT_CHARSET); - YotiHttpRequest yotiHttpRequest = createSignedRequest(path, body); + YotiHttpRequest yotiHttpRequest = createRequest(path, body); return yotiHttpRequest.execute(ShareUrlResult.class); } catch (ResourceException ex) { @@ -76,7 +76,7 @@ public ShareUrlResult createShareUrl(String appId, DynamicScenario dynamicScenar } } - YotiHttpRequest createSignedRequest(String path, byte[] body) throws DynamicShareException { + YotiHttpRequest createRequest(String path, byte[] body) throws DynamicShareException { try { return yotiHttpRequestBuilderFactory.create() .withAuthStrategy(simpleSignedRequestStrategy) diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java index a4277fe8a..0b50dca59 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/ProfileServiceTest.java @@ -62,7 +62,7 @@ public void setUp() { @Test public void shouldReturnReceiptForCorrectRequest() throws Exception { - doReturn(yotiHttpRequest).when(testObj).createSignedRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + doReturn(yotiHttpRequest).when(testObj).createRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); when(yotiHttpRequest.execute(ProfileResponse.class)).thenReturn(PROFILE_RESPONSE); Receipt result = testObj.getReceipt(KEY_PAIR, TOKEN); @@ -73,7 +73,7 @@ public void shouldReturnReceiptForCorrectRequest() throws Exception { @Test public void shouldThrowExceptionForIOError() throws Exception { IOException ioException = new IOException("Test exception"); - doReturn(yotiHttpRequest).when(testObj).createSignedRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + doReturn(yotiHttpRequest).when(testObj).createRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); when(yotiHttpRequest.execute(ProfileResponse.class)).thenThrow(ioException); try { @@ -87,7 +87,7 @@ public void shouldThrowExceptionForIOError() throws Exception { @Test public void shouldThrowExceptionWithResourceExceptionCause() throws Throwable { ResourceException resourceException = new ResourceException(404, "Not Found", "Test exception"); - doReturn(yotiHttpRequest).when(testObj).createSignedRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + doReturn(yotiHttpRequest).when(testObj).createRequest(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); when(yotiHttpRequest.execute(ProfileResponse.class)).thenThrow(resourceException); try { diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java index 1345fb793..52dee5455 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/aml/RemoteAmlServiceTest.java @@ -59,7 +59,7 @@ public void setUp() { @Test public void shouldPerformAmlCheck() throws Exception { when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(GENERATED_PATH, BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createRequest(GENERATED_PATH, BODY_BYTES); when(yotiHttpRequestMock.execute(AmlResult.class)).thenReturn(amlResultMock); AmlResult result = testObj.performCheck(amlProfileMock); @@ -71,7 +71,7 @@ public void shouldPerformAmlCheck() throws Exception { public void shouldWrapIOException() throws Exception { IOException ioException = new IOException(); when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(GENERATED_PATH, BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createRequest(GENERATED_PATH, BODY_BYTES); when(yotiHttpRequestMock.execute(AmlResult.class)).thenThrow(ioException); try { @@ -86,7 +86,7 @@ public void shouldWrapIOException() throws Exception { public void shouldWrapResourceException() throws Exception { ResourceException resourceException = new ResourceException(HTTP_UNAUTHORIZED, "Unauthorized", "failed verification"); when(objectMapperMock.writeValueAsString(amlProfileMock)).thenReturn(SERIALIZED_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(GENERATED_PATH, BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createRequest(GENERATED_PATH, BODY_BYTES); when(yotiHttpRequestMock.execute(AmlResult.class)).thenThrow(resourceException); try { diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java index 7bf57793c..bdf8fd93c 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java @@ -21,7 +21,6 @@ import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; -import com.yoti.api.client.spi.remote.call.factory.DigitalIdentitySignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.yoti.json.ResourceMapper; @@ -99,7 +98,7 @@ public void createShareSession_BuildingRequestWithWrongUri_Exception() throws Ex String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); - when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, @@ -119,7 +118,7 @@ public void createShareSession_BuildingRequestWithWrongQueryParams_Exception() t String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); - when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, @@ -139,7 +138,7 @@ public void createShareSession_BuildingRequestWithWrongDigest_Exception() throws String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); - when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, @@ -157,7 +156,7 @@ public void createShareSession_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(shareSessionRequest)).thenReturn(A_BODY_BYTES); - when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenReturn(yotiHttpRequest); + when(testObj.createRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenReturn(yotiHttpRequest); when(yotiHttpRequest.execute(ShareSession.class)).thenReturn(shareSession); ShareSession result = testObj.createShareSession(shareSessionRequest); @@ -221,7 +220,7 @@ public void fetchMatch_BuildingRequestWithWrongEndpoint_Exception() throws Excep String exMessage = "URI wrong format"; URISyntaxException causeEx = new URISyntaxException("", exMessage); - when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); + when(testObj.createRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, @@ -241,7 +240,7 @@ public void fetchMatch_BuildingRequestWithWrongQueryParams_Exception() throws Ex String exMessage = "Wrong query params format"; UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); - when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(testObj.createRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenThrow(causeEx); DigitalIdentityException ex = assertThrows( @@ -262,7 +261,7 @@ public void fetchMatch_BuildingRequestWithWrongDigest_Exception() throws Excepti String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); - when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(testObj.createRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenThrow(causeEx); DigitalIdentityException ex = assertThrows( @@ -281,7 +280,7 @@ public void fetchMatch_SessionRequest_exception() throws Exception { try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); - when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + when(testObj.createRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenReturn(yotiHttpRequest); when(yotiHttpRequest.execute(MatchResult.class)).thenReturn(matchResult); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java index f56e1af25..6d7c79f5b 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/qrcode/DynamicSharingServiceTest.java @@ -85,7 +85,7 @@ public void shouldThrowDynamicShareExceptionWhenParsingFails() throws Exception public void shouldThrowExceptionForIOError() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); IOException ioException = new IOException(); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenThrow(ioException); try { @@ -100,7 +100,7 @@ public void shouldThrowExceptionForIOError() throws Exception { public void shouldThrowExceptionWithResourceExceptionCause() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); ResourceException resourceException = new ResourceException(404, "Not Found", "Test exception"); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenThrow(resourceException); try { @@ -114,7 +114,7 @@ public void shouldThrowExceptionWithResourceExceptionCause() throws Exception { @Test public void shouldReturnReceiptForCorrectRequest() throws Exception { when(objectMapperMock.writeValueAsString(simpleDynamicScenarioMock)).thenReturn(SOME_BODY); - doReturn(yotiHttpRequestMock).when(testObj).createSignedRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); + doReturn(yotiHttpRequestMock).when(testObj).createRequest(DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); when(yotiHttpRequestMock.execute(ShareUrlResult.class)).thenReturn(shareUrlResultMock); ShareUrlResult result = testObj.createShareUrl(APP_ID, simpleDynamicScenarioMock); From b2d94d0b6e3d0090c62b9032fed5b75662390d9d Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 16 Dec 2025 14:09:46 +0000 Subject: [PATCH 15/28] SDK-2771: Add NoAuthStrategy to be used on endpoints that don't require any authentication --- .../yoti/api/client/docs/DocScanService.java | 2 ++ .../remote/call/factory/NoAuthStrategy.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/NoAuthStrategy.java diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java index c52f4aa06..3799b760f 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanService.java @@ -37,6 +37,7 @@ import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; import com.yoti.api.client.spi.remote.call.YotiHttpResponse; import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; +import com.yoti.api.client.spi.remote.call.factory.NoAuthStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.annotation.JsonInclude; @@ -474,6 +475,7 @@ SupportedDocumentsResponse getSupportedDocuments(boolean includeNonLatin) throws try { YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(new NoAuthStrategy()) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_GET) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/NoAuthStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/NoAuthStrategy.java new file mode 100644 index 000000000..0f2f64b49 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/NoAuthStrategy.java @@ -0,0 +1,22 @@ +package com.yoti.api.client.spi.remote.call.factory; + +import java.security.GeneralSecurityException; +import java.util.Collections; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.NameValuePair; + +public class NoAuthStrategy implements AuthStrategy { + + @Override + public List
createAuthHeaders(String httpMethod, String endpoint, byte[] payload) throws GeneralSecurityException { + return Collections.emptyList(); + } + + @Override + public List createQueryParams() { + return Collections.emptyList(); + } + +} From 58ac25df146f5a0e74e809abc9a33e71cb097ec1 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Wed, 10 Dec 2025 14:43:16 +0000 Subject: [PATCH 16/28] SDK-2771: Add new maven module for supporting the creation of Yoti authentication tokens via API --- pom.xml | 1 + yoti-sdk-auth/pom.xml | 113 ++++++++++ .../auth/AuthenticationTokenGenerator.java | 193 ++++++++++++++++++ .../CreateAuthenticationTokenResponse.java | 47 +++++ .../java/com/yoti/auth/FormRequestClient.java | 84 ++++++++ .../main/java/com/yoti/auth/Properties.java | 17 ++ .../AuthenticationTokenGeneratorTest.java | 124 +++++++++++ .../java/com/yoti/auth/util/CryptoUtil.java | 64 ++++++ .../org.mockito.plugins.MockMaker | 1 + 9 files changed, 644 insertions(+) create mode 100644 yoti-sdk-auth/pom.xml create mode 100644 yoti-sdk-auth/src/main/java/com/yoti/auth/AuthenticationTokenGenerator.java create mode 100644 yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java create mode 100644 yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java create mode 100644 yoti-sdk-auth/src/main/java/com/yoti/auth/Properties.java create mode 100644 yoti-sdk-auth/src/test/java/com/yoti/auth/AuthenticationTokenGeneratorTest.java create mode 100644 yoti-sdk-auth/src/test/java/com/yoti/auth/util/CryptoUtil.java create mode 100644 yoti-sdk-auth/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/pom.xml b/pom.xml index 8d4b8a1b0..8005c4dd7 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,7 @@ yoti-sdk-parent yoti-sdk-api + yoti-sdk-auth yoti-sdk-sandbox yoti-sdk-spring-boot-auto-config yoti-sdk-spring-security diff --git a/yoti-sdk-auth/pom.xml b/yoti-sdk-auth/pom.xml new file mode 100644 index 000000000..f50af3922 --- /dev/null +++ b/yoti-sdk-auth/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + + + com.yoti + yoti-sdk-parent + 4.0.0-SNAPSHOT + ../yoti-sdk-parent + + + yoti-sdk-auth + + + 0.13.0 + + + + + org.bouncycastle + bcpkix-jdk18on + + + com.yoti + yoti-sdk-api + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + + + com.fasterxml.jackson.core + jackson-databind + + + commons-logging + commons-logging + 1.1.1 + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + runtime + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + runtime + + + + + org.hamcrest + hamcrest-library + test + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + + + + + org.owasp + dependency-check-maven + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + maven-enforcer-plugin + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + maven-source-plugin + + + maven-javadoc-plugin + + + org.jacoco + jacoco-maven-plugin + + + + + + + + maven-project-info-reports-plugin + + + + + diff --git a/yoti-sdk-auth/src/main/java/com/yoti/auth/AuthenticationTokenGenerator.java b/yoti-sdk-auth/src/main/java/com/yoti/auth/AuthenticationTokenGenerator.java new file mode 100644 index 000000000..8a0cf0369 --- /dev/null +++ b/yoti-sdk-auth/src/main/java/com/yoti/auth/AuthenticationTokenGenerator.java @@ -0,0 +1,193 @@ +package com.yoti.auth; + +import static com.yoti.validation.Validation.notNull; +import static com.yoti.validation.Validation.notNullOrEmpty; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyPair; +import java.time.OffsetDateTime; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Supplier; + +import com.yoti.api.client.InitialisationException; +import com.yoti.api.client.KeyPairSource; +import com.yoti.api.client.spi.remote.KeyStreamVisitor; +import com.yoti.api.client.spi.remote.call.ResourceException; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.jsonwebtoken.Jwts; + +/** + * The {@link AuthenticationTokenGenerator} is used for generation authorization tokens + * that can be used for accessing Yoti services. An authorization token must have + * a unique identifier, and an expiry timestamp. One or more scopes can be provided + * to allow the authorization token access to different parts of Yoti systems. + *

+ * The {@link AuthenticationTokenGenerator.Builder} can be accessed via {@code AuthorizationTokenGenerator.builder()} + * method, and then configured via the fluent API. + */ +public class AuthenticationTokenGenerator { + + private final String sdkId; + private final KeyPair keyPair; + private final Supplier jwtIdSupplier; + private final FormRequestClient formRequestClient; + + private final URL authApiUrl; + private final ObjectMapper objectMapper; + + AuthenticationTokenGenerator( + String sdkId, + KeyPair keyPair, + Supplier jwtIdSupplier, + FormRequestClient formRequestClient, + ObjectMapper objectMapper) { + this.sdkId = sdkId; + this.keyPair = keyPair; + this.jwtIdSupplier = jwtIdSupplier; + this.formRequestClient = formRequestClient; + this.objectMapper = objectMapper; + + try { + authApiUrl = new URL(System.getProperty(Properties.PROPERTY_YOTI_AUTH_URL, Properties.DEFAULT_YOTI_AUTH_URL)); + } catch (MalformedURLException e) { + throw new IllegalStateException("Invalid Yoti auth url", e); + } + } + + /** + * Creates a new instance of {@link AuthenticationTokenGenerator.Builder} + * + * @return the builder + */ + public static AuthenticationTokenGenerator.Builder builder() { + return new AuthenticationTokenGenerator.Builder(); + } + + /** + * Creates a new authentication token, using the supplied scopes and comment. + * + * @param scopes a list of scopes to be used by the authentication token + * @return a {@link CreateAuthenticationTokenResponse} containing information about the created token. + * @throws ResourceException if something was incorrect with the request to the Yoti authentication service + * @throws IOException + */ + public CreateAuthenticationTokenResponse generate(List scopes) throws ResourceException, IOException { + notNullOrEmpty(scopes, "scopes"); + + String jwts = createSignedJwt(sdkId, keyPair, jwtIdSupplier, authApiUrl); + + Map formParams = new HashMap<>(); + formParams.put("grant_type", "client_credentials"); + formParams.put("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"); + formParams.put("scope", String.join(" ", scopes)); + formParams.put("client_assertion", jwts); + + byte[] responseBody = formRequestClient.performRequest(authApiUrl, "POST", formParams); + + return objectMapper.readValue(responseBody, CreateAuthenticationTokenResponse.class); + } + + private String createSignedJwt(String sdkId, KeyPair keyPair, Supplier jwtIdSupplier, URL authApiUrl) { + String sdkIdProperty = String.format("sdk:%s", sdkId); + OffsetDateTime now = OffsetDateTime.now(); + return Jwts.builder() + .issuer(sdkIdProperty) + .subject(sdkIdProperty) + .id(jwtIdSupplier.get()) + .audience() + .add(authApiUrl.toString()) + .and() + .expiration(new Date(now.plusMinutes(5).toInstant().toEpochMilli())) + .issuedAt(new Date(now.toInstant().toEpochMilli())) + .header() + .add("alg", "PS384") + .add("typ", "JWT") + .and() + .signWith(keyPair.getPrivate(), Jwts.SIG.PS384) + .compact(); + } + + public static final class Builder { + + private String sdkId; + private KeyPairSource keyPairSource; + private Supplier jwtIdSupplier = () -> UUID.randomUUID().toString(); + + private Builder() { + } + + /** + * Sets the SDK ID that the authorization token will be generated against. + * + * @param sdkId the SDK ID + * @return the builder for method chaining. + */ + public Builder withSdkId(String sdkId) { + this.sdkId = sdkId; + return this; + } + + /** + * Sets the {@link KeyPairSource} that will be used to load the {@link KeyPair} + * + * @param keyPairSource the key pair source that will be used to load the {@link KeyPair} + * @return the builder for method chaining. + */ + public Builder withKeyPairSource(KeyPairSource keyPairSource) { + this.keyPairSource = keyPairSource; + return this; + } + + /** + * Sets the supplier that will be used to generate a unique ID for the + * authorization token. By default, this will be a UUID v4. + * + * @param jwtIdSupplier the supplier used for generating authorization token ID + * @return the builder for method chaining. + */ + public Builder withJwtIdSupplier(Supplier jwtIdSupplier) { + this.jwtIdSupplier = jwtIdSupplier; + return this; + } + + /** + * Builds an {@link AuthenticationTokenGenerator} using the values supplied to the {@link Builder}. + * + * @return the configured {@link AuthenticationTokenGenerator} + */ + public AuthenticationTokenGenerator build() { + notNullOrEmpty(sdkId, "sdkId"); + notNull(keyPairSource, "keyPairSource"); + notNull(jwtIdSupplier, "jwtIdSupplier"); + + ObjectMapper objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + return new AuthenticationTokenGenerator( + sdkId, + loadKeyPair(keyPairSource), + jwtIdSupplier, + new FormRequestClient(), + objectMapper + ); + } + + private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException { + try { + return kpSource.getFromStream(new KeyStreamVisitor()); + } catch (IOException e) { + throw new InitialisationException("Cannot load key pair", e); + } + } + + } + +} diff --git a/yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java b/yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java new file mode 100644 index 000000000..9d437c727 --- /dev/null +++ b/yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java @@ -0,0 +1,47 @@ +package com.yoti.auth; + +public final class CreateAuthenticationTokenResponse { + + private String accessToken; + private String tokenType; + private Integer expiresIn; + private String scope; + + /** + * Returns the Yoti Authentication token used to perform requests to other Yoti services. + * + * @return the newly created access token + */ + public String getAccessToken() { + return accessToken; + } + + /** + * Returns the type of the newly generated authentication token. + * + * @return the token type + */ + public String getTokenType() { + return tokenType; + } + + /** + * Returns the amount of time (in seconds) in which the newly generated Authentication Token + * will expire in. + * + * @return the time (in seconds) of when the token will expire + */ + public Integer getExpiresIn() { + return expiresIn; + } + + /** + * A whitespace delimited string of scopes that the Authentication token has. + * + * @return the scopes of the token as a whitespace delimited string + */ + public String getScope() { + return scope; + } + +} diff --git a/yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java b/yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java new file mode 100644 index 000000000..fbb46372c --- /dev/null +++ b/yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java @@ -0,0 +1,84 @@ +package com.yoti.auth; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.stream.Collectors; + +import com.yoti.api.client.spi.remote.call.ResourceException; +import com.yoti.api.client.spi.remote.util.QuietCloseable; + +/** + * Internal use only. + *

+ * The {@link FormRequestClient} is used for performing an application/x-www-form-urlencoded + * HTTP request using base Java libraries only. + */ +final class FormRequestClient { + + byte[] performRequest(URL url, String method, Map formParams) throws IOException, ResourceException { + byte[] postData = getData(formParams); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setRequestMethod(method); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + connection.setRequestProperty("Content-Length", Integer.toString(postData.length)); + connection.setRequestProperty("charset", StandardCharsets.UTF_8.toString()); + connection.setUseCaches(false); + connection.setInstanceFollowRedirects(false); + + try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { + wr.write(postData); + } + + return parseResponse(connection); + } + + private byte[] getData(Map params) { + return params.entrySet().stream() + .map(entry -> encode(entry.getKey()) + "=" + encode(entry.getValue())) + .collect(Collectors.joining("&")) + .getBytes(StandardCharsets.UTF_8); + } + + private static String encode(String v) { + try { + return URLEncoder.encode(v, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private byte[] parseResponse(HttpURLConnection httpUrlConnection) throws ResourceException, IOException { + int responseCode = httpUrlConnection.getResponseCode(); + if (responseCode >= HttpURLConnection.HTTP_BAD_REQUEST) { + byte[] responseBody = readBody(httpUrlConnection); + throw new ResourceException(responseCode, httpUrlConnection.getResponseMessage(), new String(responseBody)); + } + return readBody(httpUrlConnection); + } + + private byte[] readBody(HttpURLConnection httpURLConnection) throws IOException { + try (QuietCloseable inputStream = new QuietCloseable<>(httpURLConnection.getInputStream())) { + return readChunked(inputStream.get()); + } + } + + private byte[] readChunked(InputStream inputStream) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] byteChunk = new byte[4096]; + int n; + while ((n = inputStream.read(byteChunk)) > 0) { + byteArrayOutputStream.write(byteChunk, 0, n); + } + return byteArrayOutputStream.toByteArray(); + } + +} diff --git a/yoti-sdk-auth/src/main/java/com/yoti/auth/Properties.java b/yoti-sdk-auth/src/main/java/com/yoti/auth/Properties.java new file mode 100644 index 000000000..d72e30926 --- /dev/null +++ b/yoti-sdk-auth/src/main/java/com/yoti/auth/Properties.java @@ -0,0 +1,17 @@ +package com.yoti.auth; + +/** + * Internal use only. + *

+ * Contains property values used by the `yoti-sdk-auth` module for + * creating Yoti Authentication tokens. + */ +final class Properties { + + private static final String YOTI_AUTH_HOST = "https://auth.api.yoti.com"; + private static final String YOTI_AUTH_PATH_PREFIX = "/v1/oauth/token"; + + public static final String PROPERTY_YOTI_AUTH_URL = "yoti.auth.url"; + public static final String DEFAULT_YOTI_AUTH_URL = YOTI_AUTH_HOST + YOTI_AUTH_PATH_PREFIX; + +} diff --git a/yoti-sdk-auth/src/test/java/com/yoti/auth/AuthenticationTokenGeneratorTest.java b/yoti-sdk-auth/src/test/java/com/yoti/auth/AuthenticationTokenGeneratorTest.java new file mode 100644 index 000000000..cec6eb0af --- /dev/null +++ b/yoti-sdk-auth/src/test/java/com/yoti/auth/AuthenticationTokenGeneratorTest.java @@ -0,0 +1,124 @@ +package com.yoti.auth; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.KeyPair; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Supplier; + +import com.yoti.api.client.InitialisationException; +import com.yoti.api.client.KeyPairSource; +import com.yoti.auth.util.CryptoUtil; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class AuthenticationTokenGeneratorTest { + + private static final String SOME_AUTH_API_URL = "https://someAuthApiUrl"; + private static final String SOME_SDK_ID = "someSdkId"; + private static final Supplier SOME_JWT_ID_SUPPLIER = () -> UUID.randomUUID().toString(); + private static final byte[] SOME_RESPONSE_BODY = new byte[] { 1, 2, 3 }; + + @Mock FormRequestClient formRequestClientMock; + @Mock ObjectMapper objectMapperMock; + + @Mock KeyPairSource keyPairSourceMock; + @Mock CreateAuthenticationTokenResponse createAuthenticationTokenResponseMock; + + @Captor ArgumentCaptor urlArgumentCaptor; + @Captor ArgumentCaptor> formParamsCaptor; + + private KeyPair validKeyPair; + + @Before + public void setUp() throws IOException { + System.setProperty(Properties.PROPERTY_YOTI_AUTH_URL, SOME_AUTH_API_URL); + validKeyPair = CryptoUtil.generateKeyPairFrom(CryptoUtil.KEY_PAIR_PEM); + } + + @Test + public void builder_shouldThrowIfSdkIdIsNotProvided() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + AuthenticationTokenGenerator.builder().build(); + }); + + assertThat(exception.getMessage(), is("'sdkId' must not be empty or null")); + } + + @Test + public void builder_shouldThrowIfKeyPairSourceIsNotProvided() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + AuthenticationTokenGenerator.builder() + .withSdkId(SOME_SDK_ID) + .build(); + }); + + assertThat(exception.getMessage(), is("'keyPairSource' must not be null")); + } + + @Test + public void builder_shouldThrowIfKeyPairSourceIsNull() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + AuthenticationTokenGenerator.builder() + .withSdkId(SOME_SDK_ID) + .withKeyPairSource(null) + .build(); + }); + + assertThat(exception.getMessage(), is("'keyPairSource' must not be null")); + } + + @Test + public void builder_shouldThrowIfJwtIdSupplierIsNull() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + AuthenticationTokenGenerator.builder() + .withSdkId(SOME_SDK_ID) + .withKeyPairSource(keyPairSourceMock) + .withJwtIdSupplier(null) + .build(); + }); + + assertThat(exception.getMessage(), is("'jwtIdSupplier' must not be null")); + } + + @Test + public void shouldJoinScopesCorrectly() throws Exception { + when(formRequestClientMock.performRequest(urlArgumentCaptor.capture(), eq("POST"), formParamsCaptor.capture())).thenReturn(SOME_RESPONSE_BODY); + when(objectMapperMock.readValue(SOME_RESPONSE_BODY, CreateAuthenticationTokenResponse.class)).thenReturn(createAuthenticationTokenResponseMock); + + AuthenticationTokenGenerator tokenGenerator = new AuthenticationTokenGenerator(SOME_SDK_ID, validKeyPair, SOME_JWT_ID_SUPPLIER, formRequestClientMock, objectMapperMock); + + List scopes = Arrays.asList("scope1", "scope2", "scope3:read"); + + CreateAuthenticationTokenResponse result = tokenGenerator.generate(scopes); + + assertThat(result, is(createAuthenticationTokenResponseMock)); + + Map formParams = formParamsCaptor.getValue(); + assertThat(formParams.get("grant_type"), is("client_credentials")); + assertThat(formParams.get("client_assertion_type"), is("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")); + assertThat(formParams.get("scope"), is("scope1 scope2 scope3:read")); + + assertThat(urlArgumentCaptor.getValue().toString(), is(SOME_AUTH_API_URL)); + } + +} diff --git a/yoti-sdk-auth/src/test/java/com/yoti/auth/util/CryptoUtil.java b/yoti-sdk-auth/src/test/java/com/yoti/auth/util/CryptoUtil.java new file mode 100644 index 000000000..c8520df59 --- /dev/null +++ b/yoti-sdk-auth/src/test/java/com/yoti/auth/util/CryptoUtil.java @@ -0,0 +1,64 @@ +package com.yoti.auth.util; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.KeyPair; +import java.security.Security; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; + +public class CryptoUtil { + + public static final String KEY_PAIR_PEM = "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIIEogIBAAKCAQEAvTGVVGqq2jv9K1BwT8+7GAURqoZOT8gfk2vIT3YKf3ZEB2OG\n" + + "qp9qiAaZZpL4RJKOA9x3uJxC3XVIRa+8TpvWmpUnFJJZMotE/W6jjPvOLiu4V27m\n" + + "H0i1CNy5Icjx7g3Wo2Pj2AUEOqV+bB1we2VSbNhPpJHmN2azmOMRuc7SMyXukWy5\n" + + "EeS2ZlwD2cfm3jJdTmWysV6+D4t02y3DYckjRe3RA/5pOYYg7+qgL/fjtb8eUOx3\n" + + "08fwzlS0dXwuYegX0aJuUd4KOu/drDzg2KDHDKlUmuPgHTKwlKX/mgjaXbldB9ER\n" + + "pTyq68OtJ37TElNgTl/rashfbEaC3LbQtn3lFQIDAQABAoIBADS3XSmhcyvN7VQl\n" + + "XLYQZsxhlTOTqrx2Qb4dGTpy5KfxdzEr3TkrpE50sEexifXpdCLFSqKo/8SfSl0I\n" + + "g4rPx3NZPgNwZ+Q6hCWtr2q4OxIIYpwSLZLn+nGWtwsf57FyL61lRvZJJ42D0X8k\n" + + "kNQBPn9PoplzgddMCZz/IFBKva08WDlib6h9eBMUXxw94/kEpp1WBhWreq4trADg\n" + + "l8l4BHTheT259PmgDq8L83irGjxYbuMrlNrOigXfesgbyX8UBVVkTEqHUWNnNRAR\n" + + "XONm+75GJT8r51ijdpHfEnpy54bNTXT7KHVMaHmPSQIazylvQJQew0WVZ0a9VwvF\n" + + "QZPOngECgYEA9AngQ+GCJW9vC4UCtIpuWZajCw+KNXlw4rfpXJuajnm3O+znfO+q\n" + + "FQn8IA5u1Sw1DimvdLACSavCax0p6vvJtAxjTgPtID6OnBJ3cD0rjqAcqEbZ29Xu\n" + + "YeaAg0dnSRfb5wkpbk0EtK2RkFocwdM/ql1s8WkrFkqs681zRqGLs5UCgYEAxneH\n" + + "nuHkIq8O69h+CI1RmNZpLhQBspseHXbhwTzQIvqzdiIwlPTR9mfZsGrnCokb/0CC\n" + + "BvYih+GLZN62iEaf+aCUA+662BZrNAMwEY/k4Ris+sKFNT0tBNoPDOgqdnygH9gm\n" + + "coKdIDO9sPL0144U/Hq1YsdwuK2SDQcLY3ydC4ECgYA71QALJIsIKp4LMP1MznPn\n" + + "uysWVyUHn1KyA21Pq0blj6oBI0BOPWRx7BTIt0EtOr13T3kZHt4wuc/c+zV/y2PU\n" + + "pQTj58qHkU7drRljh1vaiB7+kwBvCbB8iEsR5LvKC/N6XaCuzmtM8REzVySd0PFX\n" + + "D7jaJ3LM8FodJi4RLyJVUQKBgEy80teACDHQ9jgC0ViFK9Oos6p5Wd6xU4eY+9k3\n" + + "plKgFNvMhHRT5QsdRHKOIx9TvFuJmb0PVnKrprYt1u4CQMDIcfLDT8NVh8XopaFk\n" + + "vd67J8cdh1v6d3m0xrT639BIh7FIZjVIg3B8ERBmIH1oFn05BQFYlCEUG7Cl1KV2\n" + + "/VIBAoGAYin6eHFtBXpPRMddTt4lLOFtpBb9gGp9DxKGAsH0pdfQYgZHz0xKtxrq\n" + + "6l+d2M9sRhtisxw8YevPFWEVtcUWxz+qESM+wzUMrmWSuwwxXyVgjR4rC8untfPM\n" + + "laDBX8dDBwBQ3i0FhvuGR/LEjHWr9hj00faKROHOLFim6wbRIkg=\n" + + "-----END RSA PRIVATE KEY-----"; + + static { + Security.addProvider(new BouncyCastleProvider()); + } + + public static KeyPair generateKeyPairFrom(String keyPairString) throws IOException { + KeyPair keyPair = null; + PEMParser reader = new PEMParser( + new BufferedReader(new InputStreamReader(new ByteArrayInputStream(keyPairString.getBytes())))); + + for (Object o; (o = reader.readObject()) != null; ) { + if (o instanceof PEMKeyPair) { + keyPair = new JcaPEMKeyConverter().getKeyPair((PEMKeyPair) o); + break; + } + } + reader.close(); + return keyPair; + } + +} diff --git a/yoti-sdk-auth/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/yoti-sdk-auth/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..1f0955d45 --- /dev/null +++ b/yoti-sdk-auth/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline From ebea14e2ff80c7ada2901cfa4385db9bcce53269 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Wed, 17 Dec 2025 11:29:26 +0000 Subject: [PATCH 17/28] SDK-2771: Read from the error stream if we get >= 400 HTTP status code from auth service --- .../src/main/java/com/yoti/auth/FormRequestClient.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java b/yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java index fbb46372c..becfc1dda 100644 --- a/yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java +++ b/yoti-sdk-auth/src/main/java/com/yoti/auth/FormRequestClient.java @@ -59,14 +59,14 @@ private static String encode(String v) { private byte[] parseResponse(HttpURLConnection httpUrlConnection) throws ResourceException, IOException { int responseCode = httpUrlConnection.getResponseCode(); if (responseCode >= HttpURLConnection.HTTP_BAD_REQUEST) { - byte[] responseBody = readBody(httpUrlConnection); + byte[] responseBody = readBody(httpUrlConnection.getErrorStream()); throw new ResourceException(responseCode, httpUrlConnection.getResponseMessage(), new String(responseBody)); } - return readBody(httpUrlConnection); + return readBody(httpUrlConnection.getInputStream()); } - private byte[] readBody(HttpURLConnection httpURLConnection) throws IOException { - try (QuietCloseable inputStream = new QuietCloseable<>(httpURLConnection.getInputStream())) { + private byte[] readBody(InputStream httpInputStream) throws IOException { + try (QuietCloseable inputStream = new QuietCloseable<>(httpInputStream)) { return readChunked(inputStream.get()); } } From 8404aaee7d15a81cbe0e859dcc169da03aba9600 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Wed, 17 Dec 2025 11:29:50 +0000 Subject: [PATCH 18/28] SDK-2771: Specify exact json property names for response from auth service --- .../com/yoti/auth/CreateAuthenticationTokenResponse.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java b/yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java index 9d437c727..3f4cb439c 100644 --- a/yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java +++ b/yoti-sdk-auth/src/main/java/com/yoti/auth/CreateAuthenticationTokenResponse.java @@ -1,10 +1,19 @@ package com.yoti.auth; +import com.fasterxml.jackson.annotation.JsonProperty; + public final class CreateAuthenticationTokenResponse { + @JsonProperty("access_token") private String accessToken; + + @JsonProperty("token_type") private String tokenType; + + @JsonProperty("expires_in") private Integer expiresIn; + + @JsonProperty("scope") private String scope; /** From 58c5244e51ac32f88faaa3d89bcf45196cbe6a59 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Fri, 12 Dec 2025 10:19:52 +0000 Subject: [PATCH 19/28] SDK-2771: Allow the DocScanSandboxClient to use authentication token in requests, instead of signed requests --- .../sandbox/docs/DocScanSandboxClient.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java index c41fd7150..02545d2c4 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/DocScanSandboxClient.java @@ -2,8 +2,7 @@ import static com.yoti.api.client.spi.remote.call.YotiConstants.DEFAULT_YOTI_HOST; import static com.yoti.api.client.spi.remote.call.YotiConstants.PROPERTY_YOTI_DOCS_URL; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; -import static com.yoti.api.client.spi.remote.util.Validation.notNullOrEmpty; +import static com.yoti.validation.Validation.notNullOrEmpty; import java.io.IOException; import java.net.URISyntaxException; @@ -19,6 +18,8 @@ import com.yoti.api.client.spi.remote.call.ResourceException; import com.yoti.api.client.spi.remote.call.YotiHttpRequest; import com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilderFactory; +import com.yoti.api.client.spi.remote.call.factory.AuthStrategy; +import com.yoti.api.client.spi.remote.call.factory.AuthTokenStrategy; import com.yoti.api.client.spi.remote.call.factory.DocsSignedRequestStrategy; import com.fasterxml.jackson.databind.ObjectMapper; @@ -34,10 +35,10 @@ public class DocScanSandboxClient { private final ObjectMapper mapper; private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; private final String sdkId; - private final DocsSignedRequestStrategy authStrategy; + private final AuthStrategy authStrategy; private DocScanSandboxClient(String sdkId, - DocsSignedRequestStrategy authStrategy, + AuthStrategy authStrategy, ObjectMapper mapper, YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.sdkId = sdkId; @@ -107,10 +108,15 @@ public static class Builder { private static final Logger LOGGER = LoggerFactory.getLogger(Builder.class); + private String authToken; private String sdkId; private KeyPair keyPair; - private Builder() { + private Builder() {} + + public Builder withAuthenticationToken(String authenticationToken) { + this.authToken = authenticationToken; + return this; } public Builder withSdkId(String sdkId) { @@ -130,10 +136,28 @@ public Builder withKeyPair(KeyPairSource keyPairSource) { public DocScanSandboxClient build() { notNullOrEmpty(sdkId, "sdkId"); - notNull(keyPair, "keyPair"); - return new DocScanSandboxClient(sdkId, new DocsSignedRequestStrategy(keyPair, sdkId), new ObjectMapper(), new YotiHttpRequestBuilderFactory()); + if (authToken == null) { + validateForSignedRequest(); + return new DocScanSandboxClient(sdkId, new DocsSignedRequestStrategy(keyPair, sdkId), new ObjectMapper(), new YotiHttpRequestBuilderFactory()); + } else { + validateAuthToken(); + return new DocScanSandboxClient(sdkId, new AuthTokenStrategy(authToken), new ObjectMapper(), new YotiHttpRequestBuilderFactory()); + } + } + + private void validateForSignedRequest() { + if (sdkId == null || sdkId.isEmpty() || keyPair == null) { + throw new IllegalStateException("An sdkId and KeyPairSource must be provided when not using an authentication token"); + } } + + private void validateAuthToken() { + if (keyPair != null) { + throw new IllegalStateException("Must not supply KeyPairSource when using an authentication token"); + } + } + } } From a53d1a1d01d04f7aaeccb40e9ee2b6aa52065667 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 6 Jan 2026 12:06:27 +0000 Subject: [PATCH 20/28] Test: see if running jobs in parallel is causing issues with maven --- .github/workflows/junit.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/junit.yml b/.github/workflows/junit.yml index 32bf8fd46..0f952df5b 100644 --- a/.github/workflows/junit.yml +++ b/.github/workflows/junit.yml @@ -16,6 +16,7 @@ jobs: fail-fast: false matrix: jdk-version: [8,11,17] + max-parallel: 1 steps: - uses: actions/checkout@v4 From 3f1973491043a7c42685fec1e7b3f2da033df79d Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 6 Jan 2026 10:44:14 +0000 Subject: [PATCH 21/28] SDK-2756: Add support for requesting, and fetching Share Code resources + tasks --- .../api/client/docs/DocScanConstants.java | 2 + .../create/RequiredShareCodePayload.java | 68 +++++++++++++++++++ .../docs/session/create/SessionSpec.java | 32 ++++++++- .../session/retrieve/IdPhotoResponse.java | 16 +++++ .../retrieve/LookupProfileResponse.java | 16 +++++ .../session/retrieve/ResourceContainer.java | 12 ++++ .../retrieve/ReturnedProfileResponse.java | 16 +++++ .../retrieve/ShareCodeResourceResponse.java | 41 +++++++++++ .../retrieve/ShareCodeTaskResponse.java | 4 ++ .../docs/session/retrieve/TaskResponse.java | 1 + .../docs/session/create/SessionSpecTest.java | 39 +++++++++++ 11 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeResourceResponse.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeTaskResponse.java diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanConstants.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanConstants.java index 9ae74306d..5db1774a8 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanConstants.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/DocScanConstants.java @@ -36,6 +36,8 @@ private DocScanConstants() { } public static final String SUPPLEMENTARY_DOCUMENT_TEXT_DATA_CHECK = "SUPPLEMENTARY_DOCUMENT_TEXT_DATA_CHECK"; public static final String SUPPLEMENTARY_DOCUMENT_TEXT_DATA_EXTRACTION = "SUPPLEMENTARY_DOCUMENT_TEXT_DATA_EXTRACTION"; + public static final String VERIFY_SHARE_CODE_TASK = "VERIFY_SHARE_CODE_TASK"; + public static final String LIVENESS = "LIVENESS"; public static final String ZOOM = "ZOOM"; public static final String STATIC = "STATIC"; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java new file mode 100644 index 000000000..40d1eeeed --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java @@ -0,0 +1,68 @@ +package com.yoti.api.client.docs.session.create; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RequiredShareCodePayload { + + @JsonProperty("issuer") + private final String issuer; + + @JsonProperty("scheme") + private final String scheme; + + private RequiredShareCodePayload(String issuer, String scheme) { + this.issuer = issuer; + this.scheme = scheme; + } + + public String getIssuer() { + return issuer; + } + + public String getScheme() { + return scheme; + } + + public static RequiredShareCodePayload.Builder builder() { + return new RequiredShareCodePayload.Builder(); + } + + public static final class Builder { + + private String issuer; + private String scheme; + + /** + * Sets the issuer of the required Share Code + * + * @param issuer the issuer + * @return the builder + */ + public Builder withIssuer(String issuer) { + this.issuer = issuer; + return this; + } + + /** + * Sets the scheme of the required Share Code + * + * @param scheme the scheme + * @return + */ + public Builder withScheme(String scheme) { + this.scheme = scheme; + return this; + } + + /** + * Builds an {@link RequiredShareCodePayload} using the supplied properties in the builder. + * + * @return the built {@link RequiredShareCodePayload} + */ + public RequiredShareCodePayload build() { + return new RequiredShareCodePayload(issuer, scheme); + } + + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java index 834bbbb15..fc1a73151 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java @@ -69,6 +69,9 @@ public class SessionSpec { @JsonProperty("create_identity_profile_preview") private final Boolean createIdentityProfilePreview; + @JsonProperty("required_share_codes") + private final List requiredShareCodes; + SessionSpec(Integer clientSessionTokenTtl, Integer resourcesTtl, ImportTokenPayload importToken, @@ -85,7 +88,8 @@ public class SessionSpec { SubjectPayload subject, ResourceCreationContainer resources, Boolean createIdentityProfilePreview, - AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements) { + AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements, + List requiredShareCodes) { this.clientSessionTokenTtl = clientSessionTokenTtl; this.resourcesTtl = resourcesTtl; this.importToken = importToken; @@ -103,6 +107,7 @@ public class SessionSpec { this.resources = resources; this.createIdentityProfilePreview = createIdentityProfilePreview; this.advancedIdentityProfileRequirements = advancedIdentityProfileRequirements; + this.requiredShareCodes = requiredShareCodes; } public static Builder builder() { @@ -263,6 +268,15 @@ public AdvancedIdentityProfileRequirementsPayload getAdvancedIdentityProfileRequ return advancedIdentityProfileRequirements; } + /** + * The list of Share Codes being requested. + * + * @return the requested Share Codes + */ + public List getRequiredShareCodes() { + return requiredShareCodes; + } + public static class Builder { private final List> requestedChecks; @@ -282,11 +296,13 @@ public static class Builder { private SubjectPayload subject; private ResourceCreationContainer resources; private Boolean createIdentityProfilePreview; + private final List requiredShareCodes; private Builder() { requestedChecks = new ArrayList<>(); requestedTasks = new ArrayList<>(); requiredDocuments = new ArrayList<>(); + requiredShareCodes = new ArrayList<>(); } /** @@ -477,6 +493,17 @@ public Builder withAdvancedIdentityProfileRequirements(AdvancedIdentityProfileRe return this; } + /** + * Adds a required Share Code to the list + * + * @param requiredShareCode the required share code + * @return the builder + */ + public Builder withRequiredShareCode(RequiredShareCodePayload requiredShareCode) { + this.requiredShareCodes.add(requiredShareCode); + return this; + } + /** * Builds the {@link SessionSpec} based on the values supplied to the builder * @@ -500,7 +527,8 @@ public SessionSpec build() { subject, resources, createIdentityProfilePreview, - advancedIdentityProfileRequirementsPayload); + advancedIdentityProfileRequirementsPayload, + requiredShareCodes); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java new file mode 100644 index 000000000..79c27f8fd --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java @@ -0,0 +1,16 @@ +package com.yoti.api.client.docs.session.retrieve; + +import com.yoti.api.client.Media; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class IdPhotoResponse { + + @JsonProperty("media") + private Media media; + + public Media getMedia() { + return media; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java new file mode 100644 index 000000000..8b774239f --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java @@ -0,0 +1,16 @@ +package com.yoti.api.client.docs.session.retrieve; + +import com.yoti.api.client.Media; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class LookupProfileResponse { + + @JsonProperty("media") + private Media media; + + public Media getMedia() { + return media; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ResourceContainer.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ResourceContainer.java index 8d25c591c..1bf7bc810 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ResourceContainer.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ResourceContainer.java @@ -23,6 +23,9 @@ public class ResourceContainer { @JsonProperty("applicant_profiles") private List applicantProfiles; + @JsonProperty("share_codes") + private List shareCodes; + /** * Returns ID documents that were uploaded by the user * @@ -97,6 +100,15 @@ public List getApplicantProfiles() { return applicantProfiles; } + /** + * Returns ShareCode resources uploaded by the user + * + * @return the list of Share Code resources + */ + public List getShareCodes() { + return shareCodes; + } + ResourceContainer filterForCheck(CheckResponse checkResponse) { ResourceContainer newResourceContainer = new ResourceContainer(); newResourceContainer.idDocuments = filterResources(this.idDocuments, checkResponse.getResourcesUsed()); diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java new file mode 100644 index 000000000..486f7e05e --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java @@ -0,0 +1,16 @@ +package com.yoti.api.client.docs.session.retrieve; + +import com.yoti.api.client.Media; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ReturnedProfileResponse { + + @JsonProperty("media") + private Media media; + + public Media getMedia() { + return media; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeResourceResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeResourceResponse.java new file mode 100644 index 000000000..12ff8bb4e --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeResourceResponse.java @@ -0,0 +1,41 @@ +package com.yoti.api.client.docs.session.retrieve; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ShareCodeResourceResponse extends ResourceResponse { + + @JsonProperty("lookup_profile") + private LookupProfileResponse lookupProfile; + + @JsonProperty("returned_profile") + private ReturnedProfileResponse returnedProfile; + + @JsonProperty("id_photo") + private IdPhotoResponse idPhoto; + + @JsonProperty("file") + private FileResponse file; + + public LookupProfileResponse getLookupProfile() { + return lookupProfile; + } + + public ReturnedProfileResponse getReturnedProfile() { + return returnedProfile; + } + + public IdPhotoResponse getIdPhoto() { + return idPhoto; + } + + public FileResponse getFile() { + return file; + } + + public List getVerifyShareCodeTasks() { + return filterTasksByType(ShareCodeTaskResponse.class); + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeTaskResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeTaskResponse.java new file mode 100644 index 000000000..575089725 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ShareCodeTaskResponse.java @@ -0,0 +1,4 @@ +package com.yoti.api.client.docs.session.retrieve; + +public class ShareCodeTaskResponse extends TaskResponse { +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/TaskResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/TaskResponse.java index 1078753b8..f5e4ec59b 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/TaskResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/TaskResponse.java @@ -13,6 +13,7 @@ @JsonSubTypes({ @JsonSubTypes.Type(value = IdDocTextExtractionTaskResponse.class, name = DocScanConstants.ID_DOCUMENT_TEXT_DATA_EXTRACTION), @JsonSubTypes.Type(value = SupplementaryDocumentTextExtractionTaskResponse.class, name = DocScanConstants.SUPPLEMENTARY_DOCUMENT_TEXT_DATA_EXTRACTION), + @JsonSubTypes.Type(value = ShareCodeTaskResponse.class, name = DocScanConstants.VERIFY_SHARE_CODE_TASK) }) public class TaskResponse { diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java index cf303428e..8801ce25a 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java @@ -2,6 +2,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInRelativeOrder; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; @@ -39,6 +40,11 @@ public class SessionSpecTest { private static final String SOME_SDK_CONFIG_LOCALE = "en"; private static final String SOME_SDK_CONFIG_PRESET_ISSUING_COUNTRY = "USA"; + private static final String SOME_ISSUER = "UK_GOV"; + private static final String SOME_SCHEME = "RTW"; + private static final String SOME_OTHER_ISSUER = "someOtherIssuer"; + private static final String SOME_OTHER_SCHEME = "someOtherScheme"; + private static final String SOME_SDK_CONFIG_SUCCESS_URL = "https://yourdomain.com/some/success/endpoint"; private static final String SOME_SDK_CONFIG_ERROR_URL = "https://yourdomain.com/some/error/endpoint"; @@ -251,4 +257,37 @@ public void shouldBuildWithImportToken() { assertThat(sessionSpec.getImportToken(), is(importTokenMock)); } + @Test + public void shouldBuildWithSingleRequiredShareCode() { + RequiredShareCodePayload requiredShareCodePayload = RequiredShareCodePayload.builder() + .withIssuer(SOME_ISSUER) + .withScheme(SOME_SCHEME) + .build(); + + SessionSpec sessionSpec = SessionSpec.builder() + .withRequiredShareCode(requiredShareCodePayload) + .build(); + + assertThat(sessionSpec.getRequiredShareCodes(), containsInRelativeOrder(requiredShareCodePayload)); + } + + @Test + public void shouldBuildWithMultipleRequiredShareCodes() { + RequiredShareCodePayload requiredShareCodePayload1 = RequiredShareCodePayload.builder() + .withIssuer(SOME_ISSUER) + .withScheme(SOME_SCHEME) + .build(); + RequiredShareCodePayload requiredShareCodePayload2 = RequiredShareCodePayload.builder() + .withIssuer(SOME_OTHER_ISSUER) + .withScheme(SOME_OTHER_SCHEME) + .build(); + + SessionSpec sessionSpec = SessionSpec.builder() + .withRequiredShareCode(requiredShareCodePayload1) + .withRequiredShareCode(requiredShareCodePayload2) + .build(); + + assertThat(sessionSpec.getRequiredShareCodes(), containsInRelativeOrder(requiredShareCodePayload1, requiredShareCodePayload2)); + } + } From 47b32b78288a606b74f4be291e7cd48e21eb2f30 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 6 Jan 2026 10:48:56 +0000 Subject: [PATCH 22/28] SDK-2779: Expose capture_type property on StaticLivenessResourceResponse --- .../session/retrieve/StaticLivenessResourceResponse.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/StaticLivenessResourceResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/StaticLivenessResourceResponse.java index b6e2bf6c8..50d8f7782 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/StaticLivenessResourceResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/StaticLivenessResourceResponse.java @@ -7,8 +7,15 @@ public class StaticLivenessResourceResponse extends LivenessResourceResponse { @JsonProperty("image") private ImageResponse image; + @JsonProperty("capture_type") + private String captureType; + public ImageResponse getImage() { return image; } + public String getCaptureType() { + return captureType; + } + } From c973f55c139fa03c5fc67462fc348cc3b2fe5f32 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 6 Jan 2026 10:46:59 +0000 Subject: [PATCH 23/28] SDK-2741: Expose process property on BreakdownResponse --- .../client/docs/session/retrieve/BreakdownResponse.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/BreakdownResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/BreakdownResponse.java index 5095a28c0..f3c85adeb 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/BreakdownResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/BreakdownResponse.java @@ -15,6 +15,9 @@ public class BreakdownResponse { @JsonProperty("details") private List details; + @JsonProperty("process") + private String process; + public String getSubCheck() { return subCheck; } @@ -27,4 +30,8 @@ public List getDetails() { return details; } + public String getProcess() { + return process; + } + } From 44d814b4cdab5efac11b94b664313fe7b9a0bd48 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 6 Jan 2026 14:22:46 +0000 Subject: [PATCH 24/28] NA: Use Maven cache when running junit tests on Github Actions --- .github/workflows/junit.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/junit.yml b/.github/workflows/junit.yml index 0f952df5b..7ae63d690 100644 --- a/.github/workflows/junit.yml +++ b/.github/workflows/junit.yml @@ -26,4 +26,10 @@ jobs: distribution: 'zulu' java-version: ${{ matrix.jdk-version }} architecture: x64 + - uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- - run: mvn test -B -pl yoti-sdk-api -Ddependency-check.skip=true From caac3177d3e23b0b0e6bd73d5e7663165a84d9ac Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 6 Jan 2026 14:11:04 +0000 Subject: [PATCH 25/28] SDK-2782: Correct constructor visibility for classes that have builders --- .../src/main/java/com/yoti/api/client/aml/AmlAddress.java | 2 +- .../src/main/java/com/yoti/api/client/aml/AmlProfile.java | 2 +- .../api/client/docs/session/create/ImportTokenPayload.java | 2 +- .../api/client/docs/session/create/NotificationConfig.java | 2 +- .../com/yoti/api/client/docs/session/create/SdkConfig.java | 2 +- .../com/yoti/api/client/docs/session/create/SessionSpec.java | 2 +- .../yoti/api/client/docs/session/create/SubjectPayload.java | 2 +- .../RequestedCustomAccountWatchlistAdvancedCaConfig.java | 2 +- .../create/check/RequestedDocumentAuthenticityCheck.java | 2 +- .../create/check/RequestedDocumentSchemeValidityCheck.java | 2 +- .../docs/session/create/check/RequestedFaceMatchCheck.java | 2 +- .../session/create/check/RequestedIbvVisualReviewCheck.java | 2 +- .../create/check/RequestedIdDocumentComparisonCheck.java | 2 +- .../docs/session/create/check/RequestedLivenessCheck.java | 2 +- .../create/check/RequestedProfileDocumentMatchCheck.java | 2 +- .../create/check/RequestedThirdPartyIdentityCheck.java | 2 +- .../create/check/RequestedWatchlistAdvancedCaCheck.java | 2 +- .../create/check/RequestedWatchlistScreeningCheck.java | 2 +- .../create/check/RequestedWatchlistScreeningConfig.java | 2 +- .../check/RequestedYotiAccountWatchlistAdvancedCaConfig.java | 2 +- .../check/advanced/RequestedFuzzyMatchingStrategy.java | 2 +- .../create/check/advanced/RequestedSearchProfileSources.java | 2 +- .../create/check/advanced/RequestedTypeListSources.java | 2 +- .../session/create/filters/DocumentRestrictionsFilter.java | 2 +- .../session/create/filters/OrthogonalRestrictionsFilter.java | 2 +- .../docs/session/create/filters/RequiredIdDocument.java | 2 +- .../create/filters/RequiredSupplementaryDocument.java | 2 +- .../simple/IdentityProfileRequirementsPayload.java | 2 +- .../identityprofile/simple/IdentityProfileSchemePayload.java | 2 +- .../session/create/objective/ProofOfAddressObjective.java | 2 +- .../create/task/RequestedIdDocTextExtractionTask.java | 2 +- .../task/RequestedSupplementaryDocTextExtractionTask.java | 2 +- .../com/yoti/api/client/spi/remote/call/aml/AmlTest.java | 5 ++++- .../yoti/api/client/sandbox/docs/request/ResponseConfig.java | 2 +- .../api/client/sandbox/docs/request/SandboxCheckReports.java | 2 +- .../client/sandbox/docs/request/SandboxDocumentFilter.java | 2 +- .../api/client/sandbox/docs/request/SandboxTaskResults.java | 2 +- .../docs/request/check/SandboxDocumentAuthenticityCheck.java | 2 +- .../docs/request/check/SandboxDocumentFaceMatchCheck.java | 2 +- .../docs/request/check/SandboxDocumentTextDataCheck.java | 2 +- .../docs/request/check/SandboxFaceComparisonCheck.java | 2 +- .../docs/request/check/SandboxIdDocumentComparisonCheck.java | 2 +- .../check/SandboxSupplementaryDocumentTextDataCheck.java | 2 +- .../request/check/SandboxSynecticsIdentityFraudCheck.java | 2 +- .../docs/request/check/SandboxThirdPartyIdentityCheck.java | 2 +- .../check/SandboxThirdPartyIdentityFraudOneCheck.java | 2 +- .../docs/request/check/SandboxWatchlistAdvancedCaCheck.java | 2 +- .../docs/request/check/SandboxWatchlistScreeningCheck.java | 2 +- .../sandbox/docs/request/check/report/SandboxBreakdown.java | 2 +- .../docs/request/check/report/SandboxRecommendation.java | 2 +- .../request/task/SandboxDocumentTextDataExtractionTask.java | 2 +- .../task/SandboxSupplementaryDocTextDataExtractionTask.java | 2 +- .../docs/request/task/SandboxTextExtractionTaskReason.java | 2 +- .../task/SandboxTextExtractionTaskRecommendation.java | 2 +- 54 files changed, 57 insertions(+), 54 deletions(-) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlAddress.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlAddress.java index 712f19e86..1e1ed6d00 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlAddress.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlAddress.java @@ -10,7 +10,7 @@ public class AmlAddress { @JsonProperty("country") private final String country; - public AmlAddress(String postCode, String country) { + private AmlAddress(String postCode, String country) { this.postCode = postCode; this.country = country; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlProfile.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlProfile.java index 84342af2f..9cb4a0aab 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlProfile.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/aml/AmlProfile.java @@ -16,7 +16,7 @@ public class AmlProfile { @JsonProperty("address") private final AmlAddress amlAddress; - AmlProfile(String givenNames, String familyName, String ssn, AmlAddress amlAddress) { + private AmlProfile(String givenNames, String familyName, String ssn, AmlAddress amlAddress) { this.givenNames = givenNames; this.familyName = familyName; this.ssn = ssn; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/ImportTokenPayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/ImportTokenPayload.java index 8bc94b341..c34058b6e 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/ImportTokenPayload.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/ImportTokenPayload.java @@ -7,7 +7,7 @@ public class ImportTokenPayload { @JsonProperty("ttl") private Integer ttl; - ImportTokenPayload(Integer ttl) { + private ImportTokenPayload(Integer ttl) { this.ttl = ttl; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/NotificationConfig.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/NotificationConfig.java index 51871ea46..2a5161fb4 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/NotificationConfig.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/NotificationConfig.java @@ -26,7 +26,7 @@ public class NotificationConfig { @JsonProperty("topics") private final List topics; - NotificationConfig(String authToken, String authType, String endpoint, List topics) { + private NotificationConfig(String authToken, String authType, String endpoint, List topics) { this.authToken = authToken; this.authType = authType; this.endpoint = endpoint; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java index 549b429d1..4cd26deca 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SdkConfig.java @@ -60,7 +60,7 @@ public class SdkConfig { @JsonProperty("suppressed_screens") private final List suppressedScreens; - SdkConfig(String allowedCaptureMethods, + private SdkConfig(String allowedCaptureMethods, String primaryColour, String primaryColourDarkMode, String secondaryColour, diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java index fc1a73151..a1c53a552 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java @@ -72,7 +72,7 @@ public class SessionSpec { @JsonProperty("required_share_codes") private final List requiredShareCodes; - SessionSpec(Integer clientSessionTokenTtl, + private SessionSpec(Integer clientSessionTokenTtl, Integer resourcesTtl, ImportTokenPayload importToken, String userTrackingId, diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SubjectPayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SubjectPayload.java index 513a40595..64e6a6c51 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SubjectPayload.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SubjectPayload.java @@ -7,7 +7,7 @@ public class SubjectPayload { @JsonProperty("subject_id") private final String subjectId; - SubjectPayload(String subjectId) { + private SubjectPayload(String subjectId) { this.subjectId = subjectId; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedCustomAccountWatchlistAdvancedCaConfig.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedCustomAccountWatchlistAdvancedCaConfig.java index 857bbdd4a..8d630bd8b 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedCustomAccountWatchlistAdvancedCaConfig.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedCustomAccountWatchlistAdvancedCaConfig.java @@ -21,7 +21,7 @@ public class RequestedCustomAccountWatchlistAdvancedCaConfig extends RequestedWa @JsonProperty("client_ref") private final String clientRef; - RequestedCustomAccountWatchlistAdvancedCaConfig(Boolean removeDeceased, + private RequestedCustomAccountWatchlistAdvancedCaConfig(Boolean removeDeceased, Boolean shareUrl, RequestedCaSources sources, RequestedCaMatchingStrategy matchingStrategy, diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedDocumentAuthenticityCheck.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedDocumentAuthenticityCheck.java index 8f03996c5..f9f2f33f0 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedDocumentAuthenticityCheck.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedDocumentAuthenticityCheck.java @@ -10,7 +10,7 @@ public class RequestedDocumentAuthenticityCheck extends RequestedCheck categories; - RequestedWatchlistScreeningConfig(List categories) { + private RequestedWatchlistScreeningConfig(List categories) { this.categories = categories; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedYotiAccountWatchlistAdvancedCaConfig.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedYotiAccountWatchlistAdvancedCaConfig.java index 3b7aaa60b..8a46a17aa 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedYotiAccountWatchlistAdvancedCaConfig.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/RequestedYotiAccountWatchlistAdvancedCaConfig.java @@ -5,7 +5,7 @@ public class RequestedYotiAccountWatchlistAdvancedCaConfig extends RequestedWatchlistAdvancedCaConfig { - RequestedYotiAccountWatchlistAdvancedCaConfig(Boolean removeDeceased, + private RequestedYotiAccountWatchlistAdvancedCaConfig(Boolean removeDeceased, Boolean shareUrl, RequestedCaSources sources, RequestedCaMatchingStrategy matchingStrategy) { diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedFuzzyMatchingStrategy.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedFuzzyMatchingStrategy.java index 4ec1a4e30..9976ebbb5 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedFuzzyMatchingStrategy.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedFuzzyMatchingStrategy.java @@ -7,7 +7,7 @@ public class RequestedFuzzyMatchingStrategy extends RequestedCaMatchingStrategy @JsonProperty("fuzziness") private final Double fuzziness; - RequestedFuzzyMatchingStrategy(Double fuzziness) { + private RequestedFuzzyMatchingStrategy(Double fuzziness) { this.fuzziness = fuzziness; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedSearchProfileSources.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedSearchProfileSources.java index c9ca00c75..5e2a2e20f 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedSearchProfileSources.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedSearchProfileSources.java @@ -7,7 +7,7 @@ public class RequestedSearchProfileSources extends RequestedCaSources { @JsonProperty("search_profile") private final String searchProfile; - RequestedSearchProfileSources(String searchProfile) { + private RequestedSearchProfileSources(String searchProfile) { this.searchProfile = searchProfile; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedTypeListSources.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedTypeListSources.java index be6397225..ce40c4d9f 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedTypeListSources.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/check/advanced/RequestedTypeListSources.java @@ -9,7 +9,7 @@ public class RequestedTypeListSources extends RequestedCaSources { @JsonProperty("types") private final List types; - RequestedTypeListSources(List types) { + private RequestedTypeListSources(List types) { this.types = types; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java index fc97d5c61..30fcc216f 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java @@ -17,7 +17,7 @@ public class DocumentRestrictionsFilter extends DocumentFilter { @JsonProperty("documents") private final List documents; - DocumentRestrictionsFilter(String inclusion, List documents, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments) { + private DocumentRestrictionsFilter(String inclusion, List documents, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments) { super(DocScanConstants.DOCUMENT_RESTRICTIONS, allowNonLatinDocuments, allowExpiredDocuments); this.inclusion = inclusion; this.documents = documents; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java index 728fc63e0..bba774e5c 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java @@ -14,7 +14,7 @@ public class OrthogonalRestrictionsFilter extends DocumentFilter { @JsonProperty("type_restriction") private final TypeRestriction typeRestriction; - OrthogonalRestrictionsFilter(CountryRestriction countryRestriction, TypeRestriction typeRestriction, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments) { + private OrthogonalRestrictionsFilter(CountryRestriction countryRestriction, TypeRestriction typeRestriction, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments) { super(DocScanConstants.ORTHOGONAL_RESTRICTIONS, allowNonLatinDocuments, allowExpiredDocuments); this.countryRestriction = countryRestriction; this.typeRestriction = typeRestriction; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredIdDocument.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredIdDocument.java index f316149e8..db7ffa399 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredIdDocument.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredIdDocument.java @@ -12,7 +12,7 @@ public class RequiredIdDocument extends RequiredDocument { @JsonProperty("filter") private final DocumentFilter filter; - RequiredIdDocument(DocumentFilter filter) { + private RequiredIdDocument(DocumentFilter filter) { this.filter = filter; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredSupplementaryDocument.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredSupplementaryDocument.java index fe13ced15..94ad4f66b 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredSupplementaryDocument.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/RequiredSupplementaryDocument.java @@ -20,7 +20,7 @@ public class RequiredSupplementaryDocument extends RequiredDocument { @JsonProperty("country_codes") private final List countryCodes; - RequiredSupplementaryDocument(Objective objective, List documentTypes, List countryCodes) { + private RequiredSupplementaryDocument(Objective objective, List documentTypes, List countryCodes) { this.objective = objective; this.documentTypes = documentTypes; this.countryCodes = countryCodes; diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java index e75f454ca..14d413230 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileRequirementsPayload.java @@ -12,7 +12,7 @@ public class IdentityProfileRequirementsPayload { @JsonProperty("scheme") private final IdentityProfileSchemePayload scheme; - IdentityProfileRequirementsPayload(String trustFramework, IdentityProfileSchemePayload scheme) { + private IdentityProfileRequirementsPayload(String trustFramework, IdentityProfileSchemePayload scheme) { this.trustFramework = trustFramework; this.scheme = scheme; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java index 228173b11..b91ee5441 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/identityprofile/simple/IdentityProfileSchemePayload.java @@ -12,7 +12,7 @@ public class IdentityProfileSchemePayload { @JsonProperty("objective") private final String objective; - IdentityProfileSchemePayload(String type, String objective) { + private IdentityProfileSchemePayload(String type, String objective) { this.type = type; this.objective = objective; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/objective/ProofOfAddressObjective.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/objective/ProofOfAddressObjective.java index 3bb6db30a..9e93df047 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/objective/ProofOfAddressObjective.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/objective/ProofOfAddressObjective.java @@ -4,7 +4,7 @@ public class ProofOfAddressObjective extends Objective { - ProofOfAddressObjective() { + private ProofOfAddressObjective() { super(DocScanConstants.PROOF_OF_ADDRESS); } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/task/RequestedIdDocTextExtractionTask.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/task/RequestedIdDocTextExtractionTask.java index 51bbbed09..46339848c 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/task/RequestedIdDocTextExtractionTask.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/task/RequestedIdDocTextExtractionTask.java @@ -9,7 +9,7 @@ public class RequestedIdDocTextExtractionTask extends RequestedTask documentTextDataChecks, + private SandboxCheckReports(List documentTextDataChecks, List documentAuthenticityChecks, List livenessChecks, List documentFaceMatchChecks, diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxDocumentFilter.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxDocumentFilter.java index 215c148c7..9d9fb8069 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxDocumentFilter.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxDocumentFilter.java @@ -15,7 +15,7 @@ public class SandboxDocumentFilter { @JsonProperty("country_codes") private final List countryCodes; - SandboxDocumentFilter(List documentTypes, List countryCodes) { + private SandboxDocumentFilter(List documentTypes, List countryCodes) { this.documentTypes = documentTypes; this.countryCodes = countryCodes; } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxTaskResults.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxTaskResults.java index 9b07bec39..479405e10 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxTaskResults.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxTaskResults.java @@ -19,7 +19,7 @@ public class SandboxTaskResults { @JsonProperty(DocScanConstants.SUPPLEMENTARY_DOCUMENT_TEXT_DATA_EXTRACTION) private final List supplementaryTextDataExtractionTasks; - SandboxTaskResults(List documentTextDataExtractionTasks, + private SandboxTaskResults(List documentTextDataExtractionTasks, List supplementaryTextDataExtractionTasks) { this.documentTextDataExtractionTasks = documentTextDataExtractionTasks; this.supplementaryTextDataExtractionTasks = supplementaryTextDataExtractionTasks; diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java index a3225442f..1d3e019a1 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java @@ -5,7 +5,7 @@ public class SandboxDocumentAuthenticityCheck extends SandboxDocumentCheck { - SandboxDocumentAuthenticityCheck(SandboxCheckResult result, SandboxDocumentFilter documentFilter) { + private SandboxDocumentAuthenticityCheck(SandboxCheckResult result, SandboxDocumentFilter documentFilter) { super(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java index 80bc3a66f..848cf137c 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java @@ -5,7 +5,7 @@ public class SandboxDocumentFaceMatchCheck extends SandboxDocumentCheck { - SandboxDocumentFaceMatchCheck(SandboxCheckResult result, SandboxDocumentFilter documentFilter) { + private SandboxDocumentFaceMatchCheck(SandboxCheckResult result, SandboxDocumentFilter documentFilter) { super(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java index ae5dc902a..132ba01a3 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java @@ -11,7 +11,7 @@ @JsonInclude(JsonInclude.Include.NON_EMPTY) public class SandboxDocumentTextDataCheck extends SandboxDocumentCheck { - SandboxDocumentTextDataCheck(SandboxDocumentTextDataCheckResult result, SandboxDocumentFilter documentFilter) { + private SandboxDocumentTextDataCheck(SandboxDocumentTextDataCheckResult result, SandboxDocumentFilter documentFilter) { super(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxFaceComparisonCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxFaceComparisonCheck.java index e4dc1cdb5..719064908 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxFaceComparisonCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxFaceComparisonCheck.java @@ -4,7 +4,7 @@ public class SandboxFaceComparisonCheck extends SandboxCheck { - SandboxFaceComparisonCheck(SandboxCheckResult result) { + private SandboxFaceComparisonCheck(SandboxCheckResult result) { super(result); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java index 4a05675b1..1d16c7d90 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java @@ -10,7 +10,7 @@ public class SandboxIdDocumentComparisonCheck extends SandboxCheck { @JsonProperty("secondary_document_filter") private final SandboxDocumentFilter secondaryDocumentFilter; - SandboxIdDocumentComparisonCheck(SandboxCheckResult result, SandboxDocumentFilter secondaryDocumentFilter) { + private SandboxIdDocumentComparisonCheck(SandboxCheckResult result, SandboxDocumentFilter secondaryDocumentFilter) { super(result); this.secondaryDocumentFilter = secondaryDocumentFilter; } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java index c03053847..7e2fc98cf 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java @@ -8,7 +8,7 @@ public class SandboxSupplementaryDocumentTextDataCheck extends SandboxDocumentCheck { - SandboxSupplementaryDocumentTextDataCheck(SandboxSupplementaryDocumentTextDataCheckResult result, SandboxDocumentFilter documentFilter) { + private SandboxSupplementaryDocumentTextDataCheck(SandboxSupplementaryDocumentTextDataCheckResult result, SandboxDocumentFilter documentFilter) { super(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSynecticsIdentityFraudCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSynecticsIdentityFraudCheck.java index db3dc0cd7..eecf17702 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSynecticsIdentityFraudCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSynecticsIdentityFraudCheck.java @@ -4,7 +4,7 @@ public class SandboxSynecticsIdentityFraudCheck extends SandboxCheck { - SandboxSynecticsIdentityFraudCheck(SandboxCheckResult result) { + private SandboxSynecticsIdentityFraudCheck(SandboxCheckResult result) { super(result); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java index 7df9c8846..07baa5d81 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java @@ -4,7 +4,7 @@ public class SandboxThirdPartyIdentityCheck extends SandboxCheck { - SandboxThirdPartyIdentityCheck(SandboxCheckResult result) { + private SandboxThirdPartyIdentityCheck(SandboxCheckResult result) { super(result); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityFraudOneCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityFraudOneCheck.java index c2499643f..4dddc05f9 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityFraudOneCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityFraudOneCheck.java @@ -4,7 +4,7 @@ public class SandboxThirdPartyIdentityFraudOneCheck extends SandboxCheck { - SandboxThirdPartyIdentityFraudOneCheck(SandboxCheckResult result) { + private SandboxThirdPartyIdentityFraudOneCheck(SandboxCheckResult result) { super(result); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistAdvancedCaCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistAdvancedCaCheck.java index 477501c96..5b76cf82a 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistAdvancedCaCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistAdvancedCaCheck.java @@ -11,7 +11,7 @@ public class SandboxWatchlistAdvancedCaCheck extends SandboxCheck { @JsonProperty("sources_filter") private final SandboxCaSourcesFilter sourcesFilter; - SandboxWatchlistAdvancedCaCheck(SandboxCheckResult result, SandboxCaSourcesFilter sourcesFilter) { + private SandboxWatchlistAdvancedCaCheck(SandboxCheckResult result, SandboxCaSourcesFilter sourcesFilter) { super(result); this.sourcesFilter = sourcesFilter; } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistScreeningCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistScreeningCheck.java index 5d17d7be3..1b3792824 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistScreeningCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistScreeningCheck.java @@ -4,7 +4,7 @@ public class SandboxWatchlistScreeningCheck extends SandboxCheck { - SandboxWatchlistScreeningCheck(SandboxCheckResult result) { + private SandboxWatchlistScreeningCheck(SandboxCheckResult result) { super(result); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxBreakdown.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxBreakdown.java index 6a305134b..068d0bd79 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxBreakdown.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxBreakdown.java @@ -18,7 +18,7 @@ public class SandboxBreakdown { @JsonProperty("details") private final List details; - SandboxBreakdown(String subCheck, String result, List details) { + private SandboxBreakdown(String subCheck, String result, List details) { this.subCheck = subCheck; this.result = result; this.details = details; diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxRecommendation.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxRecommendation.java index 7b4a3936c..1f03469ca 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxRecommendation.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/report/SandboxRecommendation.java @@ -15,7 +15,7 @@ public class SandboxRecommendation { @JsonProperty("recovery_suggestion") private final String recoverySuggestion; - SandboxRecommendation(String value, String reason, String recoverySuggestion) { + private SandboxRecommendation(String value, String reason, String recoverySuggestion) { this.value = value; this.reason = reason; this.recoverySuggestion = recoverySuggestion; diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java index ba58ae883..86c1eb844 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java @@ -26,7 +26,7 @@ public class SandboxDocumentTextDataExtractionTask { @JsonProperty("result_template") private final String resultTemplate; - SandboxDocumentTextDataExtractionTask(SandboxDocumentTextDataExtractionTaskResult result, + private SandboxDocumentTextDataExtractionTask(SandboxDocumentTextDataExtractionTaskResult result, SandboxDocumentFilter documentFilter, Integer responseDelay, String resultTemplate) { diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java index ff0f7a866..2d2260f94 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java @@ -25,7 +25,7 @@ public class SandboxSupplementaryDocTextDataExtractionTask { @JsonProperty("result_template") private final String resultTemplate; - SandboxSupplementaryDocTextDataExtractionTask(SandboxSupplementaryDocTextDataExtractionTaskResult result, + private SandboxSupplementaryDocTextDataExtractionTask(SandboxSupplementaryDocTextDataExtractionTaskResult result, SandboxDocumentFilter documentFilter, Integer responseDelay, String resultTemplate) { diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskReason.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskReason.java index 505b70968..0d98c78d2 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskReason.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskReason.java @@ -14,7 +14,7 @@ public class SandboxTextExtractionTaskReason { @JsonProperty("detail") private final String detail; - SandboxTextExtractionTaskReason(String value, String detail) { + private SandboxTextExtractionTaskReason(String value, String detail) { this.value = value; this.detail = detail; } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskRecommendation.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskRecommendation.java index c78a89e43..c9019498a 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskRecommendation.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxTextExtractionTaskRecommendation.java @@ -14,7 +14,7 @@ public class SandboxTextExtractionTaskRecommendation { @JsonProperty("reason") private final SandboxTextExtractionTaskReason reason; - SandboxTextExtractionTaskRecommendation(String value, SandboxTextExtractionTaskReason reason) { + private SandboxTextExtractionTaskRecommendation(String value, SandboxTextExtractionTaskReason reason) { this.value = value; this.reason = reason; } From 65375e6ed1d91fd5732b26088cd19d50e3ebdf32 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Mon, 16 Feb 2026 10:45:40 +0000 Subject: [PATCH 26/28] SDK-2756: Revert ability to request share codes as part of a regular IDV session --- .../create/RequiredShareCodePayload.java | 68 ------------------- .../docs/session/create/SessionSpec.java | 32 +-------- .../docs/session/create/SessionSpecTest.java | 38 ----------- 3 files changed, 2 insertions(+), 136 deletions(-) delete mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java deleted file mode 100644 index 40d1eeeed..000000000 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/RequiredShareCodePayload.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.yoti.api.client.docs.session.create; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class RequiredShareCodePayload { - - @JsonProperty("issuer") - private final String issuer; - - @JsonProperty("scheme") - private final String scheme; - - private RequiredShareCodePayload(String issuer, String scheme) { - this.issuer = issuer; - this.scheme = scheme; - } - - public String getIssuer() { - return issuer; - } - - public String getScheme() { - return scheme; - } - - public static RequiredShareCodePayload.Builder builder() { - return new RequiredShareCodePayload.Builder(); - } - - public static final class Builder { - - private String issuer; - private String scheme; - - /** - * Sets the issuer of the required Share Code - * - * @param issuer the issuer - * @return the builder - */ - public Builder withIssuer(String issuer) { - this.issuer = issuer; - return this; - } - - /** - * Sets the scheme of the required Share Code - * - * @param scheme the scheme - * @return - */ - public Builder withScheme(String scheme) { - this.scheme = scheme; - return this; - } - - /** - * Builds an {@link RequiredShareCodePayload} using the supplied properties in the builder. - * - * @return the built {@link RequiredShareCodePayload} - */ - public RequiredShareCodePayload build() { - return new RequiredShareCodePayload(issuer, scheme); - } - - } - -} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java index a1c53a552..960cbd920 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/SessionSpec.java @@ -69,9 +69,6 @@ public class SessionSpec { @JsonProperty("create_identity_profile_preview") private final Boolean createIdentityProfilePreview; - @JsonProperty("required_share_codes") - private final List requiredShareCodes; - private SessionSpec(Integer clientSessionTokenTtl, Integer resourcesTtl, ImportTokenPayload importToken, @@ -88,8 +85,7 @@ private SessionSpec(Integer clientSessionTokenTtl, SubjectPayload subject, ResourceCreationContainer resources, Boolean createIdentityProfilePreview, - AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements, - List requiredShareCodes) { + AdvancedIdentityProfileRequirementsPayload advancedIdentityProfileRequirements) { this.clientSessionTokenTtl = clientSessionTokenTtl; this.resourcesTtl = resourcesTtl; this.importToken = importToken; @@ -107,7 +103,6 @@ private SessionSpec(Integer clientSessionTokenTtl, this.resources = resources; this.createIdentityProfilePreview = createIdentityProfilePreview; this.advancedIdentityProfileRequirements = advancedIdentityProfileRequirements; - this.requiredShareCodes = requiredShareCodes; } public static Builder builder() { @@ -268,15 +263,6 @@ public AdvancedIdentityProfileRequirementsPayload getAdvancedIdentityProfileRequ return advancedIdentityProfileRequirements; } - /** - * The list of Share Codes being requested. - * - * @return the requested Share Codes - */ - public List getRequiredShareCodes() { - return requiredShareCodes; - } - public static class Builder { private final List> requestedChecks; @@ -296,13 +282,11 @@ public static class Builder { private SubjectPayload subject; private ResourceCreationContainer resources; private Boolean createIdentityProfilePreview; - private final List requiredShareCodes; private Builder() { requestedChecks = new ArrayList<>(); requestedTasks = new ArrayList<>(); requiredDocuments = new ArrayList<>(); - requiredShareCodes = new ArrayList<>(); } /** @@ -493,17 +477,6 @@ public Builder withAdvancedIdentityProfileRequirements(AdvancedIdentityProfileRe return this; } - /** - * Adds a required Share Code to the list - * - * @param requiredShareCode the required share code - * @return the builder - */ - public Builder withRequiredShareCode(RequiredShareCodePayload requiredShareCode) { - this.requiredShareCodes.add(requiredShareCode); - return this; - } - /** * Builds the {@link SessionSpec} based on the values supplied to the builder * @@ -527,8 +500,7 @@ public SessionSpec build() { subject, resources, createIdentityProfilePreview, - advancedIdentityProfileRequirementsPayload, - requiredShareCodes); + advancedIdentityProfileRequirementsPayload); } } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java index 8801ce25a..5a78a9dd5 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/SessionSpecTest.java @@ -40,11 +40,6 @@ public class SessionSpecTest { private static final String SOME_SDK_CONFIG_LOCALE = "en"; private static final String SOME_SDK_CONFIG_PRESET_ISSUING_COUNTRY = "USA"; - private static final String SOME_ISSUER = "UK_GOV"; - private static final String SOME_SCHEME = "RTW"; - private static final String SOME_OTHER_ISSUER = "someOtherIssuer"; - private static final String SOME_OTHER_SCHEME = "someOtherScheme"; - private static final String SOME_SDK_CONFIG_SUCCESS_URL = "https://yourdomain.com/some/success/endpoint"; private static final String SOME_SDK_CONFIG_ERROR_URL = "https://yourdomain.com/some/error/endpoint"; @@ -257,37 +252,4 @@ public void shouldBuildWithImportToken() { assertThat(sessionSpec.getImportToken(), is(importTokenMock)); } - @Test - public void shouldBuildWithSingleRequiredShareCode() { - RequiredShareCodePayload requiredShareCodePayload = RequiredShareCodePayload.builder() - .withIssuer(SOME_ISSUER) - .withScheme(SOME_SCHEME) - .build(); - - SessionSpec sessionSpec = SessionSpec.builder() - .withRequiredShareCode(requiredShareCodePayload) - .build(); - - assertThat(sessionSpec.getRequiredShareCodes(), containsInRelativeOrder(requiredShareCodePayload)); - } - - @Test - public void shouldBuildWithMultipleRequiredShareCodes() { - RequiredShareCodePayload requiredShareCodePayload1 = RequiredShareCodePayload.builder() - .withIssuer(SOME_ISSUER) - .withScheme(SOME_SCHEME) - .build(); - RequiredShareCodePayload requiredShareCodePayload2 = RequiredShareCodePayload.builder() - .withIssuer(SOME_OTHER_ISSUER) - .withScheme(SOME_OTHER_SCHEME) - .build(); - - SessionSpec sessionSpec = SessionSpec.builder() - .withRequiredShareCode(requiredShareCodePayload1) - .withRequiredShareCode(requiredShareCodePayload2) - .build(); - - assertThat(sessionSpec.getRequiredShareCodes(), containsInRelativeOrder(requiredShareCodePayload1, requiredShareCodePayload2)); - } - } From 1e51c55143f4fd1b9ac31c1484fbf57bdc81a68e Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Mon, 16 Feb 2026 10:56:15 +0000 Subject: [PATCH 27/28] SDK-2784: Use MediaResponse class instead of Media interface for ShareCode response classes --- .../api/client/docs/session/retrieve/IdPhotoResponse.java | 8 +++----- .../docs/session/retrieve/LookupProfileResponse.java | 6 ++---- .../docs/session/retrieve/ReturnedProfileResponse.java | 8 +++----- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java index 79c27f8fd..ca0a394e4 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdPhotoResponse.java @@ -1,16 +1,14 @@ package com.yoti.api.client.docs.session.retrieve; -import com.yoti.api.client.Media; - import com.fasterxml.jackson.annotation.JsonProperty; public class IdPhotoResponse { @JsonProperty("media") - private Media media; + private MediaResponse media; - public Media getMedia() { + public MediaResponse getMedia() { return media; } - + } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java index 8b774239f..450904b1d 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/LookupProfileResponse.java @@ -1,15 +1,13 @@ package com.yoti.api.client.docs.session.retrieve; -import com.yoti.api.client.Media; - import com.fasterxml.jackson.annotation.JsonProperty; public class LookupProfileResponse { @JsonProperty("media") - private Media media; + private MediaResponse media; - public Media getMedia() { + public MediaResponse getMedia() { return media; } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java index 486f7e05e..ad2b90356 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/ReturnedProfileResponse.java @@ -1,16 +1,14 @@ package com.yoti.api.client.docs.session.retrieve; -import com.yoti.api.client.Media; - import com.fasterxml.jackson.annotation.JsonProperty; public class ReturnedProfileResponse { @JsonProperty("media") - private Media media; + private MediaResponse media; - public Media getMedia() { + public MediaResponse getMedia() { return media; } - + } From 56957fa589edc061743bb5f62ce07e2ade19bbd1 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Mon, 23 Feb 2026 10:06:06 +0000 Subject: [PATCH 28/28] Release 4.0.0: Bump version for release --- README.md | 4 ++-- examples/doc-scan/pom.xml | 2 +- pom.xml | 2 +- yoti-sdk-api/pom.xml | 2 +- .../com/yoti/api/client/spi/remote/call/YotiConstants.java | 2 +- yoti-sdk-auth/pom.xml | 2 +- yoti-sdk-parent/pom.xml | 2 +- yoti-sdk-sandbox/pom.xml | 2 +- yoti-sdk-spring-boot-auto-config/README.md | 4 ++-- yoti-sdk-spring-boot-auto-config/pom.xml | 2 +- yoti-sdk-spring-boot-example/README.md | 2 +- yoti-sdk-spring-boot-example/pom.xml | 2 +- yoti-sdk-spring-security/README.md | 4 ++-- yoti-sdk-spring-security/pom.xml | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a30beba81..278c4bb0d 100644 --- a/README.md +++ b/README.md @@ -101,13 +101,13 @@ If you are using Maven, you need to add the following dependency: com.yoti yoti-sdk-api - 4.0.0-SNAPSHOT + 4.0.0 ``` If you are using Gradle, here is the dependency to add: -`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '4.0.0-SNAPSHOT'` +`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '4.0.0'` You will find all classes packaged under `com.yoti.api` diff --git a/examples/doc-scan/pom.xml b/examples/doc-scan/pom.xml index 468e0e43a..73adc9d6c 100644 --- a/examples/doc-scan/pom.xml +++ b/examples/doc-scan/pom.xml @@ -53,7 +53,7 @@ com.yoti yoti-sdk-api - 4.0.0-SNAPSHOT + 4.0.0 diff --git a/pom.xml b/pom.xml index 8005c4dd7..83355e89f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk pom - 4.0.0-SNAPSHOT + 4.0.0 Yoti SDK Java SDK for simple integration with the Yoti platform https://github.com/getyoti/yoti-java-sdk diff --git a/yoti-sdk-api/pom.xml b/yoti-sdk-api/pom.xml index 27714d7ab..78eb438d1 100644 --- a/yoti-sdk-api/pom.xml +++ b/yoti-sdk-api/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 4.0.0-SNAPSHOT + 4.0.0 ../yoti-sdk-parent diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java index a87a5ddfc..4ca63609b 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java @@ -30,7 +30,7 @@ private YotiConstants() {} public static final String CONTENT_TYPE_JPEG = "image/jpeg"; public static final String JAVA = "Java"; - public static final String SDK_VERSION = JAVA + "-4.0.0-SNAPSHOT"; + public static final String SDK_VERSION = JAVA + "-4.0.0"; public static final String SIGNATURE_ALGORITHM = "SHA256withRSA"; public static final String ASYMMETRIC_CIPHER = "RSA/NONE/PKCS1Padding"; public static final String SYMMETRIC_CIPHER = "AES/CBC/PKCS7Padding"; diff --git a/yoti-sdk-auth/pom.xml b/yoti-sdk-auth/pom.xml index f50af3922..4ce1c511d 100644 --- a/yoti-sdk-auth/pom.xml +++ b/yoti-sdk-auth/pom.xml @@ -7,7 +7,7 @@ com.yoti yoti-sdk-parent - 4.0.0-SNAPSHOT + 4.0.0 ../yoti-sdk-parent diff --git a/yoti-sdk-parent/pom.xml b/yoti-sdk-parent/pom.xml index 2912695e4..183ed1c9b 100644 --- a/yoti-sdk-parent/pom.xml +++ b/yoti-sdk-parent/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk-parent pom - 4.0.0-SNAPSHOT + 4.0.0 Yoti SDK Parent Pom Parent pom for the Java SDK projects https://github.com/getyoti/yoti-java-sdk diff --git a/yoti-sdk-sandbox/pom.xml b/yoti-sdk-sandbox/pom.xml index 8bf17923e..878164a2d 100644 --- a/yoti-sdk-sandbox/pom.xml +++ b/yoti-sdk-sandbox/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 4.0.0-SNAPSHOT + 4.0.0 ../yoti-sdk-parent diff --git a/yoti-sdk-spring-boot-auto-config/README.md b/yoti-sdk-spring-boot-auto-config/README.md index 2d7f8864f..05b54ef90 100644 --- a/yoti-sdk-spring-boot-auto-config/README.md +++ b/yoti-sdk-spring-boot-auto-config/README.md @@ -18,7 +18,7 @@ If you are using Maven, you need to add the following dependencies: com.yoti yoti-sdk-spring-boot-auto-config - 4.0.0-SNAPSHOT + 4.0.0 ``` @@ -26,7 +26,7 @@ If you are using Maven, you need to add the following dependencies: If you are using Gradle, here is the dependency to add: ``` -compile group: 'com.yoti', name: 'yoti-sdk-spring-boot-auto-config', version: '4.0.0-SNAPSHOT' +compile group: 'com.yoti', name: 'yoti-sdk-spring-boot-auto-config', version: '4.0.0' ``` diff --git a/yoti-sdk-spring-boot-auto-config/pom.xml b/yoti-sdk-spring-boot-auto-config/pom.xml index afa28fb84..548a78a0a 100644 --- a/yoti-sdk-spring-boot-auto-config/pom.xml +++ b/yoti-sdk-spring-boot-auto-config/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 4.0.0-SNAPSHOT + 4.0.0 ../yoti-sdk-parent diff --git a/yoti-sdk-spring-boot-example/README.md b/yoti-sdk-spring-boot-example/README.md index 5d2793937..fc2aeb960 100644 --- a/yoti-sdk-spring-boot-example/README.md +++ b/yoti-sdk-spring-boot-example/README.md @@ -17,7 +17,7 @@ Note that: com.yoti yoti-sdk-api - 4.0.0-SNAPSHOT + 4.0.0 ``` diff --git a/yoti-sdk-spring-boot-example/pom.xml b/yoti-sdk-spring-boot-example/pom.xml index bb86ad435..883ed5b47 100644 --- a/yoti-sdk-spring-boot-example/pom.xml +++ b/yoti-sdk-spring-boot-example/pom.xml @@ -6,7 +6,7 @@ com.yoti yoti-sdk-spring-boot-example Yoti Spring Boot Example - 4.0.0-SNAPSHOT + 4.0.0 org.springframework.boot diff --git a/yoti-sdk-spring-security/README.md b/yoti-sdk-spring-security/README.md index f6fe0ca0a..7b5ccf7ab 100644 --- a/yoti-sdk-spring-security/README.md +++ b/yoti-sdk-spring-security/README.md @@ -25,14 +25,14 @@ If you are using Maven, you need to add the following dependencies: com.yoti yoti-sdk-spring-security - 4.0.0-SNAPSHOT + 4.0.0 ``` If you are using Gradle, here is the dependency to add: ``` -compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '4.0.0-SNAPSHOT' +compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '4.0.0' ``` ### Provide a `YotiClient` instance diff --git a/yoti-sdk-spring-security/pom.xml b/yoti-sdk-spring-security/pom.xml index a902565b9..9eb70f490 100644 --- a/yoti-sdk-spring-security/pom.xml +++ b/yoti-sdk-spring-security/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 4.0.0-SNAPSHOT + 4.0.0 ../yoti-sdk-parent