tlconnor-activemerchant 1.23.2 → 1.23.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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