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/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 e586b6b8c..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; @@ -34,9 +33,10 @@ 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.AuthStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.annotation.JsonInclude; @@ -62,51 +62,49 @@ 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); } - 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); 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()); } /** * 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); - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_POST) @@ -114,7 +112,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) { @@ -129,29 +127,27 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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) { @@ -166,28 +162,26 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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) { @@ -202,30 +196,28 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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; @@ -243,30 +235,28 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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) { @@ -276,27 +266,26 @@ 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); - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_PUT) .withPayload(payload) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (GeneralSecurityException ex) { throw new DocScanException("Error signing the request: " + ex.getMessage(), ex); } catch (ResourceException ex) { @@ -306,23 +295,22 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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) { @@ -335,29 +323,27 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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) { @@ -367,22 +353,21 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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; @@ -397,23 +382,22 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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) { @@ -423,30 +407,28 @@ 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); - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withPayload(payload) .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) { @@ -456,26 +438,25 @@ 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 { - signedRequestBuilderFactory.create() + yotiHttpRequestBuilderFactory.create() .withMultipartBoundary(YOTI_MULTIPART_BOUNDARY) .withMultipartBinaryBody( "binary-content", faceCaptureImagePayload.getImageContents(), ContentType.parse(faceCaptureImagePayload.getImageContentType()), "face-capture-image") - .withKeyPair(keyPair) + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_PUT) @@ -488,20 +469,16 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() .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) { @@ -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 { - signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_POST) @@ -532,23 +508,22 @@ 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 { - SignedRequest signedRequest = signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequest yotiHttpRequest = yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .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) { @@ -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 { - signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + yotiHttpRequestBuilderFactory.create() + .withAuthStrategy(authStrategy) .withBaseUrl(apiUrl) .withEndpoint(path) .withHttpMethod(HTTP_DELETE) @@ -579,7 +553,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))) { @@ -590,5 +564,4 @@ private String findContentType(SignedRequestResponse 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/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..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; @@ -29,52 +30,54 @@ 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; + 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 SignedRequestBuilderFactory()); + new YotiHttpRequestBuilderFactory(), + new ProfileSignedRequestStrategy(keyPair, appId)); } - ProfileService(UnsignedPathFactory profilePathFactory, SignedRequestBuilderFactory signedRequestBuilderFactory) { - this.unsignedPathFactory = profilePathFactory; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; - + 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()); - - SignedRequest signedRequest = createSignedRequest(keyPair, path, authKey); - return fetchReceipt(signedRequest); + YotiHttpRequest yotiHttpRequest = createSignedRequest(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,10 +91,10 @@ private ProfileResponse fetchReceipt(SignedRequest signedRequest) throws IOExcep } } - SignedRequest createSignedRequest(KeyPair keyPair, String path, String authKey) throws ProfileException { + YotiHttpRequest createSignedRequest(String path, String authKey) throws ProfileException { try { - return signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + return yotiHttpRequestBuilderFactory.create() + .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/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/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/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 62% 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..9f1c408c7 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 @@ -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 SignedRequestBuilder { +public class YotiHttpRequestBuilder { - private KeyPair keyPair; + private AuthStrategy authStrategy; private String baseUrl; private String endpoint; private byte[] payload; @@ -35,22 +43,16 @@ public class SignedRequestBuilder { 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; - SignedRequestBuilder(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 SignedRequestBuilder { /** * 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 SignedRequestBuilder 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; } @@ -74,8 +106,14 @@ public SignedRequestBuilder withKeyPair(KeyPair keyPair) { * @param baseUrl the base url * @return the updated builder */ - public SignedRequestBuilder withBaseUrl(String baseUrl) { - this.baseUrl = baseUrl.replaceAll("([/]+)$", ""); + public YotiHttpRequestBuilder withBaseUrl(String baseUrl) { + int index; + for (index = baseUrl.length() - 1; index >= 0; index--) { + if (baseUrl.charAt(index) != '/') { + break; + } + } + this.baseUrl = baseUrl.substring(0, index + 1); return this; } @@ -85,7 +123,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 +134,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 +147,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 +159,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 +170,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 +190,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 +209,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,16 +224,9 @@ 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("?")) { - endpoint = endpoint.concat("&"); - } else { - endpoint = endpoint.concat("?"); - } - - String builtEndpoint = endpoint + createQueryParameterString(queryParameters); + String builtEndpoint = endpoint + createQueryParameterString(); byte[] finalPayload; if (multipartEntityBuilder == null) { @@ -213,10 +244,10 @@ public SignedRequest build() throws GeneralSecurityException, UnsupportedEncodin } } - String digest = createDigest(builtEndpoint, finalPayload); - headers.putAll(headersFactory.create(digest)); + List
authHeaders = authStrategy.createAuthHeaders(httpMethod, builtEndpoint, finalPayload); + headers.putAll(headersFactory.create(authHeaders)); - return new SignedRequest( + return new YotiHttpRequest( new URI(baseUrl + builtEndpoint), httpMethod, finalPayload, @@ -227,30 +258,38 @@ public SignedRequest build() throws GeneralSecurityException, UnsupportedEncodin } 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/SignedRequestBuilderFactory.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiHttpRequestBuilderFactory.java similarity index 52% 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..62116e7a1 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 @@ -1,29 +1,23 @@ 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 SignedRequestBuilderFactory { +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); imageResourceFetcher = ImageResourceFetcher.newInstance(rawResourceFetcher); } - public SignedRequestBuilder create() { - return new SignedRequestBuilder(pathFactory, signedMessageFactory, headersFactory, jsonResourceFetcher, rawResourceFetcher, imageResourceFetcher); + public YotiHttpRequestBuilder create() { + return new YotiHttpRequestBuilder(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..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 @@ -20,8 +20,9 @@ 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.AmlSignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.databind.ObjectMapper; @@ -30,38 +31,40 @@ public class RemoteAmlService { private final UnsignedPathFactory unsignedPathFactory; private final ObjectMapper objectMapper; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + 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 SignedRequestBuilderFactory() + new YotiHttpRequestBuilderFactory(), + new AmlSignedRequestStrategy(keyPair, appId) ); } - RemoteAmlService(UnsignedPathFactory unsignedPathFactory, + private RemoteAmlService(UnsignedPathFactory unsignedPathFactory, ObjectMapper objectMapper, - SignedRequestBuilderFactory signedRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory, + AmlSignedRequestStrategy amlSignedRequestStrategy) { this.unsignedPathFactory = unsignedPathFactory; this.objectMapper = objectMapper; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + 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); - SignedRequest signedRequest = createSignedRequest(keyPair, resourcePath, body); - return signedRequest.execute(AmlResult.class); + YotiHttpRequest yotiHttpRequest = createSignedRequest(resourcePath, body); + return yotiHttpRequest.execute(AmlResult.class); } catch (IOException ioException) { throw new AmlException("Error communicating with AML endpoint", ioException); } catch (ResourceException resourceException) { @@ -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); } } - SignedRequest createSignedRequest(KeyPair keyPair, String resourcePath, byte[] body) throws AmlException { + YotiHttpRequest createSignedRequest(String resourcePath, byte[] body) throws AmlException { try { - return signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + return yotiHttpRequestBuilderFactory.create() + .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 b79178c00..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; @@ -22,9 +21,10 @@ 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.DigitalIdentitySignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.yoti.json.ResourceMapper; import com.yoti.validation.Validation; @@ -39,43 +39,40 @@ 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 DigitalIdentitySignedRequestStrategy authStrategy; private final String apiUrl; - public DigitalIdentityService( + private DigitalIdentityService( UnsignedPathFactory pathFactory, - SignedRequestBuilderFactory requestBuilderFactory, - ReceiptParser receiptParser) { + YotiHttpRequestBuilderFactory requestBuilderFactory, + 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 SignedRequestBuilderFactory(), - ReceiptParser.newInstance() + new YotiHttpRequestBuilderFactory(), + 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 } } - SignedRequest 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); } - SignedRequest createSignedRequest(String sdkId, KeyPair keyPair, String path, String method, byte[] payload) + YotiHttpRequest createSignedRequest(String path, String method, byte[] payload) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { - SignedRequestBuilder request = requestBuilderFactory.create() - .withKeyPair(keyPair) + YotiHttpRequestBuilder request = requestBuilderFactory.create() + .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 fc9b47422..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 @@ -15,9 +15,9 @@ 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.SimpleSignedRequestStrategy; import com.yoti.api.client.spi.remote.call.factory.UnsignedPathFactory; import com.fasterxml.jackson.databind.ObjectMapper; @@ -26,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 SignedRequestBuilderFactory() + new YotiHttpRequestBuilderFactory(), + new SimpleSignedRequestStrategy(keyPair) ); } @@ -38,23 +39,25 @@ public static DynamicSharingService newInstance() { private final UnsignedPathFactory unsignedPathFactory; private final ObjectMapper objectMapper; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; + private final SimpleSignedRequestStrategy simpleSignedRequestStrategy; private final String apiUrl; - DynamicSharingService(UnsignedPathFactory unsignedPathFactory, + private DynamicSharingService(UnsignedPathFactory unsignedPathFactory, ObjectMapper objectMapper, - SignedRequestBuilderFactory signedRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory, + SimpleSignedRequestStrategy simpleSignedRequestStrategy) { this.unsignedPathFactory = unsignedPathFactory; this.objectMapper = objectMapper; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + 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); @@ -63,9 +66,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(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,10 +76,10 @@ public ShareUrlResult createShareUrl(String appId, KeyPair keyPair, DynamicScena } } - SignedRequest createSignedRequest(KeyPair keyPair, String path, byte[] body) throws DynamicShareException { + YotiHttpRequest createSignedRequest(String path, byte[] body) throws DynamicShareException { try { - return signedRequestBuilderFactory.create() - .withKeyPair(keyPair) + return yotiHttpRequestBuilderFactory.create() + .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 a945140fb..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,12 +6,9 @@ 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; -import static org.hamcrest.Matchers.any; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; @@ -29,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; @@ -54,16 +50,16 @@ 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.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; @@ -76,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"; @@ -87,48 +82,36 @@ 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 SignedRequest signedRequestMock; - @Mock(answer = Answers.RETURNS_SELF) SignedRequestBuilder signedRequestBuilderMock; - @Mock SignedRequestResponse signedRequestResponseMock; - @Mock SignedRequestBuilderFactory signedRequestBuilderFactoryMock; + @Mock(answer = Answers.RETURNS_SELF) YotiHttpRequestBuilder yotiHttpRequestBuilderMock; + + @Mock AuthStrategy authStrategyMock; + @Mock YotiHttpRequest yotiHttpRequestMock; + @Mock YotiHttpResponse yotiHttpResponseMock; + @Mock YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactoryMock; @Mock SupportedDocumentsResponse supportedDocumentsResponseMock; @Mock Instructions instructionsMock; @Mock CreateFaceCaptureResourcePayload createFaceCaptureResourcePayloadMock; @Mock UploadFaceCaptureImagePayload uploadFaceCaptureImagePayloadMock; - @BeforeClass - public static void setUpClass() throws Exception { - KEY_PAIR = generateKeyPairFrom(KEY_PAIR_PEM); - } - @Before public void setUp() { - when(signedRequestBuilderFactoryMock.create()).thenReturn(signedRequestBuilderMock); - } - - @Test - public void createSession_shouldThrowExceptionWhenMissingAppId() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.createSession(null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); + when(yotiHttpRequestBuilderFactoryMock.create()).thenReturn(yotiHttpRequestBuilderMock); } @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")); } @@ -137,9 +120,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), gse); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); @@ -149,10 +132,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error posting the request: Failed Request")); @@ -162,10 +145,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createSession(authStrategyMock, sessionSpecMock)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -175,9 +158,9 @@ 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)); + 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")); @@ -188,9 +171,9 @@ 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)); + 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")); @@ -201,52 +184,38 @@ 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(unsignedPathFactoryMock.createNewYotiDocsSessionPath(SOME_APP_ID)).thenReturn(SOME_PATH); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(CreateSessionResult.class)).thenReturn(createSessionResultMock); + 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(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); - } - - @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)); - - assertThat(ex.getMessage(), containsString("SDK ID")); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); + 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 - public void retrieveSession_shouldThrowExceptionWhenMissingKeyPair() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(SOME_APP_ID, null, null)); + public void retrieveSession_shouldThrowExceptionWhenMissingAuthStrategy() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.retrieveSession(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")); } @@ -254,9 +223,9 @@ 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)); + 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")); @@ -265,10 +234,10 @@ 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)); + 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")); @@ -277,10 +246,10 @@ 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)); + 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")); @@ -289,9 +258,9 @@ 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)); + 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")); @@ -300,50 +269,36 @@ 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(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute(GetSessionResult.class)).thenReturn(docScanSessionResponseMock); + 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(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).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")); + 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_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")); } @@ -351,9 +306,9 @@ 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)); + 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")); @@ -362,10 +317,10 @@ 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)); + 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")); @@ -374,10 +329,10 @@ 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)); + 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")); @@ -386,9 +341,9 @@ 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)); + 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,62 +351,48 @@ public void deleteSession_shouldWrapGeneralException() { @Test public void deleteSession_shouldBuildSignedRequest() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - 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); - } - - @Test - public void getMediaContent_shouldThrowExceptionWhenApplicationIdIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(null, null, null, null)); - - assertThat(ex.getMessage(), containsString("SDK ID")); - } + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(unsignedPathFactoryMock.createYotiDocsSessionPath(SOME_SESSION_ID)).thenReturn(SOME_PATH); - @Test - public void getMediaContent_shouldThrowExceptionWhenApplicationIdIsEmpty() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent("", null, null, null)); + docScanService.deleteSession(authStrategyMock, SOME_SESSION_ID); - assertThat(ex.getMessage(), containsString("SDK ID")); + 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_shouldThrowExceptionWhenKeyPairIsNull() { - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(SOME_APP_ID, null, null, null)); + public void getMediaContent_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getMediaContent(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")); } @@ -459,9 +400,9 @@ 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)); + 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")); @@ -470,10 +411,10 @@ 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)); + 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")); @@ -482,10 +423,10 @@ 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)); + 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")); @@ -494,9 +435,9 @@ 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)); + 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")); @@ -504,28 +445,28 @@ 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(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + YotiHttpResponse yotiHttpResponseMock = mock(YotiHttpResponse.class, RETURNS_DEEP_STUBS); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + 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(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_GET); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); + 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(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + 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_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)); @@ -533,25 +474,25 @@ 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(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + when(yotiHttpResponseMock.getResponseCode()).thenReturn(204); + 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())); } @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(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + 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_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)); @@ -564,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")); } @@ -615,9 +542,9 @@ 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)); + 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")); @@ -626,10 +553,10 @@ 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)); + 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")); @@ -638,10 +565,10 @@ 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)); + 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")); @@ -650,9 +577,9 @@ 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)); + 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,15 +587,15 @@ public void deleteMediaContent_shouldWrapURISyntaxException() throws Exception { @Test public void deleteMediaContent_shouldBuildSignedRequest() throws Exception { - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - when(unsignedPathFactoryMock.createMediaContentPath(SOME_APP_ID, SOME_SESSION_ID, SOME_MEDIA_ID)).thenReturn(SOME_PATH); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + 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(signedRequestBuilderMock).withKeyPair(KEY_PAIR); - verify(signedRequestBuilderMock).withEndpoint(SOME_PATH); - verify(signedRequestBuilderMock).withBaseUrl(SOME_API_URL); - verify(signedRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); + verify(yotiHttpRequestBuilderMock).withAuthStrategy(authStrategyMock); + verify(yotiHttpRequestBuilderMock).withEndpoint(SOME_PATH); + verify(yotiHttpRequestBuilderMock).withBaseUrl(SOME_API_URL); + verify(yotiHttpRequestBuilderMock).withHttpMethod(HttpMethod.HTTP_DELETE); } @Test @@ -694,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)); - - 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)); + public void putIbvInstructions_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(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")); } @@ -738,9 +651,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -748,10 +661,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock)); assertThat(ex.getMessage(), containsString("Error executing the PUT: Failed Request")); } @@ -759,10 +672,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.putIbvInstructions(authStrategyMock, SOME_SESSION_ID, instructionsMock)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -770,44 +683,30 @@ 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)); + 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")); } @@ -815,9 +714,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -825,10 +724,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -836,10 +735,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructions(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -847,44 +746,32 @@ 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)); + 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)); + public void getIbvInstructionsPdf_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.getIbvInstructionsPdf(null, 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)); - - 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")); } @@ -892,9 +779,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -902,10 +789,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -913,10 +800,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -924,22 +811,22 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getIbvInstructionsPdf(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Failed to build URI: someUrl")); } @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(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + 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_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)); @@ -947,47 +834,35 @@ 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(unsignedPathFactoryMock.createFetchIbvInstructionsPdfPath(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenReturn(yotiHttpResponseMock); + when(yotiHttpResponseMock.getResponseCode()).thenReturn(204); + 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)); + public void fetchInstructionsContactProfile_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchInstructionsContactProfile(null, 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)); - - 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")); } @@ -995,9 +870,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -1005,10 +880,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -1016,10 +891,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchInstructionsContactProfile(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1027,44 +902,32 @@ 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)); + 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)); - - 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)); + public void fetchSessionConfiguration_shouldThrowExceptionWhenAuthStrategyIsNull() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.fetchSessionConfiguration(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")); } @@ -1072,9 +935,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -1082,10 +945,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); } @@ -1093,10 +956,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.fetchSessionConfiguration(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1104,51 +967,40 @@ 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)); + 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")); } @@ -1156,9 +1008,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(authStrategyMock, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("Error signing the request: some gse")); } @@ -1166,10 +1018,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(authStrategyMock, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("Error executing the POST: Failed Request")); } @@ -1177,10 +1029,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.createFaceCaptureResource(authStrategyMock, SOME_SESSION_ID, createFaceCaptureResourcePayloadMock)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1188,65 +1040,56 @@ 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)); + 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)); - - 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)); + public void uploadFaceCaptureImage_shouldFailForNullAuthStrategy() { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.uploadFaceCaptureImage(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")); } @@ -1255,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(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)); + 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")); @@ -1269,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(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)); + 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")); @@ -1283,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(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)); + 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")); @@ -1298,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(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)); + 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")); } @@ -1347,9 +1178,9 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the POST: some gse")); } @@ -1357,10 +1188,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error executing the POST: Failed Request")); } @@ -1368,10 +1199,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.triggerIbvEmailNotification(authStrategyMock, SOME_SESSION_ID)); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); } @@ -1379,26 +1210,19 @@ 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)); + 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(signedRequestBuilderMock.build()).thenThrow(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")); @@ -1407,10 +1231,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(false)); assertSame(ex.getCause(), resourceException); assertThat(ex.getMessage(), containsString("Error executing the GET: Failed Request")); @@ -1419,10 +1243,10 @@ 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)); + DocScanException ex = assertThrows(DocScanException.class, () -> docScanService.getSupportedDocuments(false)); assertSame(ex.getCause(), ioException); assertThat(ex.getMessage(), containsString("Error building the request: Some io exception")); @@ -1431,9 +1255,9 @@ 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)); + 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")); @@ -1441,51 +1265,41 @@ 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); + 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")); } @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)); + 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")); @@ -1494,10 +1308,10 @@ 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)); + 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")); @@ -1506,10 +1320,10 @@ 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)); + 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")); @@ -1518,9 +1332,9 @@ 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)); + 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")); @@ -1528,52 +1342,42 @@ 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(unsignedPathFactoryMock.createFetchTrackedDevices(SOME_APP_ID, SOME_SESSION_ID)).thenReturn(SOME_PATH); + when(yotiHttpRequestMock.execute(ArgumentMatchers.any(TypeReference.class))).thenReturn(Collections.singletonList(metadataResponseMock)); + 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")); } @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)); + 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")); @@ -1582,10 +1386,10 @@ 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)); + 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")); @@ -1594,10 +1398,10 @@ 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)); + 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")); @@ -1606,9 +1410,9 @@ 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)); + 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/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..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 @@ -5,19 +5,25 @@ 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; 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.*; +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 +46,8 @@ public class ProfileServiceTest { @Mock UnsignedPathFactory unsignedPathFactory; - @Mock SignedRequest signedRequest; + @Mock ProfileSignedRequestStrategy profileSignedRequestStrategyMock; + @Mock YotiHttpRequest yotiHttpRequest; @BeforeClass public static void setUpClass() throws Exception { @@ -50,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(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(GENERATED_PROFILE_PATH, B64_PUBLIC_KEY); + when(yotiHttpRequest.execute(ProfileResponse.class)).thenReturn(PROFILE_RESPONSE); + + Receipt result = testObj.getReceipt(KEY_PAIR, TOKEN); - Receipt result = testObj.getReceipt(KEY_PAIR, APP_ID, TOKEN); assertSame(RECEIPT, result); } @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(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()); @@ -79,11 +87,11 @@ 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(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()); @@ -92,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/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 66% 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..c6dc3fc17 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 @@ -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; @@ -15,49 +15,56 @@ 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.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.*; +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.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"; 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()); @@ -66,27 +73,19 @@ public class SignedRequestBuilderTest { SIGNED_REQUEST_HEADERS.put(YotiConstants.DIGEST_HEADER, SOME_SIGNATURE); } - @BeforeClass - public static void setUpClass() throws Exception { - KEY_PAIR = generateKeyPairFrom(KEY_PAIR_PEM); - } - - @InjectMocks SignedRequestBuilder signedRequestBuilder; + @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() { try { - signedRequestBuilder.withHttpMethod("someNonsenseHere"); + yotiHttpRequestBuilder.withHttpMethod("someNonsenseHere"); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("someNonsenseHere")); return; @@ -96,11 +95,11 @@ public void withHttpMethod_shouldThrowExceptionWhenSuppliedWithUnsupportedHttpMe } @Test - public void build_shouldThrowExceptionWhenMissingKeyPair() throws Exception { + public void build_shouldThrowExceptionWhenMissingAuthStrategy() throws Exception { try { - signedRequestBuilder.build(); + yotiHttpRequestBuilder.build(); } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("keyPair")); + assertThat(e.getMessage(), containsString("'authStrategy' must not be null")); return; } fail("Expected an IllegalArgumentException"); @@ -109,7 +108,7 @@ public void build_shouldThrowExceptionWhenMissingKeyPair() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingBaseUrl() throws Exception { try { - signedRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .build(); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("baseUrl")); @@ -121,7 +120,7 @@ public void build_shouldThrowExceptionWhenMissingBaseUrl() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingEndpoint() throws Exception { try { - signedRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .build(); } catch (IllegalArgumentException e) { @@ -134,7 +133,7 @@ public void build_shouldThrowExceptionWhenMissingEndpoint() throws Exception { @Test public void build_shouldThrowExceptionWhenMissingHttpMethod() throws Exception { try { - signedRequestBuilder.withKeyPair(KEY_PAIR) + yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .build(); @@ -147,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"))); - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -157,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 { - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(DEFAULT_YOTI_API_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -172,103 +172,103 @@ 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); - SignedRequest result = signedRequestBuilder.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)); } @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.withAuthStrategy(authStrategyMock) .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 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); - SignedRequest result = signedRequestBuilder.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)); @@ -276,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); - SignedRequest result = signedRequestBuilder.withKeyPair(KEY_PAIR) + YotiHttpRequest result = yotiHttpRequestBuilder.withAuthStrategy(authStrategyMock) .withBaseUrl(SOME_BASE_URL) .withEndpoint(SOME_ENDPOINT) .withHttpMethod(HTTP_GET) @@ -290,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)); @@ -302,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 @@ -323,7 +316,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.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) @@ -338,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)); @@ -352,7 +341,7 @@ public void shouldThrowIllegalArgumentExceptionWhenThereIsAnErrorBuildingTheMult ms.when(MultipartEntityBuilder::create).thenReturn(multipartEntityBuilderMock); IllegalStateException exception = assertThrows(IllegalStateException.class, () -> { - signedRequestBuilder.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 3f032bdf6..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; @@ -17,7 +15,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; @@ -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,8 +43,7 @@ public class RemoteAmlServiceTest { @Mock ObjectMapper objectMapperMock; @Mock AmlProfile amlProfileMock; - @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPairMock; - @Mock SignedRequest signedRequestMock; + @Mock YotiHttpRequest yotiHttpRequestMock; @Mock AmlResult amlResultMock; @BeforeClass @@ -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(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); - when(signedRequestMock.execute(AmlResult.class)).thenReturn(amlResultMock); + 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(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); - when(signedRequestMock.execute(AmlResult.class)).thenThrow(ioException); + 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(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, GENERATED_PATH, BODY_BYTES); - when(signedRequestMock.execute(AmlResult.class)).thenThrow(resourceException); + 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 8e3cacdbf..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 @@ -1,102 +1,74 @@ 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; 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; 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.DigitalIdentitySignedRequestStrategy; 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.junit.MockitoJUnitRunner; @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); - @Spy @InjectMocks DigitalIdentityService identityService; + @InjectMocks DigitalIdentityService testObj; - @Mock UnsignedPathFactory unsignedPathFactory; - @Mock(answer = RETURNS_DEEP_STUBS) SignedRequestBuilder signedRequestBuilder; - @Mock SignedRequestBuilderFactory requestBuilderFactory; + @Mock UnsignedPathFactory unsignedPathFactoryMock; + @Mock YotiHttpRequestBuilderFactory requestBuilderFactoryMock; - @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPair; - @Mock SignedRequest signedRequest; + @Mock(answer = RETURNS_DEEP_STUBS) YotiHttpRequestBuilder yotiHttpRequestBuilder; + @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")); - } - - @Test - public void createShareSession_NullKeyPair_Exception() { - IllegalArgumentException ex = assertThrows( - IllegalArgumentException.class, - () -> identityService.createShareSession(SDK_ID, null, shareSessionRequest) - ); + when(requestBuilderFactoryMock.create()).thenReturn(yotiHttpRequestBuilder); - 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) + () -> testObj.createShareSession(null) ); assertThat(ex.getMessage(), containsString("Share Session request")); @@ -111,7 +83,7 @@ public void createShareSession_SerializingWrongPayload_Exception() { DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -124,16 +96,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(signedRequestBuilder); 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(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -147,16 +117,13 @@ 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); - 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(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -170,16 +137,13 @@ 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); - 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(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.createShareSession(SDK_ID, keyPair, shareSessionRequest) + () -> testObj.createShareSession(shareSessionRequest) ); Throwable cause = ex.getCause(); @@ -193,133 +157,40 @@ 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(identityService.createSignedRequest(SDK_ID, keyPair, SESSION_CREATION_PATH, POST, A_BODY_BYTES)) - .thenReturn(signedRequest); + when(testObj.createSignedRequest(SESSION_CREATION_PATH, POST, A_BODY_BYTES)).thenReturn(yotiHttpRequest); + when(yotiHttpRequest.execute(ShareSession.class)).thenReturn(shareSession); - when(signedRequest.execute(ShareSession.class)).thenReturn(shareSession); + ShareSession result = testObj.createShareSession(shareSessionRequest); - ShareSession result = identityService.createShareSession(SDK_ID, keyPair, 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) + () -> testObj.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) + () -> testObj.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) + () -> testObj.fetchMatch(null) ); assertThat(ex.getMessage(), notNullValue()); @@ -334,7 +205,7 @@ public void fetchMatch_SerializingWrongPayload_Exception() { DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -347,16 +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); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); 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(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)).thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -370,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); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); - 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(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) .thenThrow(causeEx); DigitalIdentityException ex = assertThrows( DigitalIdentityException.class, - () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -393,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); - when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); - String exMessage = "Wrong digest"; GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); - when(identityService.createSignedRequest(SDK_ID, keyPair, 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(SDK_ID, keyPair, matchRequest) + () -> testObj.fetchMatch(matchRequest) ); Throwable cause = ex.getCause(); @@ -416,14 +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(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); - - when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) - .thenReturn(signedRequest); + when(testObj.createSignedRequest(DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + .thenReturn(yotiHttpRequest); + when(yotiHttpRequest.execute(MatchResult.class)).thenReturn(matchResult); - when(signedRequest.execute(MatchResult.class)).thenReturn(matchResult); + MatchResult result = testObj.fetchMatch(matchRequest); - 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..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 @@ -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; @@ -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(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); - when(signedRequestMock.execute(ShareUrlResult.class)).thenThrow(ioException); + 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(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); - when(signedRequestMock.execute(ShareUrlResult.class)).thenThrow(resourceException); + 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(signedRequestMock).when(testObj).createSignedRequest(keyPairMock, DYNAMIC_QRCODE_PATH, SOME_BODY_BYTES); - when(signedRequestMock.execute(ShareUrlResult.class)).thenReturn(shareUrlResultMock); + 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 1f113c752..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 @@ -18,11 +18,10 @@ 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.yoti.api.client.spi.remote.call.factory.SimpleSignedRequestStrategy; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; @@ -34,12 +33,12 @@ 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; private final ResourceFetcher resourceFetcher; - private final SignedRequestBuilderFactory signedRequestBuilderFactory; + private final YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; public static YotiSandboxClientBuilder builder() { return new YotiSandboxClientBuilder(); @@ -49,13 +48,14 @@ 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.authStrategy = new SimpleSignedRequestStrategy(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 +65,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) + .withAuthStrategy(authStrategy) .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 +108,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..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 @@ -17,8 +17,9 @@ 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.yoti.api.client.spi.remote.call.factory.DocsSignedRequestStrategy; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; @@ -31,18 +32,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; + private final DocsSignedRequestStrategy authStrategy; - DocScanSandboxClient(String sdkId, - KeyPair keyPair, + private DocScanSandboxClient(String sdkId, + DocsSignedRequestStrategy authStrategy, ObjectMapper mapper, - SignedRequestBuilderFactory signedRequestBuilderFactory) { + YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory) { this.sdkId = sdkId; - this.keyPair = keyPair; + this.authStrategy = authStrategy; this.mapper = mapper; - this.signedRequestBuilderFactory = signedRequestBuilderFactory; + this.yotiHttpRequestBuilderFactory = yotiHttpRequestBuilderFactory; this.docScanBaseUrl = System.getProperty(PROPERTY_YOTI_DOCS_URL, DEFAULT_DOC_SCAN_SANDBOX_API_URL); } @@ -63,16 +64,15 @@ 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) + .withAuthStrategy(authStrategy) .withHttpMethod(HttpMethod.HTTP_PUT) .withPayload(body) - .withQueryParameter("sdkId", sdkId) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (URISyntaxException | GeneralSecurityException | ResourceException | IOException e) { throw new SandboxException(e); } @@ -89,15 +89,15 @@ 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) + .withAuthStrategy(authStrategy) .withHttpMethod(HttpMethod.HTTP_PUT) .withPayload(body) .build(); - signedRequest.execute(); + yotiHttpRequest.execute(); } catch (URISyntaxException | GeneralSecurityException | ResourceException | IOException e) { throw new SandboxException(e); } @@ -132,7 +132,8 @@ public DocScanSandboxClient build() { notNullOrEmpty(sdkId, "sdkId"); notNull(keyPair, "keyPair"); - return new DocScanSandboxClient(sdkId, keyPair, new ObjectMapper(), new SignedRequestBuilderFactory()); + 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 828213aac..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 @@ -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,18 @@ 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 +114,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 +130,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..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 @@ -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.junit.Assert.fail; -import static org.mockito.Mockito.*; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThrows; +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.yoti.api.client.spi.remote.call.factory.DocsSignedRequestStrategy; 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.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class DocScanSandboxClientTest { @@ -32,80 +37,72 @@ 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 ResponseConfig responseConfigMock; + @InjectMocks DocScanSandboxClient testObj; + + @Mock YotiHttpRequestBuilderFactory yotiHttpRequestBuilderFactory; @Mock ObjectMapper objectMapperMock; - @Mock KeyPair keyPairMock; + @Mock DocsSignedRequestStrategy authStrategyMock; - @Spy @InjectMocks DocScanSandboxClient docScanSandboxClient; + @Mock(answer = Answers.RETURNS_SELF) YotiHttpRequestBuilder yotiHttpRequestBuilderMock; + @Mock YotiHttpRequest yotiHttpRequestMock; + @Mock ResponseConfig responseConfigMock; + @Mock KeyPair keyPairMock; @Before public void setUp() { - when(signedRequestBuilderFactory.create()).thenReturn(signedRequestBuilderMock); + when(yotiHttpRequestBuilderFactory.create()).thenReturn(yotiHttpRequestBuilderMock); } @Test 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); - - try { - docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); - } catch (SandboxException ex) { - assertThat(ex.getMessage(), containsString("Some error")); - return; - } - fail("Expected an exception"); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(ioException); + + SandboxException thrown = assertThrows(SandboxException.class, () -> testObj.configureSessionResponse(SOME_SESSION_ID, responseConfigMock)); + + 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(signedRequestMock.execute()).thenThrow(resourceException); - when(signedRequestBuilderMock.build()).thenReturn(signedRequestMock); - - try { - docScanSandboxClient.configureSessionResponse(SOME_SESSION_ID, responseConfigMock); - } catch (SandboxException ex) { - assertThat(ex.getMessage(), containsString("Some error")); - return; - } - fail("Expected an exception"); + when(yotiHttpRequestBuilderMock.build()).thenReturn(yotiHttpRequestMock); + when(yotiHttpRequestMock.execute()).thenThrow(resourceException); + + SandboxException thrown = assertThrows(SandboxException.class, () -> testObj.configureSessionResponse(SOME_SESSION_ID, responseConfigMock)); + + assertThat(thrown.getMessage(), containsString("Some error")); } @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); + testObj.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).withAuthStrategy(authStrategyMock); + 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); + FieldSetter.setField(testObj, "sdkId", SOME_SDK_ID); - docScanSandboxClient.configureApplicationResponse(responseConfigMock); + testObj.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).withAuthStrategy(authStrategyMock); + verify(yotiHttpRequestBuilderMock).withEndpoint("/apps/" + SOME_SDK_ID + "/response-config"); + verify(yotiHttpRequestBuilderMock).withPayload(SOME_BYTES); } }