paypal-sdk-core 0.2.1 → 0.2.2

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2FlZTU2MWY0MmE1ZmVkOTc4YTU0YTBiYzMwYWI1ODdhN2Y5MGNlZQ==
5
+ data.tar.gz: !binary |-
6
+ YTVlMzA0MzY0OWU2ZGU0MDFmOTlmZDljNmY3YTE1ZTUzMjBkOWJmMA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ Mzk3ODAxOTEyZmMyNzdlMzVkMTUyNWRjM2VlMmZhMDk0OGRkYWYzMmRjNDlm
10
+ MGM1ZTdlYTA4Mzk5NzBkOGQzYmM3ZjgxMDU2NWJiMGY1NWVmOWJkNDZlNmYy
11
+ YTBmZWIxMDZkM2YxNGZmYjE1MmY3NWYwNzQzZjI2MTRlM2M0ZDc=
12
+ data.tar.gz: !binary |-
13
+ MTBmMThmZjZhZTRlN2E1N2RjMTIzNzVhNjg2ZDZlMDFkMWZiYmIwNmQyYWU0
14
+ MzVmYTZiZGNmN2QwMTcwZGU1ODVkYjhlNzAzMjRjNmUwNjNjOWUwZTkwMWVj
15
+ YjdjZWUyZTEzMmJiYmE4MTkxODIwMjE1NWExZmRjZjRjNWQyMzc=
data/CHANGELOG.txt ADDED
@@ -0,0 +1,16 @@
1
+ Version 0.2.2 - Apr 25, 2013
2
+ - Validate token expiry duration on every REST API call
3
+ - Removed exception handling for Socket and Timeout errors
4
+ - Added configure and logger methods to PayPal::SDK module
5
+ - Added PayPal:SDK::OpenIDConnect module
6
+
7
+ Version 0.2.1 - Mar 22, 2013
8
+ - Skip values for undefined members on initializer
9
+
10
+ Version 0.1.5 - Jan 28, 2013
11
+ - Fix OrderedHash issue with ruby 1.8.7
12
+
13
+ Version 0.1.4 - Jan 09, 2013
14
+
15
+ - Support ruby version 1.8.7
16
+ - Update IPN Endpoint
@@ -1,2 +1,2 @@
1
- PayPal::SDK::Core::Config.load("config/paypal.yml", Rails.env)
2
- PayPal::SDK::Core::Config.logger = Rails.logger
1
+ PayPal::SDK.load("config/paypal.yml", Rails.env)
2
+ PayPal::SDK.logger = Rails.logger
@@ -1,6 +1,6 @@
1
1
  test: &default
2
2
 
3
- # Credentials for New APIs
3
+ # Credentials for REST APIs
4
4
  client_id: EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM
5
5
  client_secret: EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM
6
6
 
@@ -8,10 +8,10 @@ test: &default
8
8
  mode: sandbox
9
9
 
10
10
  # Credentials for Classic APIs
11
+ app_id: APP-80W284485P519543T
11
12
  username: jb-us-seller_api1.paypal.com
12
13
  password: WX4WTU3S8MY44S7F
13
14
  signature: AFcWxV21C7fd0v3bYYYRCpSSRl31A7yDhhsPUU2XhtMoZXsWHFxu-RWy
14
- app_id: APP-80W284485P519543T
15
15
  # # With Certificate
16
16
  # cert_path: "config/cert_key.pem"
17
17
  sandbox_email_address: Platform.sdk.seller@gmail.com
@@ -8,39 +8,31 @@ module PayPal
8
8
  autoload :Logging, "paypal-sdk/core/logging"
9
9
  autoload :Authentication, "paypal-sdk/core/authentication"
10
10
  autoload :Exceptions, "paypal-sdk/core/exceptions"
11
+ autoload :OpenIDConnect, "paypal-sdk/core/openid_connect"
12
+ autoload :API, "paypal-sdk/core/api"
13
+ autoload :Util, "paypal-sdk/core/util"
14
+ autoload :Credential, "paypal-sdk/core/credential"
11
15
 
