Skip to content

Commit

Permalink
Feat: auth manager refactoring enabling to have dedicated managers to…
Browse files Browse the repository at this point in the history
… each underline APIs (#14)

* docs: typo & javadoc

* refactor: Attach Auth manager at API level. Because of OAS files could cause conflicts with same scheme name alias for different managers, dedicated service's auth managers are stored at API level and no longer at HttpClient level (http client is shared across all APIs for sinch client SDK library)

* feat: synchronize generated sources from OAS file
  • Loading branch information
JPPortier authored Nov 22, 2023
1 parent 2aaf1ba commit 08bdadd
Show file tree
Hide file tree
Showing 36 changed files with 396 additions and 193 deletions.
22 changes: 1 addition & 21 deletions client/src/main/com/sinch/sdk/SinchClient.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
package com.sinch.sdk;

import com.sinch.sdk.auth.AuthManager;
import com.sinch.sdk.auth.adapters.BasicAuthManager;
import com.sinch.sdk.auth.adapters.BearerAuthManager;
import com.sinch.sdk.core.http.HttpMapper;
import com.sinch.sdk.domains.numbers.NumbersService;
import com.sinch.sdk.domains.sms.SMSService;
import com.sinch.sdk.http.HttpClientApache;
import com.sinch.sdk.models.Configuration;
import com.sinch.sdk.models.SMSRegion;
import java.io.IOException;
import java.io.InputStream;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/** Sinch Sdk Client implementation */
public class SinchClient {
Expand Down Expand Up @@ -143,22 +135,10 @@ private Properties handleDefaultConfigurationFile() {

private HttpClientApache getHttpClient() {
if (null == httpClient || httpClient.isClosed()) {
AuthManager basicAuthManager = new BasicAuthManager(configuration);
BearerAuthManager bearerAuthManager = new BearerAuthManager(configuration, new HttpMapper());

Map<String, AuthManager> authManagers =
Stream.of(basicAuthManager, bearerAuthManager)
.map(e -> new AbstractMap.SimpleEntry<>(e.getSchema(), e))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

// TODO: by adding a setter, we could imagine having another HTTP client provided
// programmatically or use
// configuration file referencing another class by name
this.httpClient = new HttpClientApache(authManagers);

// Avoid multiple and costly http client creation and reuse it for authManager
bearerAuthManager.setHttpClient(this.httpClient);

this.httpClient = new HttpClientApache();
LOGGER.fine("HTTP client loaded");
}
return this.httpClient;
Expand Down
14 changes: 0 additions & 14 deletions client/src/main/com/sinch/sdk/auth/AuthManager.java

This file was deleted.

15 changes: 4 additions & 11 deletions client/src/main/com/sinch/sdk/auth/adapters/BasicAuthManager.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
package com.sinch.sdk.auth.adapters;

import com.sinch.sdk.auth.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.models.Configuration;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class BasicAuthManager implements AuthManager {
public static final String BASIC_SCHEMA_KEYWORD = "BasicAuth";
private static final String BASIC_AUTH_KEYWORD = "Basic";
private static final String AUTH_KEYWORD = "Basic";
private final Configuration configuration;

public BasicAuthManager(Configuration configuration) {
this.configuration = configuration;
}

public String getSchema() {
return BASIC_SCHEMA_KEYWORD;
}

@Override
public void setHttpClient(HttpClient httpClient) {
// no op
return SCHEMA_KEYWORD_BASIC;
}

@Override
Expand All @@ -36,7 +29,7 @@ public String getAuthorizationHeaderValue() {

String raw = key + ":" + secret;

return BASIC_AUTH_KEYWORD
return AUTH_KEYWORD
+ " "
+ Base64.getEncoder().encodeToString(raw.getBytes(StandardCharsets.UTF_8));
}
Expand Down
35 changes: 21 additions & 14 deletions client/src/main/com/sinch/sdk/auth/adapters/BearerAuthManager.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,49 @@
package com.sinch.sdk.auth.adapters;

import com.fasterxml.jackson.core.type.TypeReference;
import com.sinch.sdk.auth.AuthManager;
import com.sinch.sdk.auth.models.BearerAuthResponse;
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.core.http.HttpMapper;
import com.sinch.sdk.core.http.HttpMethod;
import com.sinch.sdk.core.http.HttpRequest;
import com.sinch.sdk.core.http.HttpResponse;
import com.sinch.sdk.models.Configuration;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class BearerAuthManager implements AuthManager {
public static final String BEARER_SCHEMA_KEYWORD = "BearerAuth";
public static final String BEARER_EXPIRED_KEYWORD = "expired";
public static final String BEARER_AUTHENTICATE_RESPONSE_HEADER_KEYWORD = "www-authenticate";
private static final Logger LOGGER = Logger.getLogger(BearerAuthManager.class.getName());
private static final String BEARER_AUTH_KEYWORD = "Bearer";
private static final String AUTH_KEYWORD = "Bearer";
private static final int maxRefreshAttempt = 5;
private final Configuration configuration;
private final HttpMapper mapper;
private HttpClient httpClient;
private final HttpClient httpClient;
private final Map<String, AuthManager> authManagers;

private String token;

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

public String getSchema() {
return BEARER_SCHEMA_KEYWORD;
AuthManager basicAuthManager = new BasicAuthManager(configuration);
authManagers =
Stream.of(new AbstractMap.SimpleEntry<>(SCHEMA_KEYWORD_BASIC, basicAuthManager))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

@Override
public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
public String getSchema() {
return SCHEMA_KEYWORD_BEARER;
}

@Override
Expand All @@ -51,7 +57,7 @@ public String getAuthorizationHeaderValue() {
if (token == null) {
refreshToken();
}
return BEARER_AUTH_KEYWORD + " " + token;
return AUTH_KEYWORD + " " + token;
}

private void refreshToken() {
Expand Down Expand Up @@ -80,9 +86,10 @@ private Optional<String> getNewToken() {
null,
null,
Collections.singletonList("application/x-www-form-urlencoded"),
Collections.singletonList(BasicAuthManager.BASIC_SCHEMA_KEYWORD));
Collections.singletonList(SCHEMA_KEYWORD_BASIC));
try {
HttpResponse httpResponse = httpClient.invokeAPI(configuration.getOAuthServer(), request);
HttpResponse httpResponse =
httpClient.invokeAPI(configuration.getOAuthServer(), authManagers, request);
BearerAuthResponse authResponse =
mapper.deserialize(httpResponse, new TypeReference<BearerAuthResponse>() {});
return Optional.ofNullable(authResponse.getAccessToken());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public interface NumbersService {
ActiveNumberService active();

/**
* Callbacks Configuraiton Service instance
* Callbacks Configuration Service instance
*
* @return service instance for project
* @since 1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sinch.sdk.domains.numbers.adapters;

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.core.http.HttpMapper;
import com.sinch.sdk.core.models.pagination.Page;
Expand All @@ -22,6 +23,7 @@
import com.sinch.sdk.models.Configuration;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

Expand All @@ -32,9 +34,12 @@ public class ActiveNumberService implements com.sinch.sdk.domains.numbers.Active

public ActiveNumberService() {}

public ActiveNumberService(Configuration configuration, HttpClient httpClient) {
public ActiveNumberService(
Configuration configuration, HttpClient httpClient, Map<String, AuthManager> authManagers) {
this.configuration = configuration;
this.api = new ActiveNumberApi(httpClient, configuration.getNumbersServer(), new HttpMapper());
this.api =
new ActiveNumberApi(
httpClient, configuration.getNumbersServer(), authManagers, new HttpMapper());
}

private ActiveNumberApi getApi() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sinch.sdk.domains.numbers.adapters;

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.core.http.HttpMapper;
import com.sinch.sdk.core.utils.EnumDynamic;
Expand All @@ -20,6 +21,7 @@
import com.sinch.sdk.models.Configuration;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

Expand All @@ -31,10 +33,12 @@ public class AvailableNumberService

public AvailableNumberService() {}

public AvailableNumberService(Configuration configuration, HttpClient httpClient) {
public AvailableNumberService(
Configuration configuration, HttpClient httpClient, Map<String, AuthManager> authManagers) {
this.configuration = configuration;
this.api =
new AvailableNumberApi(httpClient, configuration.getNumbersServer(), new HttpMapper());
new AvailableNumberApi(
httpClient, configuration.getNumbersServer(), authManagers, new HttpMapper());
}

private AvailableNumberApi getApi() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sinch.sdk.domains.numbers.adapters;

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.core.http.HttpMapper;
import com.sinch.sdk.core.utils.EnumDynamic;
Expand All @@ -13,6 +14,7 @@
import com.sinch.sdk.models.Configuration;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class AvailableRegionService
Expand All @@ -23,10 +25,12 @@ public class AvailableRegionService

public AvailableRegionService() {}

public AvailableRegionService(Configuration configuration, HttpClient httpClient) {
public AvailableRegionService(
Configuration configuration, HttpClient httpClient, Map<String, AuthManager> authManagers) {
this.configuration = configuration;
this.api =
new AvailableRegionsApi(httpClient, configuration.getNumbersServer(), new HttpMapper());
new AvailableRegionsApi(
httpClient, configuration.getNumbersServer(), authManagers, new HttpMapper());
}

public AvailableRegionListResponse list(AvailableRegionListAllRequestParameters parameters)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sinch.sdk.domains.numbers.adapters;

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.core.http.HttpMapper;
import com.sinch.sdk.domains.numbers.adapters.api.v1.CallbackConfigurationApi;
Expand All @@ -10,6 +11,7 @@
import com.sinch.sdk.domains.numbers.models.dto.v1.CallbackConfigurationDto;
import com.sinch.sdk.domains.numbers.models.requests.CallbackConfigurationUpdateRequestParameters;
import com.sinch.sdk.models.Configuration;
import java.util.Map;

public class CallbackConfigurationService
implements com.sinch.sdk.domains.numbers.CallbackConfigurationService {
Expand All @@ -19,11 +21,12 @@ public class CallbackConfigurationService

public CallbackConfigurationService() {}

public CallbackConfigurationService(Configuration configuration, HttpClient httpClient) {
public CallbackConfigurationService(
Configuration configuration, HttpClient httpClient, Map<String, AuthManager> authManagers) {
this.configuration = configuration;
this.api =
new CallbackConfigurationApi(
httpClient, configuration.getNumbersServer(), new HttpMapper());
httpClient, configuration.getNumbersServer(), authManagers, new HttpMapper());
}

private CallbackConfigurationApi getApi() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,59 @@
package com.sinch.sdk.domains.numbers.adapters;

import com.sinch.sdk.auth.adapters.BasicAuthManager;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.models.Configuration;
import java.util.AbstractMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class NumbersService implements com.sinch.sdk.domains.numbers.NumbersService {
private static final String SECURITY_SCHEME_KEYWORD_NUMBERS = "BasicAuth";

private final Configuration configuration;
private final HttpClient httpClient;
private AvailableNumberService available;
private ActiveNumberService active;
private AvailableRegionService regions;
private CallbackConfigurationService callback;
private final Map<String, AuthManager> authManagers;

public NumbersService(Configuration configuration, HttpClient httpClient) {
this.configuration = configuration;
this.httpClient = httpClient;
AuthManager basicAuthManager = new BasicAuthManager(configuration);

authManagers =
Stream.of(new AbstractMap.SimpleEntry<>(SECURITY_SCHEME_KEYWORD_NUMBERS, basicAuthManager))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

public AvailableNumberService available() {
if (null == this.available) {
this.available = new AvailableNumberService(configuration, httpClient);
this.available = new AvailableNumberService(configuration, httpClient, authManagers);
}
return this.available;
}

public AvailableRegionService regions() {
if (null == this.regions) {
this.regions = new AvailableRegionService(configuration, httpClient);
this.regions = new AvailableRegionService(configuration, httpClient, authManagers);
}
return this.regions;
}

public ActiveNumberService active() {
if (null == this.active) {
this.active = new ActiveNumberService(configuration, httpClient);
this.active = new ActiveNumberService(configuration, httpClient, authManagers);
}
return this.active;
}

public CallbackConfigurationService callback() {
if (null == this.callback) {
this.callback = new CallbackConfigurationService(configuration, httpClient);
this.callback = new CallbackConfigurationService(configuration, httpClient, authManagers);
}
return this.callback;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public interface GroupsService {
* Get phone numbers for a group
*
* @param groupId ID of a group that you are interested in getting.
* @return A list of phone numbers in E.164 format.
* @see <a
* href="https://developers.sinch.com/docs/sms/api-reference/sms/tag/Groups/#tag/Groups/operation/deleteGroup">https://developers.sinch.com/docs/sms/api-reference/sms/tag/Groups/#tag/Groups/operation/deleteGroup</a>
* @since 1.0
Expand Down
Loading

0 comments on commit 08bdadd

Please sign in to comment.