Skip to content

Commit 24d37fe

Browse files
committed
feat(go): add generateSecuredApiKey helper
1 parent 608fd29 commit 24d37fe

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

templates/go/api.mustache

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import (
1414
"slices"
1515
"time"
1616
"github.com/algolia/algoliasearch-client-go/v4/algolia/errs"
17+
"crypto/hmac"
18+
"crypto/sha256"
19+
"encoding/base64"
20+
"encoding/hex"
1721
{{/isSearchClient}}
1822

1923
"github.com/algolia/algoliasearch-client-go/v4/algolia/utils"

templates/go/search_helpers.mustache

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,61 @@ func (c *APIClient) WaitForApiKeyWithContext(
293293
maxDelay,
294294
)
295295
}
296+
297+
// GenerateSecuredApiKey generates a public API key intended to restrict access
298+
// to certain records. This new key is built upon the existing key named
299+
// `parentApiKey` and the following options:
300+
func (c *APIClient) GenerateSecuredApiKey(parentApiKey string, restrictions *SecuredAPIKeyRestrictions) (string, error) {
301+
h := hmac.New(sha256.New, []byte(parentApiKey))
302+
303+
message, err := encodeRestrictions(restrictions)
304+
if err != nil {
305+
return "", err
306+
}
307+
_, err = h.Write([]byte(message))
308+
if err != nil {
309+
return "", fmt.Errorf("failed to compute HMAC: %w", err)
310+
}
311+
312+
checksum := hex.EncodeToString(h.Sum(nil))
313+
key := base64.StdEncoding.EncodeToString([]byte(checksum + message))
314+
315+
return key, nil
316+
}
317+
318+
func encodeRestrictions(restrictions *SecuredAPIKeyRestrictions) (string, error) {
319+
toSerialize := map[string]any{}
320+
if restrictions.Filters != nil {
321+
toSerialize["filters"] = restrictions.Filters
322+
}
323+
if restrictions.ValidUntil != nil {
324+
toSerialize["validUntil"] = restrictions.ValidUntil
325+
}
326+
if restrictions.RestrictIndices != nil {
327+
toSerialize["restrictIndices"] = restrictions.RestrictIndices
328+
}
329+
if restrictions.RestrictSources != nil {
330+
toSerialize["restrictSources"] = restrictions.RestrictSources
331+
}
332+
if restrictions.UserToken != nil {
333+
toSerialize["userToken"] = restrictions.UserToken
334+
}
335+
if restrictions.SearchParams != nil {
336+
// merge with searchParams
337+
serializedParams, err := restrictions.SearchParams.MarshalJSON()
338+
if err != nil {
339+
return "", fmt.Errorf("failed to marshal SearchParams: %w", err)
340+
}
341+
err = json.Unmarshal(serializedParams, &toSerialize)
342+
if err != nil {
343+
return "", fmt.Errorf("failed to unmarshal SearchParams: %w", err)
344+
}
345+
}
346+
347+
queryString := make([]string, 0, len(toSerialize))
348+
for k, v := range toSerialize {
349+
queryString = append(queryString, k+"="+queryParameterToString(v))
350+
}
351+
352+
return strings.Join(queryString, "&"), nil
353+
}

0 commit comments

Comments
 (0)