12
- module API
13
- autoload :Base, "paypal-sdk/core/api/base"
14
- autoload :Merchant, "paypal-sdk/core/api/merchant"
15
- autoload :Platform, "paypal-sdk/core/api/platform"
16
- autoload :REST, "paypal-sdk/core/api/rest"
17
- autoload :IPN, "paypal-sdk/core/api/ipn"
16
+ end
18
17
 
19
- module DataTypes
20
- autoload :Base, "paypal-sdk/core/api/data_types/base"
21
- autoload :Enum, "paypal-sdk/core/api/data_types/enum"
22
- autoload :SimpleTypes, "paypal-sdk/core/api/data_types/simple_types"
23
- autoload :ArrayWithBlock, "paypal-sdk/core/api/data_types/array_with_block"
24
- end
25
- end
18
+ autoload :OpenIDConnect, "paypal-sdk/core/openid_connect"
26
19
 
27
- module Util
28
- autoload :OauthSignature, "paypal-sdk/core/util/oauth_signature"
29
- autoload :OrderedHash, "paypal-sdk/core/util/ordered_hash"
30
- autoload :HTTPHelper, "paypal-sdk/core/util/http_helper"
20
+ class << self
21
+ def configure(options = {}, &block)
22
+ Core::Config.configure(options, &block)
31
23
  end
32
24
 
33
- module Credential
34
- autoload :Base, "paypal-sdk/core/credential/base"
35
- autoload :Certificate, "paypal-sdk/core/credential/certificate"
36
- autoload :Signature, "paypal-sdk/core/credential/signature"
25
+ def load(*args)
26
+ Core::Config.load(*args)
27
+ end
37
28
 
38
- module ThirdParty
39
- autoload :Token, "paypal-sdk/core/credential/third_party/token"
40
- autoload :Subject, "paypal-sdk/core/credential/third_party/subject"
41
- end
29
+ def logger
30
+ Core::Config.logger
42
31
  end
43
32
 
33
+ def logger=(log)
34
+ Core::Config.logger = log
35
+ end
44
36
  end
45
37
  end
46
38
  end
@@ -0,0 +1,20 @@
1
+ module PayPal
2
+ module SDK
3
+ module Core
4
+ module API
5
+ autoload :Base, "paypal-sdk/core/api/base"
6
+ autoload :Merchant, "paypal-sdk/core/api/merchant"
7
+ autoload :Platform, "paypal-sdk/core/api/platform"
8
+ autoload :REST, "paypal-sdk/core/api/rest"
9
+ autoload :IPN, "paypal-sdk/core/api/ipn"
10
+
11
+ module DataTypes
12
+ autoload :Base, "paypal-sdk/core/api/data_types/base"
13
+ autoload :Enum, "paypal-sdk/core/api/data_types/enum"
14
+ autoload :SimpleTypes, "paypal-sdk/core/api/data_types/simple_types"
15
+ autoload :ArrayWithBlock, "paypal-sdk/core/api/data_types/array_with_block"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -84,8 +84,6 @@ module PayPal::SDK::Core
84
84
  payload[:response] = http_call(payload)
85
85
  format_response(payload)
86
86
  payload[:data]
87
- rescue Net::HTTPBadGateway, Errno::ECONNRESET, Errno::ECONNABORTED, SocketError => error
88
- format_error(error, error.message)
89
87
  end
90
88
 
91
89
  # Generate HTTP request for given action and parameters
@@ -30,7 +30,7 @@ module PayPal::SDK::Core
30
30
  # Clear cached values.
31
31
  def set_config(*args)
32
32
  @token_uri = nil
33
- @token = nil
33
+ @token_hash = nil
34
34
  super
35
35
  end
36
36
 
@@ -45,19 +45,41 @@ module PayPal::SDK::Core
45
45
  end
46
46
 
47
47
  # Generate Oauth token or Get cached
48
- def token
49
- @token ||=
48
+ def token_hash
49
+ validate_token_hash
50
+ @token_hash ||=
50
51
  begin
