Skip to content

Commit

Permalink
feat(clients): add generate_secured_api_key to ruby (#3166)
Browse files Browse the repository at this point in the history
  • Loading branch information
millotp authored Jun 12, 2024
1 parent 2181ca5 commit b2a464a
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ def self.encode_uri(uri)
CGI.escape(uri).gsub('+', '%20')
end

def self.stringify_query_params(query_params)
query_params.to_h do |key, value|
value = value.join(',') if value.is_a?(Array)
[encode_uri(key.to_s).to_sym, encode_uri(value.to_s)]
end
end

class Transport
include RetryOutcomeType
include CallType
Expand Down Expand Up @@ -79,7 +86,7 @@ def build_request(method, path, body, request_options)
request[:method] = method.downcase
request[:path] = path
request[:body] = build_body(body, request_options)
request[:query_params] = stringify_query_params(request_options.query_params)
request[:query_params] = Algolia::Transport.stringify_query_params(request_options.query_params)
request[:header_params] = generate_header_params(body, request_options)
request[:timeout] = request_options.timeout
request[:connect_timeout] = request_options.connect_timeout
Expand Down Expand Up @@ -128,13 +135,6 @@ def get_timeout(call_type)
@config.write_timeout
end
end

def stringify_query_params(query_params)
query_params.to_h do |key, value|
value = value.join(',') if value.is_a?(Array)
[Algolia::Transport.encode_uri(key.to_s).to_sym, Algolia::Transport.encode_uri(value.to_s)]
end
end
end
end
end
5 changes: 5 additions & 0 deletions templates/ruby/api.mustache
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# {{{generationBanner}}}

{{#isSearchClient}}
require 'openssl'
require 'base64'
{{/isSearchClient}}

module {{moduleName}}
{{#operations}}
class {{classname}}
Expand Down
48 changes: 48 additions & 0 deletions templates/ruby/search_helpers.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,51 @@ def browse_synonyms(index_name, search_synonyms_params = Search::SearchSynonymsP

synonyms unless block_given?
end

# Helper: Generates a secured API key based on the given `parent_api_key` and given `restrictions`.
#
# @param parent_api_key [String] Parent API key used the generate the secured key
# @param restrictions [SecuredApiKeyRestrictions] Restrictions to apply on the secured key
#
# @return [String]
#
def generate_secured_api_key(parent_api_key, restrictions = {})
restrictions = restrictions.to_hash
if restrictions.key?(:searchParams)
# merge searchParams with the root of the restrictions

restrictions.merge!(restrictions[:searchParams])
restrictions.delete(:searchParams)
end

url_encoded_restrictions = Algolia::Transport.stringify_query_params(restrictions).sort.to_h.map do |key, value|
"#{key}=#{value}"
end.join('&')

hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), parent_api_key, url_encoded_restrictions)

puts "hmac: #{hmac}"
puts "url_encoded_restrictions: #{url_encoded_restrictions}"
Base64.encode64("#{hmac}#{url_encoded_restrictions}").gsub("\n", '')
end

# Helper: Retrieves the remaining validity of the previous generated `secured_api_key`, the `validUntil` parameter must have been provided.
#
# @param secured_api_key [String]
#
# @return [Integer]
#
def get_secured_api_key_remaining_validity(secured_api_key)
now = Time.now.to_i
decoded_key = Base64.decode64(secured_api_key)
regex = 'validUntil=(\d+)'
matches = decoded_key.match(regex)

if matches.nil?
raise AlgoliaError, 'The SecuredApiKey doesn\'t have a validUntil parameter.'
end

valid_until = matches[1].to_i

valid_until - now
end

1 comment on commit b2a464a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.