tlconnor-activemerchant 1.23.2 → 1.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ require 'cgi'
1
2
  require 'openssl'
2
3
  require 'base64'
3
4
  module ActiveMerchant #:nodoc:
@@ -65,21 +66,18 @@ module ActiveMerchant #:nodoc:
65
66
  def initialize(options = {})
66
67
  requires!(options, :login, :password)
67
68
 
68
- headers = if options[:access_token]
69
- access_token = options.delete(:access_token)
70
- access_secret = options.delete(:access_secret)
71
-
72
- {'X-PAYPAL-AUTHORIZATION' => x_pp_authorization_header(options[:login], options[:password], access_token, access_secret)}
73
- else
74
- {}
75
- end
69
+ access_token = options.delete(:access_token)
70
+ access_secret = options.delete(:access_secret)
76
71
 
77
72
  @options = {
78
73
  :pem => pem_file,
79
74
  :signature => signature,
80
- :headers => headers || {}
75
+ :headers => {}
81
76
  }.update(options)
82
77
 
78
+ if access_token
79
+ @options[:headers] = {'X-PAYPAL-AUTHORIZATION' => x_pp_authorization_header(endpoint_url, options[:login], options[:password], access_token, access_secret)}
80
+ end
83
81
 
84
82
  if @options[:pem].blank? && @options[:signature].blank?
85
83
  raise ArgumentError, "An API Certificate or API Signature is required to make requests to PayPal"
@@ -87,7 +85,7 @@ module ActiveMerchant #:nodoc:
87
85
 
88
86
  super
89
87
  end
90
-
88
+
91
89
  def test?
92
90
  @options[:test] || Base.gateway_mode == :test
93
91
  end
@@ -646,39 +644,53 @@ module ActiveMerchant #:nodoc:
646
644
  (date.is_a?(Date) ? date.to_time : date).utc.iso8601
647
645
  end
648
646
 
649
- def x_pp_authorization_header(login, password, access_token, access_secret)
647
+ def x_pp_authorization_header(url, api_user_id, api_password, access_token, access_token_verifier)
650
648
  timestamp = Time.now.to_i.to_s
651
- signature = x_pp_authorization_signature(timestamp, login, password, access_token, access_secret)
649
+ signature = x_pp_authorization_signature url, api_user_id, api_password, timestamp, access_token, access_token_verifier
652
650
  "token=#{access_token},signature=#{signature},timestamp=#{timestamp}"
653
651
  end
654
652
 
655
- def x_pp_authorization_signature(timestamp, login, password, access_token, access_secret)
653
+ def x_pp_authorization_signature(url, api_user_id, api_password, timestamp, access_token, access_token_verifier)
656
654
  # no query params, but if there were, this is where they'd go
657
655
  query_params = {}
658
656
  key = [
659
- URI.encode(password),
660
- URI.encode(access_secret),
657
+ paypal_encode(api_password),
658
+ paypal_encode(access_token_verifier),
661
659
  ].join("&")
662
660
 
663
661
  params = query_params.dup.merge({
664
- "oauth_consumer_key" => login,
662
+ "oauth_consumer_key" => api_user_id,
665
663
  "oauth_version" => "1.0",
666
664
  "oauth_signature_method" => "HMAC-SHA1",
667
665
  "oauth_token" => access_token,
668
666
  "oauth_timestamp" => timestamp,
669
667
  })
670
- sorted_params = Hash[params.sort]
671
- sorted_query_string = sorted_params.to_query
668
+ sorted_query_string = params.collect do |key, value|
669
+ "#{key}=#{value}"
670
+ end.sort * '&'
672
671
 
673
672
  base = [
674
673
  "POST",
675
- URI.encode(endpoint_url),
676
- URI.encode(sorted_query_string)
674
+ paypal_encode(url),
675
+ paypal_encode(sorted_query_string)
677
676
  ].join("&")
677
+ base = base.gsub /%([0-9A-F])([0-9A-F])/ do
678
+ "%#{$1.downcase}#{$2.downcase}" # hack to match PayPal Java SDK bit for bit
679
+ end
678
680
 
679
- hexdigest = OpenSSL::HMAC.hexdigest('sha1', key, base)
680
- Base64.encode64(hexdigest).chomp
681
- end
681
+ digest = OpenSSL::HMAC.digest('sha1', key, base)
682
+ Base64.encode64(digest).chomp
683
+ end
684
+
685
+ # The PayPalURLEncoder java class percent encodes everything other than 'a-zA-Z0-9 _'.
686
+ # Then it converts ' ' to '+'.
687
+ # Ruby's CGI.encode takes care of the ' ' and '*' to satisfy PayPal
688
+ # (but beware, URI.encode percent encodes spaces, and does nothing with '*').
689
+ # Finally, CGI.encode does not encode '.-', which we need to do here.
690
+ def paypal_encode(str)
691
+ s = str.dup
692
+ CGI.escape(s).gsub('.', '%2E').gsub('-', '%2D')
693
+ end
682
694
  end
683
695
  end
684
696
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = "1.23.2"
2
+ VERSION = "1.23.3"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tlconnor-activemerchant
3
3
  version: !ruby/object:Gem::Version
4
- hash: 79
4
+ hash: 77
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 23
9
- - 2
10
- version: 1.23.2
9
+ - 3
10
+ version: 1.23.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tobias Luetke