52
+ @token_request_at = Time.now
51
53
  basic_auth = ["#{config.client_id}:#{config.client_secret}"].pack('m').delete("\r\n")
52
54
  token_headers = default_http_header.merge( "Authorization" => "Basic #{basic_auth}" )
53
55
  response = http_call( :method => :post, :uri => token_uri, :body => TOKEN_REQUEST_PARAMS, :header => token_headers )
54
- MultiJson.load(response.body)["access_token"]
56
+ MultiJson.load(response.body, :symbolize_keys => true)
55
57
  end
56
58
  end
59
+ attr_writer :token_hash
60
+
61
+ # Get access token
62
+ def token
63
+ token_hash[:access_token]
64
+ end
65
+
66
+ # Get access token type
67
+ def token_type
68
+ token_hash[:token_type] || "Bearer"
69
+ end
57
70
 
58
71
  # token setter
59
72
  def token=(new_token)
60
- @token = new_token
73
+ @token_hash = { :access_token => new_token, :token_type => "Bearer" }
74
+ end
75
+
76
+ # Check token expired or not
77
+ def validate_token_hash
78
+ if @token_request_at and
79
+ @token_hash and @token_hash[:expires_in] and
80
+ (Time.now - @token_request_at) > @token_hash[:expires_in].to_i
81
+ @token_hash = nil
82
+ end
61
83
  end
62
84
 
63
85
  # Override the API call to handle Token Expire
@@ -66,9 +88,9 @@ module PayPal::SDK::Core
66
88
  begin
67
89
  response = super(payload)
68
90
  rescue UnauthorizedAccess => error
69
- if @token and config.client_id
91
+ if @token_hash and config.client_id
70
92
  # Reset cached token and Retry api request
71
- @token = nil
93
+ @token_hash = nil
72
94
  response = super(backup_payload)
73
95
  else
74
96
  raise error
@@ -96,7 +118,7 @@ module PayPal::SDK::Core
96
118
  # HTTP Header
97
119
  credential_properties = credential(payload[:uri].to_s).properties
98
120
  header = map_header_value(NVP_AUTH_HEADER, credential_properties)
99
- payload[:header] = header.merge("Authorization" => "Bearer #{token}").
121
+ payload[:header] = header.merge("Authorization" => "#{token_type} #{token}").
100
122
  merge(DEFAULT_HTTP_HEADER).merge(payload[:header])
101
123
  # Post Data
102
124
  payload[:body] = MultiJson.dump(payload[:params])
@@ -121,11 +143,6 @@ module PayPal::SDK::Core
121
143
  payload
122
144
  end
123
145
 
124
- # Formate Exception object
125
- def format_error(exception, message)
126
- { "error" => { "name" => "ERROR", "message" => message, "developer_msg" => exception } }
127
- end
128
-
129
146
  # Log PayPal-Request-Id header
130
147
  def log_http_call(payload)
131
148
  if payload[:header] and payload[:header]["PayPal-Request-Id"]
@@ -73,7 +73,8 @@ module PayPal::SDK::Core
73
73
  :http_timeout, :http_proxy,
74
74
  :device_ipaddress, :sandbox_email_address,
75
75
  :mode, :endpoint, :merchant_endpoint, :platform_endpoint, :ipn_endpoint,
76
- :rest_endpoint, :rest_token_endpoint, :client_id, :client_secret
76
+ :rest_endpoint, :rest_token_endpoint, :client_id, :client_secret,
77
+ :openid_endpoint, :openid_redirect_uri, :openid_client_id, :openid_client_secret
77
78
 
78
79
  alias_method :end_point=, :endpoint=
79
80
  alias_method :end_point, :endpoint
@@ -163,7 +164,7 @@ module PayPal::SDK::Core
163
164
 
164
165
  # Get default environment name
165
166
  def default_environment
166
- @@default_environment ||= ENV['PAYPAL_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'] || ENV['ENV'] || "development"
167
+ @@default_environment ||= ENV['PAYPAL_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'] || "development"
167
168
  end
