Skip to content

Commit 5759543

Browse files
algolia-botmillotp
andcommitted
chore: generated code for commit a58e883. [skip ci]
Co-authored-by: Pierre Millot <[email protected]>
1 parent a58e883 commit 5759543

File tree

1 file changed

+104
-8
lines changed
  • clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/api

1 file changed

+104
-8
lines changed

clients/algoliasearch-client-java/algoliasearch/src/main/java/com/algolia/api/SearchClient.java

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,31 @@
77
import com.algolia.config.*;
88
import com.algolia.config.ClientOptions;
99
import com.algolia.exceptions.*;
10+
import com.algolia.internal.JsonSerializer;
1011
import com.algolia.model.search.*;
1112
import com.algolia.utils.*;
1213
import com.fasterxml.jackson.core.type.TypeReference;
14+
import java.nio.charset.Charset;
15+
import java.security.InvalidKeyException;
16+
import java.security.NoSuchAlgorithmException;
17+
import java.time.Duration;
18+
import java.time.Instant;
1319
import java.util.ArrayList;
20+
import java.util.Base64;
1421
import java.util.Collections;
1522
import java.util.EnumSet;
23+
import java.util.HashMap;
1624
import java.util.List;
1725
import java.util.Map;
1826
import java.util.Random;
1927
import java.util.concurrent.CompletableFuture;
2028
import java.util.function.IntUnaryOperator;
29+
import java.util.regex.*;
2130
import java.util.stream.Collectors;
2231
import java.util.stream.Stream;
2332
import javax.annotation.Nonnull;
33+
import javax.crypto.Mac;
34+
import javax.crypto.spec.SecretKeySpec;
2435

