Skip to content

Commit 21c7afb

Browse files
authored
Merge 763b978 into a4e3eec
2 parents a4e3eec + 763b978 commit 21c7afb

File tree

88 files changed

+567
-131
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+567
-131
lines changed

clients/algoliasearch-client-csharp/algoliasearch/Clients/AlgoliaConfig.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected AlgoliaConfig(string appId, string apiKey, string clientName, string c
4545
/// The admin API Key
4646
/// </summary>
4747
/// <returns></returns>
48-
public string ApiKey { get; }
48+
public string ApiKey { get; set; }
4949

5050
/// <summary>
5151
/// Configurations hosts
@@ -97,5 +97,16 @@ internal Dictionary<string, string> BuildHeaders()
9797
DefaultHeaders[Defaults.UserAgentHeader.ToLowerInvariant()] = UserAgent.ToString();
9898
return DefaultHeaders;
9999
}
100+
101+
/// <summary>
102+
/// Helper to switch the API key sent with each request
103+
/// </summary>
104+
/// <param name="apiKey">Your API Key</param>
105+
/// <returns></returns>
106+
public void SetClientApiKey(string apiKey)
107+
{
108+
ApiKey = apiKey;
109+
DefaultHeaders[Defaults.AlgoliaApiKeyHeader.ToLowerInvariant()] = apiKey;
110+
}
100111
}
101112
}

clients/algoliasearch-client-csharp/algoliasearch/Transport/HttpTransport.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal class HttpTransport
2424
private readonly IHttpRequester _httpClient;
2525
private readonly ISerializer _serializer;
2626
private readonly RetryStrategy _retryStrategy;
27-
private readonly AlgoliaConfig _algoliaConfig;
27+
internal AlgoliaConfig _algoliaConfig;
2828
private string _errorMessage;
2929
private readonly ILogger<HttpTransport> _logger;
3030

clients/algoliasearch-client-dart/packages/client_core/lib/src/api_client.dart

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ import 'package:algolia_client_core/src/config/client_options.dart';
22

33
/// An abstract class representing an API client with specific properties and options.
44
abstract interface class ApiClient {
5-
/// The unique identifier for the application using the API client.
6-
String get appId;
7-
8-
/// The API key used for authentication.
9-
String get apiKey;
10-
115
/// A set of custom client options to configure the behavior of the API client.
126
ClientOptions get options;
137

8+
/// Allow switching the API key used to authenticate requests.
9+
void setClientApiKey({required String apiKey});
10+
1411
/// Dispose of underlying resources.
1512
void dispose();
1613
}