168
169
 
169
170
  # Set default environment
@@ -171,6 +172,17 @@ module PayPal::SDK::Core
171
172
  @@default_environment = env.to_s
172
173
  end
173
174
 
175
+ def configure(options = {}, &block)
176
+ begin
177
+ self.config.merge!(options)
178
+ rescue Errno::ENOENT
179
+ self.configurations = { default_environment => options }
180
+ end
181
+ block.call(self.config) if block
182
+ self.config
183
+ end
184
+ alias_method :set_config, :configure
185
+
174
186
  # Create or Load Config object based on given environment and configurations.
175
187
  # === Attributes
176
188
  # * <tt>env</tt> (Optional) -- Environment name
@@ -184,12 +196,19 @@ module PayPal::SDK::Core
184
196
  override_configuration = env
185
197
  env = default_environment
186
198
  end
187
- env = (env || default_environment).to_s
188
- raise "Configuration[#{env}] NotFound" unless configurations[env]
189
199
  if override_configuration.nil? or override_configuration.empty?
190
- @@config_cache[env] ||= new configurations[env]
200
+ default_config(env)
201
+ else
202
+ default_config(env).dup.merge!(override_configuration)
203
+ end
204
+ end
205
+
206
+ def default_config(env = nil)
207
+ env = (env || default_environment).to_s
208
+ if configurations[env]
209
+ @@config_cache[env] ||= new(configurations[env])
191
210
  else
192
- new(configurations[env]).merge!(override_configuration)
211
+ raise Exceptions::MissingConfig.new("Configuration[#{env}] NotFound")
193
212
  end
194
213
  end
195
214
 