2536
public class SearchClient extends ApiClient {
2637

@@ -5856,10 +5867,10 @@ public GetApiKeyResponse waitForApiKey(
58565867
}
58575868

58585869
/**
5859-
* Helper: Wait for an API key to be added, updated or deleted based on a given `operation`.
5870+
* Helper: Wait for an API key to be added or deleted based on a given `operation`.
58605871
*
58615872
* @param operation The `operation` that was done on a `key`. (ADD or DELETE only)
5862-
* @param key The `key` that has been added, deleted or updated.
5873+
* @param key The `key` that has been added or deleted.
58635874
* @param maxRetries The maximum number of retry. 50 by default. (optional)
58645875
* @param timeout The function to decide how long to wait between retries. min(retries * 200,
58655876
* 5000) by default. (optional)
@@ -5891,10 +5902,10 @@ public GetApiKeyResponse waitForApiKey(ApiKeyOperation operation, String key, Ap
58915902
}
58925903

58935904
/**
5894-
* Helper: Wait for an API key to be added, updated or deleted based on a given `operation`.
5905+
* Helper: Wait for an API key to be added or deleted based on a given `operation`.
58955906
*
58965907
* @param operation The `operation` that was done on a `key`. (ADD or DELETE only)
5897-
* @param key The `key` that has been added, deleted or updated.
5908+
* @param key The `key` that has been added or deleted.
58985909
* @param requestOptions The requestOptions to send along with the query, they will be merged with
58995910
* the transporter requestOptions. (optional)
59005911
*/
@@ -5918,10 +5929,10 @@ public GetApiKeyResponse waitForApiKey(ApiKeyOperation operation, String key, Ap
59185929
}
59195930

59205931
/**
5921-
* Helper: Wait for an API key to be added, updated or deleted based on a given `operation`.
5932+
* Helper: Wait for an API key to be added or deleted based on a given `operation`.
59225933
*
59235934
* @param operation The `operation` that was done on a `key`. (ADD or DELETE only)
5924-
* @param key The `key` that has been added, deleted or updated.
5935+
* @param key The `key` that has been added or deleted.
59255936
* @param maxRetries The maximum number of retry. 50 by default. (optional)
59265937
* @param timeout The function to decide how long to wait between retries. min(retries * 200,
59275938
* 5000) by default. (optional)
@@ -5943,10 +5954,10 @@ public GetApiKeyResponse waitForApiKey(ApiKeyOperation operation, String key, Ap
59435954
}
59445955

59455956
/**
5946-
* Helper: Wait for an API key to be added, updated or deleted based on a given `operation`.
5957+
* Helper: Wait for an API key to be added or deleted based on a given `operation`.
59475958
*
59485959
* @param operation The `operation` that was done on a `key`. (ADD or DELETE only)
5949-
* @param key The `key` that has been added, deleted or updated.
5960+
* @param key The `key` that has been added or deleted.
59505961
*/
59515962
public GetApiKeyResponse waitForApiKey(ApiKeyOperation operation, String key) {
59525963
return this.waitForApiKey(operation, key, null, TaskUtils.DEFAULT_MAX_RETRIES, TaskUtils.DEFAULT_TIMEOUT, null);
@@ -6353,4 +6364,89 @@ public <T> ReplaceAllObjectsResponse replaceAllObjects(
63536364
.setBatchResponses(batchResponses)
63546365
.setMoveOperationResponse(moveOperationResponse);
63556366
}
6367+
6368+
/**
6369+
* Helper: Generates a secured API key based on the given `parent_api_key` and given
6370+
* `restrictions`.
6371+
*
6372+
* @param parentApiKey API key to generate from.
6373+
* @param restrictions Restrictions to add the key
6374+
* @throws Exception if an error occurs during the encoding
6375+
* @throws AlgoliaRetryException When the retry has failed on all hosts
6376+
* @throws AlgoliaApiException When the API sends an http error code
6377+
* @throws AlgoliaRuntimeException When an error occurred during the serialization
6378+
*/
6379+
public String generateSecuredApiKey(@Nonnull String parentApiKey, @Nonnull SecuredAPIKeyRestrictions restrictions) throws Exception {
6380+
Map<String, String> restrictionsMap = new HashMap<>();
6381+
if (restrictions.getFilters() != null) restrictionsMap.put("filters", StringUtils.paramToString(restrictions.getFilters()));
6382+
if (restrictions.getValidUntil() != 0) restrictionsMap.put("validUntil", StringUtils.paramToString(restrictions.getValidUntil()));
6383+
if (restrictions.getRestrictIndices() != null) restrictionsMap.put(
6384+
"restrictIndices",
6385+
StringUtils.paramToString(restrictions.getRestrictIndices())
6386+
);
6387+
if (restrictions.getRestrictSources() != null) restrictionsMap.put(
6388+
"restrictSources",
6389+
StringUtils.paramToString(restrictions.getRestrictSources())
6390+
);
6391+
if (restrictions.getUserToken() != null) restrictionsMap.put("userToken", StringUtils.paramToString(restrictions.getUserToken()));
6392+
6393+
if (restrictions.getSearchParams() != null) {
6394+
Map<String, Object> searchParamsMap = JsonSerializer
6395+
.getObjectMapper()
6396+
.convertValue(restrictions.getSearchParams(), new TypeReference<Map<String, Object>>() {});
6397+
searchParamsMap.forEach((key, value) -> restrictionsMap.put(key, StringUtils.paramToString(value)));
6398+
}
6399+
6400+
String queryStr = restrictionsMap
6401+
.entrySet()
6402+
.stream()
6403+
.sorted(Map.Entry.comparingByKey())
6404+
.map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue()))
6405+
.collect(Collectors.joining("&"));
6406+
6407+
String key = hmac(parentApiKey, queryStr);
6408+
6409+
return new String(Base64.getEncoder().encode(String.format("%s%s", key, queryStr).getBytes(Charset.forName("UTF8"))));
6410+
}
6411+
6412+
private String hmac(String key, String msg) throws NoSuchAlgorithmException, InvalidKeyException {
6413+
Mac hmac = Mac.getInstance("HmacSHA256");
6414+
hmac.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"));
6415+
byte[] rawHmac = hmac.doFinal(msg.getBytes());
6416+
StringBuilder sb = new StringBuilder(rawHmac.length * 2);
6417+
for (byte b : rawHmac) {
6418+
sb.append(String.format("%02x", b & 0xff));
6419+
}
6420+
return sb.toString();
6421+
}
6422+
6423+
/**
6424+
* Helper: Retrieves the remaining validity of the previous generated `secured_api_key`, the
6425+
* `validUntil` parameter must have been provided.
6426+
*
6427+
* @param securedApiKey The secured API Key to check
6428+
* @throws AlgoliaRuntimeException if <code>securedApiKey</code> is null, empty or whitespaces.
6429+
* @throws AlgoliaRuntimeException if <code>securedApiKey</code> doesn't have a <code>validUntil
6430+
* </code> parameter.
6431+
*/
6432+
public Duration getSecuredApiKeyRemainingValidity(@Nonnull String securedApiKey) {
6433+
if (securedApiKey == null || securedApiKey.trim().isEmpty()) {
6434+
throw new AlgoliaRuntimeException("securedAPIKey must not be empty, null or whitespaces");
6435+
}
6436+
6437+
byte[] decodedBytes = Base64.getDecoder().decode(securedApiKey);
6438+
String decodedString = new String(decodedBytes);
6439+
6440+
Pattern pattern = Pattern.compile("validUntil=\\d+");
6441+
Matcher matcher = pattern.matcher(decodedString);
6442+
6443+
if (!matcher.find()) {
6444+
throw new AlgoliaRuntimeException("The Secured API Key doesn't have a validUntil parameter.");
6445+
}
6446+
6447+
String validUntilMatch = matcher.group(0);
6448+
long timeStamp = Long.parseLong(validUntilMatch.replace("validUntil=", ""));
6449+
6450+
return Duration.ofSeconds(timeStamp - Instant.now().getEpochSecond());
6451+
}
63566452
}

0 commit comments

Comments
 (0)