Skip to content

Commit

Permalink
Merge pull request #19 from sinch/support-application-id-secret-for-v…
Browse files Browse the repository at this point in the history
…erification-api

Support application id/secret for Verification API authentication
  • Loading branch information
JPPortier authored Dec 4, 2023
2 parents 6ca8c0d + 94133e1 commit 614d898
Show file tree
Hide file tree
Showing 13 changed files with 147 additions and 43 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ buildNumber.properties
# JDT-specific (Eclipse Java Development Tools)
.classpath
.idea
*.iml
*.iml

sample-app/src/main/resources/config.properties
1 change: 0 additions & 1 deletion client/src/main/com/sinch/sdk/SinchClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ private Properties handlePropertiesFile(String fileName) {

private HttpClientApache getHttpClient() {
if (null == httpClient || httpClient.isClosed()) {

// TODO: by adding a setter, we could imagine having another HTTP client provided
// programmatically or use
// configuration file referencing another class by name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ public class BasicAuthManager implements AuthManager {
private final String keySecret;

public BasicAuthManager(Configuration configuration) {
this.keyId = configuration.getKeyId();
this.keySecret = configuration.getKeySecret();
this(configuration.getKeyId(), configuration.getKeySecret());
}

public BasicAuthManager(String keyId, String keySecret) {
this.keyId = keyId;
this.keySecret = keySecret;
}

public String getSchema() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,20 @@ public class BearerAuthManager implements AuthManager {
private String token;

public BearerAuthManager(Configuration configuration, HttpMapper mapper, HttpClient httpClient) {
this(configuration.getKeyId(), configuration.getKeySecret(), configuration, mapper, httpClient);
}

public BearerAuthManager(
String keyId,
String keySecret,
Configuration configuration,
HttpMapper mapper,
HttpClient httpClient) {
this.oAuthServer = configuration.getOAuthServer();
this.mapper = mapper;
this.httpClient = httpClient;

AuthManager basicAuthManager = new BasicAuthManager(configuration);
AuthManager basicAuthManager = new BasicAuthManager(keyId, keySecret);
authManagers =
Stream.of(new AbstractMap.SimpleEntry<>(SCHEMA_KEYWORD_BASIC, basicAuthManager))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@
*/
public interface VerificationService {

/**
* Use application secret in place of unified configuration for authentication (see Sinch
* dashboard for details) These credentials are related to Verification Apps
*
* @param key see <a href="https://dashboard.sinch.com/verification/apps">dashboard</a>
* @param secret see <a href="https://dashboard.sinch.com/verification/apps">dashboard</a>
* @return service instance for project
* @since 1.0
*/
VerificationService setApplicationCredentials(String key, String secret);

/**
* Verifications Service instance
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,29 @@
import com.sinch.sdk.domains.verification.models.VerificationReport;
import com.sinch.sdk.models.Configuration;
import java.util.Map;
import java.util.function.Supplier;

public class StatusService implements com.sinch.sdk.domains.verification.StatusService {

private QueryVerificationsApi api;

public StatusService() {}
private final Configuration configuration;
private final HttpClient httpClient;
private final Supplier<Map<String, AuthManager>> authManagerSupplier;

public StatusService(
Configuration configuration, HttpClient httpClient, Map<String, AuthManager> authManager) {
this.api =
new QueryVerificationsApi(
httpClient, configuration.getVerificationServer(), authManager, new HttpMapper());
Configuration configuration,
HttpClient httpClient,
Supplier<Map<String, AuthManager>> authManagerSupplier) {
this.configuration = configuration;
this.httpClient = httpClient;
this.authManagerSupplier = authManagerSupplier;
}

private QueryVerificationsApi getApi() {
return this.api;
protected QueryVerificationsApi getApi() {
return new QueryVerificationsApi(
httpClient,
configuration.getVerificationServer(),
authManagerSupplier.get(),
new HttpMapper());
}

public VerificationReport get(Identity identity, VerificationMethodType method) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import com.sinch.sdk.auth.adapters.BasicAuthManager;
import com.sinch.sdk.auth.adapters.VerificationApplicationAuthManager;
import com.sinch.sdk.core.exceptions.ApiAuthException;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.domains.verification.StatusService;
import com.sinch.sdk.domains.verification.VerificationsService;
import com.sinch.sdk.models.Configuration;
import java.util.AbstractMap;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -22,45 +24,55 @@ public class VerificationService implements com.sinch.sdk.domains.verification.V
private final HttpClient httpClient;
private VerificationsService verifications;
private StatusService status;
private final Map<String, AuthManager> authManagers;
private Map<String, AuthManager> authManagers;
private final Supplier<Map<String, AuthManager>> authManagersSupplier = () -> authManagers;

public VerificationService(Configuration configuration, HttpClient httpClient) {
this.configuration = configuration;
this.httpClient = httpClient;
}

public VerificationService setApplicationCredentials(String key, String secret) {

AuthManager authManager;
boolean useApplicationAuth = true;
if (useApplicationAuth) {
authManager =
new VerificationApplicationAuthManager(
configuration.getKeyId(),
// TODO: Currently Verification do not accept project related key/secret. TBC
// fallback to the verifications usage ones for POC
// Base64.getEncoder().encodeToString(configuration.getKeySecret().getBytes(StandardCharsets.UTF_8))
configuration.getKeySecret());
authManager = new VerificationApplicationAuthManager(key, secret);
} else {
authManager = new BasicAuthManager(configuration);
authManager = new BasicAuthManager(key, secret);
}
authManagers =
Stream.of(new AbstractMap.SimpleEntry<>(SECURITY_SCHEME_KEYWORD_VERIFICATION, authManager))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return this;
}

public VerificationsService verifications() {
if (null == this.verifications) {
checkCredentials();
this.verifications =
new com.sinch.sdk.domains.verification.adapters.VerificationsService(
configuration, httpClient, authManagers);
configuration, httpClient, authManagersSupplier);
}
return this.verifications;
}

public StatusService status() {
if (null == this.status) {
checkCredentials();
this.status =
new com.sinch.sdk.domains.verification.adapters.StatusService(
configuration, httpClient, authManagers);
configuration, httpClient, authManagersSupplier);
}
return this.status;
}

private void checkCredentials() throws ApiAuthException {
if (null == authManagers || authManagers.isEmpty()) {
throw new ApiAuthException(
String.format(
"Service '%s' cannot be called without defined credentials",
this.getClass().getSimpleName()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,30 @@
import com.sinch.sdk.domains.verification.models.response.StartVerificationResponse;
import com.sinch.sdk.models.Configuration;
import java.util.Map;
import java.util.function.Supplier;

public class VerificationsService
implements com.sinch.sdk.domains.verification.VerificationsService {

private SendingAndReportingVerificationsApi api;

public VerificationsService() {}
private final Configuration configuration;
private final HttpClient httpClient;
private final Supplier<Map<String, AuthManager>> authManagerSupplier;

public VerificationsService(
Configuration configuration, HttpClient httpClient, Map<String, AuthManager> authManager) {
this.api =
new SendingAndReportingVerificationsApi(
httpClient, configuration.getVerificationServer(), authManager, new HttpMapper());
Configuration configuration,
HttpClient httpClient,
Supplier<Map<String, AuthManager>> authManagerSupplier) {
this.configuration = configuration;
this.httpClient = httpClient;
this.authManagerSupplier = authManagerSupplier;
}

private SendingAndReportingVerificationsApi getApi() {
return this.api;
protected SendingAndReportingVerificationsApi getApi() {
return new SendingAndReportingVerificationsApi(
httpClient,
configuration.getVerificationServer(),
authManagerSupplier.get(),
new HttpMapper());
}

public StartVerificationResponse start(StartVerificationRequestParameters parameters) {
Expand Down
1 change: 1 addition & 0 deletions client/src/main/com/sinch/sdk/http/HttpClientApache.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ private void addAuth(
Map<String, AuthManager> authManagersByOasSecuritySchemes,
Collection<String> values,
String body) {

if (null == values || values.isEmpty() || null == authManagersByOasSecuritySchemes) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.sinch.sdk.domains.verification.adapters;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import com.adelean.inject.resources.junit.jupiter.TestWithResources;
import com.sinch.sdk.BaseTest;
import com.sinch.sdk.core.exceptions.ApiException;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.domains.verification.adapters.api.v1.QueryVerificationsApi;
import com.sinch.sdk.domains.verification.adapters.converters.VerificationsDtoConverterTest;
import com.sinch.sdk.domains.verification.models.NumberIdentity;
Expand All @@ -15,17 +19,28 @@
import com.sinch.sdk.domains.verification.models.VerificationReport;
import com.sinch.sdk.domains.verification.models.dto.v1.VerificationReportDtoTest;
import com.sinch.sdk.models.Configuration;
import java.util.Map;
import java.util.function.Supplier;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

@TestWithResources
public class StatusServiceTest extends BaseTest {

@Mock Configuration configuration;
@Mock QueryVerificationsApi api;
@InjectMocks StatusService service;
@Mock Configuration configuration;
@Mock HttpClient httpClient;
@Mock Supplier<Map<String, AuthManager>> authManagerSupplier;

StatusService service;

@BeforeEach
public void initMocks() {
service = spy(new StatusService(configuration, httpClient, authManagerSupplier));
doReturn(api).when(service).getApi();
}

@Test
void getByIdentity() throws ApiException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.sinch.sdk.domains.verification.adapters;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import com.adelean.inject.resources.junit.jupiter.GivenJsonResource;
import com.adelean.inject.resources.junit.jupiter.TestWithResources;
import com.sinch.sdk.BaseTest;
import com.sinch.sdk.core.exceptions.ApiException;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.domains.verification.adapters.api.v1.SendingAndReportingVerificationsApi;
import com.sinch.sdk.domains.verification.adapters.converters.VerificationsDtoConverterTest;
import com.sinch.sdk.domains.verification.models.NumberIdentity;
Expand All @@ -18,9 +22,11 @@
import com.sinch.sdk.domains.verification.models.dto.v1.VerificationReportRequestResourceDto;
import com.sinch.sdk.domains.verification.models.response.StartVerificationResponse;
import com.sinch.sdk.models.Configuration;
import java.util.Map;
import java.util.function.Supplier;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

@TestWithResources
Expand All @@ -32,9 +38,18 @@ public class VerificationsServiceTest extends BaseTest {
@GivenJsonResource("/domains/verification/v1/VerificationReportCalloutRequestDto.json")
public VerificationReportRequestResourceDto verificationReportRequestResourceDto;

@Mock Configuration configuration;
@Mock SendingAndReportingVerificationsApi api;
@InjectMocks VerificationsService service;
@Mock Configuration configuration;
@Mock HttpClient httpClient;
@Mock Supplier<Map<String, AuthManager>> authManagerSupplier;

VerificationsService service;

@BeforeEach
public void initMocks() {
service = spy(new VerificationsService(configuration, httpClient, authManagerSupplier));
doReturn(api).when(service).getApi();
}

@Test
void start() throws ApiException {
Expand Down
3 changes: 1 addition & 2 deletions sample-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ See https://developers.sinch.com for details about these parameters
## Available samples classes
<<<<<<< HEAD
### Full workflow
A full application chaining calls to Numbers service to onboard onto Java SDK and Numbers: [NumbersSampleFlow](src/main/java/com/sinch/sample/numbers/NumbersSampleFlow.java)
Expand All @@ -68,7 +67,7 @@ A full application chaining calls to Numbers service to onboard onto Java SDK an
| | | - Update | [com.sinch.sample.numbers.active.Update](src/main/java/com/sinch/sample/numbers/active/Update.java) | Require `PHONE_NUMBER` parameter |
| | Callback | - Get | [com.sinch.sample.numbers.callback.Get](src/main/java/com/sinch/sample/numbers/callback/Get.java) | |
| | | - Update | [com.sinch.sample.numbers.callback.Update](src/main/java/com/sinch/sample/numbers/callback/Get.java) | |
| | Regions | - ListAll | [com.sinch.sample.numbers.regions.ListAll](src/main/java/com/sinch/sample/numbers/regions/ListAll.java) | |
| | Regions | - ListAll | [com.sinch.sample.numbers.regions.List](src/main/java/com/sinch/sample/numbers/regions/List.java) | |
| SMS | Batches | - Get | [com.sinch.sample.sms.batches.Get](src/main/java/com/sinch/sample/sms/batches/Get.java) | Require `BATCH_ID` parameter |
| | | - List | [com.sinch.sample.sms.batches.List](src/main/java/com/sinch/sample/sms/batches/List.java) | |
| | | - Send | [com.sinch.sample.sms.batches.Send](src/main/java/com/sinch/sample/sms/batches/Send.java) | |
Expand Down
Loading

0 comments on commit 614d898

Please sign in to comment.