@@ -0,0 +1,16 @@
1
+ module PayPal
2
+ module SDK
3
+ module Core
4
+ module Credential
5
+ autoload :Base, "paypal-sdk/core/credential/base"
6
+ autoload :Certificate, "paypal-sdk/core/credential/certificate"
7
+ autoload :Signature, "paypal-sdk/core/credential/signature"
8
+
9
+ module ThirdParty
10
+ autoload :Token, "paypal-sdk/core/credential/third_party/token"
11
+ autoload :Subject, "paypal-sdk/core/credential/third_party/subject"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,116 @@
1
+
2
+ module PayPal::SDK
3
+ module Core
4
+ module OpenIDConnect
5
+ autoload :API, "paypal-sdk/core/openid_connect/api"
6
+ autoload :SetAPI, "paypal-sdk/core/openid_connect/set_api"
7
+ autoload :GetAPI, "paypal-sdk/core/openid_connect/get_api"
8
+ autoload :RequestDataType, "paypal-sdk/core/openid_connect/request_data_type"
9
+ autoload :DataTypes, "paypal-sdk/core/openid_connect/data_types"
10
+
11
+ include DataTypes
12
+
13
+ class << self
14
+ def api
15
+ RequestDataType.api
16
+ end
17
+
18
+ def set_config(*args)
19
+ RequestDataType.set_config(*args)
20
+ end
21
+ alias_method :config=, :set_config
22
+
23
+ AUTHORIZATION_URL = "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize"
24
+ ENDSESSION_URL = "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/endsession"
25
+ DEFAULT_SCOPE = "openid"
26
+
27
+ def authorize_url(params = {})
28
+ uri = URI(AUTHORIZATION_URL)
29
+ uri.query = api.encode_www_form({
30
+ :response_type => "code",
31
+ :scope => DEFAULT_SCOPE,
32
+ :client_id => RequestDataType.client_id,
33
+ :redirect_uri => api.config.openid_redirect_uri
34
+ }.merge(params))
35
+ uri.to_s
36
+ end
37
+
38
+ def logout_url(params = {})
39
+ uri = URI(ENDSESSION_URL)
40
+ uri.query = api.encode_www_form({
41
+ :logout => "true",
42
+ :redirect_uri => api.config.openid_redirect_uri
43
+ }.merge(params))
44
+ uri.to_s
45
+ end
46
+ end
47
+
48
+ module DataTypes
49
+ class Tokeninfo < Base
50
+ include RequestDataType
51
+ PATH = "v1/identity/openidconnect/tokenservice"
52
+
53
+ class << self
54
+ def create_from_authorization_code(options, http_header = {})
55
+ options = { :code => options } if options.is_a? String
56
+ options = options.merge( :grant_type => "authorization_code" )
57
+ Tokeninfo.new(api.post(PATH, with_credentials(options), http_header))
58
+ end
59
+ alias_method :create, :create_from_authorization_code
60
+
61
+ def create_from_refresh_token(options, http_header = {})
62
+ options = { :refresh_token => options } if options.is_a? String
63
+ options = options.merge( :grant_type => "refresh_token" )
64
+ Tokeninfo.new(api.post(PATH, with_credentials(options), http_header))
65
+ end
66
+ alias_method :refresh, :create_from_refresh_token
67
+
68
+ def with_credentials(options = {})
69
+ options = options.dup
70
+ [ :client_id, :client_secret ].each do |key|
71
+ options[key] = self.send(key) unless options[key] or options[key.to_s]
72
+ end
73
+ options
74
+ end
75
+
76
+ def authorize_url(options = {})
77
+ OpenIDConnect.authorize_url(options)
78
+ end
79
+ end
80
+
81
+ def refresh(options = {})
82
+ tokeninfo = self.class.refresh({
83
+ :refresh_token => self.refresh_token}.merge(options))
84
+ self.merge!(tokeninfo.to_hash)
85
+ end
86
+
87
+ def userinfo(options = {})
88
+ Userinfo.get({ :access_token => self.access_token }.merge(options))
89
+ end
90
+
91
+ def logout_url(options = {})
92
+ OpenIDConnect.logout_url({ :id_token => self.id_token }.merge(options))
93
+ end
94
+
95
+ end
96
+
97
+ class Userinfo < Base
98
+ include RequestDataType
99
+ PATH = "v1/identity/openidconnect/userinfo"
100
+
101
+ class << self
102
+ def get_userinfo(options = {}, http_header = {})
103
+ options = { :access_token => options } if options.is_a? String
104
+ options = options.merge( :schema => "openid" ) unless options[:schema] or options["schema"]
105
+ Userinfo.new(api.post(PATH, options, http_header))
106
+ end
107
+ alias_method :get, :get_userinfo
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ # Alias for the Core::OpenIDConnect constant
115
+ OpenIDConnect = Core::OpenIDConnect
116
+ end
@@ -0,0 +1,41 @@
1
+ require 'multi_json'
2
+
3
+ module PayPal::SDK
4
+ module Core
5
+ module OpenIDConnect
6
+ class API < Core::API::Base
7
+
8
+ DEFAULT_OPENID_ENDPOINT ="https://api.paypal.com"
9
+
10
+ def initialize(environment = nil, options = {})
11
+ super("", environment, options)
12
+ end
13
+
14
+ def service_endpoint
15
+ self.config.openid_endpoint || DEFAULT_OPENID_ENDPOINT
16
+ end
17
+
18
+ def format_request(payload)
19
+ payload[:uri].path = url_join(payload[:uri].path, payload[:action])
20
+ payload[:body] = encode_www_form(payload[:params]) if payload[:params]
21
+ payload[:header] = {"Content-Type" => "application/x-www-form-urlencoded" }.merge(payload[:header])
22
+ payload
23
+ end
24
+
25
+ def format_response(payload)
26
+ payload[:data] =
27
+ if payload[:response].code >= "200" and payload[:response].code <= "299"
28
+ MultiJson.load(payload[:response].body)
29
+ elsif payload[:response].content_type == "application/json"
30
+ { "error" => MultiJson.load(payload[:response].body) }
31
+ else
32
+ { "error" => { "name" => payload[:response].code, "message" => payload[:response].message,
33
+ "developer_msg" => payload[:response] } }
34
+ end
35
+ payload
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end