paypal-sdk-core 0.2.1 → 0.2.2

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