diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb index b3780223..7c38e35a 100644 --- a/lib/oauth2/client.rb +++ b/lib/oauth2/client.rb @@ -4,6 +4,8 @@ module OAuth2 # The OAuth2::Client class class Client # rubocop:disable Metrics/ClassLength + RESERVED_PARAM_KEYS = ['headers', 'parse'].freeze + attr_reader :id, :secret, :site attr_accessor :options attr_writer :connection @@ -132,7 +134,16 @@ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, Method # @param [Hash] access token options, to pass to the AccessToken object # @param [Class] class of access token for easier subclassing OAuth2::AccessToken # @return [AccessToken] the initialized AccessToken - def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength + def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + params = params.map do |key, value| + if RESERVED_PARAM_KEYS.include?(key) + [key.to_sym, value] + else + [key, value] + end + end + params = Hash[params] + params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params) opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)} headers = params.delete(:headers) || {} diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb index 62cb4ec2..f045e044 100644 --- a/spec/oauth2/client_spec.rb +++ b/spec/oauth2/client_spec.rb @@ -157,6 +157,68 @@ client.auth_code.get_token('code') end end + + describe 'custom headers' do + context 'string key headers' do + it 'adds the custom headers to request' do + client = described_class.new('abc', 'def', :site => 'https://api.example.com', :auth_scheme => :request_body) do |builder| + builder.adapter :test do |stub| + stub.post('/oauth/token') do |env| + expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'}) + [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}'] + end + end + end + header_params = {'headers' => { 'CustomHeader' => 'CustomHeader' }} + client.auth_code.get_token('code', header_params) + end + end + + context 'symbol key headers' do + it 'adds the custom headers to request' do + client = described_class.new('abc', 'def', :site => 'https://api.example.com', :auth_scheme => :request_body) do |builder| + builder.adapter :test do |stub| + stub.post('/oauth/token') do |env| + expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'}) + [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}'] + end + end + end + header_params = {headers: { 'CustomHeader' => 'CustomHeader' }} + client.auth_code.get_token('code', header_params) + end + end + + context 'string key custom headers with basic auth' do + it 'adds the custom headers to request' do + client = described_class.new('abc', 'def', :site => 'https://api.example.com') do |builder| + builder.adapter :test do |stub| + stub.post('/oauth/token') do |env| + expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'}) + [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}'] + end + end + end + header_params = {'headers' => { 'CustomHeader' => 'CustomHeader' }} + client.auth_code.get_token('code', header_params) + end + end + + context 'symbol key custom headers with basic auth' do + it 'adds the custom headers to request' do + client = described_class.new('abc', 'def', :site => 'https://api.example.com') do |builder| + builder.adapter :test do |stub| + stub.post('/oauth/token') do |env| + expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'}) + [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}'] + end + end + end + header_params = {headers: { 'CustomHeader' => 'CustomHeader' }} + client.auth_code.get_token('code', header_params) + end + end + end end describe '#request' do