clients/algoliasearch-client-dart/packages/client_core/lib/src/transport/dio/auth_interceptor.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class AuthInterceptor extends Interceptor {
99
final String appId;
1010

1111
/// The API key used for Algolia authentication.
12-
final String apiKey;
12+
String apiKey;
1313

1414
/// Constructs an [AuthInterceptor] with the provided application id and API key.
1515
AuthInterceptor({

clients/algoliasearch-client-dart/packages/client_core/lib/src/transport/dio/dio_requester.dart

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import 'package:dio/dio.dart';
1616
/// response conversion and error handling.
1717
class DioRequester implements Requester {
1818
/// The underlying Dio client.
19-
final Dio _client;
19+
final AuthInterceptor _authInterceptor;
20+
late final Dio _client;
2021

2122
/// Constructs a [DioRequester] with the given [appId], [apiKey], and [options].
2223
DioRequester({
@@ -28,29 +29,30 @@ class DioRequester implements Requester {
2829
Function(Object?)? logger,
2930
Iterable<Interceptor>? interceptors,
3031
HttpClientAdapter? httpClientAdapter,
31-
}) : _client = Dio(
32-
BaseOptions(
33-
headers: headers,
34-
connectTimeout: connectTimeout,
32+
}) : _authInterceptor = AuthInterceptor(
33+
appId: appId,
34+
apiKey: apiKey,
35+
) {
36+
_client = Dio(
37+
BaseOptions(
38+
headers: headers,
39+
connectTimeout: connectTimeout,
40+
),
41+
)..interceptors.addAll([
42+
_authInterceptor,
43+
AgentInterceptor(
44+
agent: AlgoliaAgent(packageVersion)
45+
..addAll(clientSegments ?? const [])
46+
..addAll(Platform.agentSegments()),
47+
),
48+
if (logger != null)
49+
LogInterceptor(
50+
requestBody: true,
51+
responseBody: true,
52+
logPrint: logger,
3553
),
36-
)..interceptors.addAll([
37-
AuthInterceptor(
38-
appId: appId,
39-
apiKey: apiKey,
40-
),
41-
AgentInterceptor(
42-
agent: AlgoliaAgent(packageVersion)
43-
..addAll(clientSegments ?? const [])
44-
..addAll(Platform.agentSegments()),
45-
),
46-
if (logger != null)
47-
LogInterceptor(
48-
requestBody: true,
49-
responseBody: true,
50-
logPrint: logger,
51-
),
52-
if (interceptors != null) ...interceptors,
53-
]) {
54+
if (interceptors != null) ...interceptors,
55+
]);
5456
if (httpClientAdapter != null) {
5557
_client.httpClientAdapter = httpClientAdapter;
5658
}
@@ -114,4 +116,9 @@ class DioRequester implements Requester {
114116

115117
@override
116118
void close() => _client.close();
119+
120+
@override
121+
void setClientApiKey(String apiKey) {
122+
_authInterceptor.apiKey = apiKey;
123+
}
117124
}

clients/algoliasearch-client-dart/packages/client_core/lib/src/transport/requester.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ abstract class Requester {
1111
/// The method returns a Future that resolves to an [HttpResponse].
1212
Future<HttpResponse> perform(HttpRequest request);
1313

14+
/// Allows to switch the API key used to authenticate requests.
15+
void setClientApiKey(String apiKey);
16+
1417
/// Closes any underlying resources that the Requester might be using.
1518
///
1619
/// By default, it does nothing (no-op), but it can be implemented to handle resource cleanup

clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/ApiClient.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.concurrent.ExecutorService;
1717
import java.util.stream.Collectors;
1818
import org.jetbrains.annotations.Nullable;
19+
import javax.annotation.Nonnull;
1920

2021
/**
2122
* Represents a base client for making API requests. The client uses a {@link Requester} for
@@ -26,6 +27,7 @@ public abstract class ApiClient implements Closeable {
2627

2728
private final Requester requester;
2829
private final ExecutorService executor;
30+
private AuthInterceptor authInterceptor;
2931

3032
/** Constructs a new instance of the {@link ApiClient}. */
3133
protected ApiClient(String appId, String apiKey, String clientName, @Nullable ClientOptions options, List<Host> defaultHosts) {
@@ -52,8 +54,9 @@ private Requester defaultRequester(String appId, String apiKey, String clientNam
5254
List<StatefulHost> statefulHosts = hosts.stream().map(StatefulHost::new).collect(Collectors.toList());
5355

5456
JsonSerializer serializer = JsonSerializer.builder().setCustomConfig(options.getMapperConfig()).build();
57+
this.authInterceptor = new AuthInterceptor(appId, apiKey);
5558
HttpRequester.Builder builder = new HttpRequester.Builder(serializer)
56-
.addInterceptor(new AuthInterceptor(appId, apiKey))
59+
.addInterceptor(authInterceptor)
5760
.addInterceptor(new UserAgentInterceptor(algoliaAgent))
5861
.addInterceptor(new RetryStrategy(statefulHosts));
5962
if (options.getRequesterConfig() != null) {
@@ -62,6 +65,15 @@ private Requester defaultRequester(String appId, String apiKey, String clientNam
6265
return builder.build(options);
6366
}
6467

68+
/**
69+
* Helper method to switch the API key used to authenticate the requests.
70+
*
71+
* @param apiKey The new API key to be used from now on.
72+
*/
73+
public void setClientApiKey(@Nonnull String apiKey) {
74+
this.authInterceptor.setApiKey(apiKey);
75+
}
76+
6577
/**
6678
* Executes an HTTP request asynchronously and returns a {@link CompletableFuture} of the response
6779
* deserialized into a specified type.

clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/internal/interceptors/AuthInterceptor.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@ public final class AuthInterceptor implements Interceptor {
1212
private static final String HEADER_API_KEY = "x-algolia-api-key";
1313

1414
private final String applicationId;
15-
private final String apiKey;
15+
private String apiKey;
1616

1717
public AuthInterceptor(String applicationId, String apiKey) {
1818
this.applicationId = applicationId;
1919
this.apiKey = apiKey;
2020
}
2121

22+
public void setApiKey(String apiKey) {
23+
this.apiKey = apiKey;
24+
}
25+
2226
@Nonnull
2327
@Override
2428
public Response intercept(Chain chain) throws IOException {

clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/configuration/internal/HttpClient.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import io.ktor.client.request.*
99
import io.ktor.serialization.kotlinx.json.*
1010

1111
private const val HEADER_APPLICATION_ID = "x-algolia-application-id"
12-
private const val HEADER_APIKEY = "x-algolia-api-key"
12+
public const val HEADER_APIKEY: String = "x-algolia-api-key"
1313

1414
internal fun algoliaHttpClient(
1515
appId: String,

clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/transport/Requester.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ public interface Requester {
3030
requestOptions: RequestOptions? = null,
3131
returnType: TypeInfo,
3232
): T
33+
34+
public fun setClientApiKey(apiKey: String);
3335
}

clients/algoliasearch-client-kotlin/client/src/commonMain/kotlin/com/algolia/client/transport/internal/KtorRequester.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.algolia.client.transport.internal
22

33
import com.algolia.client.configuration.CallType
44
import com.algolia.client.configuration.Host
5+
import com.algolia.client.configuration.internal.HEADER_APIKEY
56
import com.algolia.client.exception.AlgoliaRetryException
67
import com.algolia.client.exception.internal.asApiException
78
import com.algolia.client.exception.internal.asClientException
@@ -38,6 +39,15 @@ public class KtorRequester(
3839
private val mutex: Mutex = Mutex()
3940
private val retryableHosts = hosts.map { RetryableHost(it) }
4041

42+
public override fun setClientApiKey(apiKey: String) {
43+
headers {
44+
if (contains(HEADER_APIKEY)) {
45+
remove(HEADER_APIKEY)
46+
}
47+
append(HEADER_APIKEY, apiKey)
48+
}
49+
}
50+
4151
override suspend fun <T> execute(
4252
requestConfig: RequestConfig,
4353
requestOptions: RequestOptions?,

clients/algoliasearch-client-php/lib/Configuration/Configuration.php

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public function __construct(array $config = [])
6767
throw new AlgoliaException('`apiKey` is missing.');
6868
}
6969

70-
$this->setAlgoliaApiKey($config['apiKey']);
70+
$this->setClientApiKey($config['apiKey']);
7171
$this->setAuth('x-algolia-api-key', $config['apiKey']);
7272

7373
$this->setAppId($config['appId']);
@@ -193,13 +193,6 @@ public function getAlgoliaApiKey()
193193
return $this->config['apiKey'];
194194
}
195195

196-
public function setAlgoliaApiKey($apiKey)
197-
{
198-
$this->config['apiKey'] = $apiKey;
199-
200-
return $this;
201-
}
202-
203196
public function getHosts()
204197
{
205198
return $this->config['hosts'];
@@ -272,6 +265,30 @@ public function setDefaultHeaders(array $defaultHeaders)
272265
return $this;
273266
}
274267

268+
/**
269+
* Switch the API key used to authenticate requessts.
270+
*
271+
* @param string $apiKey The new API key to be used
272+
*
273+
* @return void
274+
*/
275+
public function setClientApiKey($apiKey)
276+
{
277+
$this->config['apiKey'] = $apiKey;
278+
279+
return $this;
280+
}
281+
282+
/**
283+
* @deprecated This method is deprecated. Use setClientApiKey() instead.
284+
*
285+
* @param mixed $apiKey
286+
*/
287+
public function setAlgoliaApiKey($apiKey)
288+
{
289+
return $this->setClientApiKey($apiKey);
290+
}
291+
275292
/**
276293
* Sets the user agent of the api client.
277294
*

clients/algoliasearch-client-python/algoliasearch/http/base_config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,8 @@ def __init__(self, app_id: Optional[str] = None, api_key: Optional[str] = None):
4040
self.headers = None
4141
self.proxies = None
4242
self.hosts = None
43+
44+
def set_client_api_key(self, api_key: str) -> None:
45+
"""Sets a new API key to authenticate requests."""
46+
self.api_key = api_key
47+
self.headers["x-algolia-api-key"] = api_key

clients/algoliasearch-client-ruby/lib/algolia/api_client.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ def self.default
2020
@@default ||= ApiClient.new
2121
end
2222

23+
def set_client_api_key(api_key)
24+
@config.set_client_api_key(api_key)
25+
end
26+
2327
# Call an API with given options.
2428
#
2529
# @return [Http::Response] the response.

clients/algoliasearch-client-ruby/lib/algolia/configuration.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ def initialize(app_id, api_key, hosts, client_name, opts = {})
4444
yield(self) if block_given?
4545
end
4646

47+
def set_client_api_key(api_key)
48+
@api_key = api_key
49+
@header_params["X-Algolia-API-Key"] = api_key
50+
end
51+
4752
# The default Configuration object.
4853
def self.default
4954
@@default ||= Configuration.new

clients/algoliasearch-client-scala/src/main/scala/algoliasearch/ApiClient.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ abstract class ApiClient(
4040
throw AlgoliaClientException("`apiKey` is missing.")
4141
}
4242

43+
private val authInterceptor = new AuthInterceptor(appId, apiKey)
44+
4345
private val requester = options.customRequester match {
4446
case Some(customRequester) => customRequester
4547
case None =>
@@ -62,7 +64,7 @@ abstract class ApiClient(
6264

6365
val builder = HttpRequester
6466
.builder(options.customFormats.getOrElse(formats))
65-
.withInterceptor(new AuthInterceptor(appId, apiKey))
67+
.withInterceptor(authInterceptor)
6668
.withInterceptor(new UserAgentInterceptor(algoliaAgent))
6769
.withInterceptor(new RetryStrategy(statefulHosts))
6870

@@ -89,4 +91,8 @@ abstract class ApiClient(
8991
override def close(): Unit = {
9092
Try(requester.close())
9193
}
94+
95+
def setClientApiKey(apiKey: String): Unit = {
96+
authInterceptor.setApiKey(apiKey)
97+
}
9298
}

clients/algoliasearch-client-scala/src/main/scala/algoliasearch/internal/interceptor/AuthInterceptor.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ import okhttp3.{Interceptor, Response}
1010
* API key
1111
*/
1212
private[algoliasearch] class AuthInterceptor(
13-
applicationId: String,
14-
apiKey: String
13+
applicationId: String,
14+
private var apiKey: String
1515
) extends Interceptor {
1616

1717
private val HeaderApplicationId = "x-algolia-application-id"
1818
private val HeaderApiKey = "x-algolia-api-key"
1919

20+
def setApiKey(newApiKey: String): Unit = {
21+
apiKey = newApiKey
22+
}
23+
2024
override def intercept(chain: Interceptor.Chain): Response = {
2125
val originalRequest = chain.request()
2226
val builder = originalRequest.newBuilder()

clients/algoliasearch-client-swift/Sources/Core/Networking/BaseConfiguration.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public protocol BaseConfiguration {
2323
var hosts: [RetryableHost] { get }
2424

2525
/// Default headers that should be applied to every request.
26-
var defaultHeaders: [String: String]? { get }
26+
var defaultHeaders: [String: String]? { get set }
2727

2828
/// Compression type
2929
var compression: CompressionAlgorithm { get }
@@ -48,7 +48,7 @@ public struct DefaultConfiguration: BaseConfiguration {
4848
public let writeTimeout: TimeInterval = 30
4949
public let readTimeout: TimeInterval = 5
5050
public let logLevel: LogLevel = .info
51-
public let defaultHeaders: [String: String]? = [:]
51+
public var defaultHeaders: [String: String]? = [:]
5252
public var hosts: [RetryableHost] = []
5353
public let compression: CompressionAlgorithm = .none
5454
}

0 commit comments

Comments
 (0)