@@ -293,3 +293,61 @@ func (c *APIClient) WaitForApiKeyWithContext(
293
293
maxDelay,
294
294
)
295
295
}
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