paypal-permissions 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -2
- data/VERSION +1 -0
- data/lib/paypal/permissions.rb +9 -0
- data/lib/{paypal-permissions → paypal/permissions}/fault_message.rb +6 -6
- data/lib/paypal/permissions/oauth.rb +42 -0
- data/lib/{paypal-permissions → paypal/permissions}/paypal.rb +7 -7
- data/lib/paypal/permissions/version.rb +5 -0
- data/paypal-permissions.gemspec +69 -0
- data/spec/oauth_spec.rb +20 -0
- data/spec/paypal_spec.rb +7 -7
- data/spec/spec_helper.rb +2 -2
- metadata +34 -17
- data/lib/paypal-permissions.rb +0 -9
- data/lib/paypal-permissions/version.rb +0 -3
data/README.md
CHANGED
@@ -9,7 +9,7 @@ Please visit PayPal's [Permissions Service API developer forums](https://www.x.c
|
|
9
9
|
### Step 1: Direct the user to the "Grant Permissions" on PayPal
|
10
10
|
|
11
11
|
~~~~~ ruby
|
12
|
-
paypal =
|
12
|
+
paypal = PayPal::Permissions::Paypal.new( userid, password, signature, application_id, :production )
|
13
13
|
request_data = paypal.request_permissions(
|
14
14
|
[:express_checkout, :direct_payment, :auth_capture, :refund, :transaction_details],
|
15
15
|
'http://localhost/callback_url'
|
@@ -22,7 +22,7 @@ redirect_to request_data[:permissions_url]
|
|
22
22
|
### Step 2: Lookup result to get the final permission token
|
23
23
|
|
24
24
|
~~~~~ ruby
|
25
|
-
paypal =
|
25
|
+
paypal = PayPal::Permissions::Paypal.new( userid, password, signature, application_id, :production )
|
26
26
|
token_data = paypal.get_access_token( params['token'], params['verifier'] )
|
27
27
|
|
28
28
|
# Save token_data[:token] and token_data[:token_secret]
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.2
|
@@ -1,12 +1,12 @@
|
|
1
|
-
module
|
1
|
+
module Paypal::Permissions
|
2
2
|
# Base error class
|
3
3
|
class Error < Exception; end
|
4
4
|
|
5
5
|
# PayPal returned a 500 Internal Server Error. Retry?
|
6
|
-
class InternalServerError <
|
6
|
+
class InternalServerError < ::Paypal::Permissions::Error; end
|
7
7
|
|
8
8
|
# PayPal returned an unexpected error message
|
9
|
-
class UnknownResponse <
|
9
|
+
class UnknownResponse < ::Paypal::Permissions::Error
|
10
10
|
attr_accessor :response_code
|
11
11
|
|
12
12
|
def initialize(response_code, message)
|
@@ -39,7 +39,7 @@ module PaypalPermissions
|
|
39
39
|
@correlation_id = options['correlationId']
|
40
40
|
@build = options['build']
|
41
41
|
@errors = collect_errors(options)
|
42
|
-
|
42
|
+
|
43
43
|
@message = @ack
|
44
44
|
end
|
45
45
|
|
@@ -47,9 +47,9 @@ module PaypalPermissions
|
|
47
47
|
def collect_errors(options={})
|
48
48
|
errors = []
|
49
49
|
error_number = 0
|
50
|
-
|
50
|
+
|
51
51
|
while options["error(#{error_number}).errorId"]
|
52
|
-
errors <<
|
52
|
+
errors << ::Paypal::Permissions::FaultMessage::ErrorInformation.new(options, error_number)
|
53
53
|
error_number = error_number + 1
|
54
54
|
end
|
55
55
|
errors
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'openssl'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Paypal::Permissions
|
6
|
+
module Oauth
|
7
|
+
|
8
|
+
# Note: OAuth does not encode '.', but PayPal does.
|
9
|
+
OAUTH_RESERVED_CHARACTERS = /[^a-zA-Z0-9\_]/
|
10
|
+
OAUTH_SIGNATURE_METHOD = 'HMAC-SHA1'
|
11
|
+
|
12
|
+
# Create the X-PP-AUTHORIZATION header
|
13
|
+
def generate_signature(token, token_secret, http_method, endpoint)
|
14
|
+
raise "Invalid HTTP Method. Valid values: GET, POST, DELETE, UPDATE." unless ['GET','POST','DELETE','UPDATE'].include? http_method
|
15
|
+
|
16
|
+
timestamp = Time.now.to_i.to_s
|
17
|
+
signature_key = "#{@password}&#{oauth_escape(token_secret)}"
|
18
|
+
|
19
|
+
oauth_params = {
|
20
|
+
'oauth_consumer_key' => @userid,
|
21
|
+
'oauth_signature_method' => OAUTH_SIGNATURE_METHOD,
|
22
|
+
'oauth_timestamp' => timestamp,
|
23
|
+
'oauth_token' => token,
|
24
|
+
'oauth_version' => '1.0',
|
25
|
+
}
|
26
|
+
|
27
|
+
input_string = "#{http_method}&#{oauth_escape(endpoint)}&"
|
28
|
+
input_string += oauth_params.map{ |k,v| "#{k}=#{v}" }.join('&')
|
29
|
+
|
30
|
+
# HMAC SHA1
|
31
|
+
digest_key = ::Digest::SHA1.digest(signature_key)
|
32
|
+
sha1_hash = ::OpenSSL::Digest::Digest.new('sha1')
|
33
|
+
signature = ::OpenSSL::HMAC.hexdigest(sha1_hash, digest_key, input_string)
|
34
|
+
|
35
|
+
"timestamp=#{timestamp},token=#{token},signature=#{signature}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def oauth_escape(value)
|
39
|
+
URI::escape(value.to_s, OAUTH_RESERVED_CHARACTERS)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -3,7 +3,7 @@ require 'net/https'
|
|
3
3
|
require 'uri'
|
4
4
|
require 'cgi'
|
5
5
|
|
6
|
-
module
|
6
|
+
module Paypal::Permissions
|
7
7
|
class Paypal
|
8
8
|
include Oauth
|
9
9
|
|
@@ -61,7 +61,7 @@ module PaypalPermissions
|
|
61
61
|
permissions_scopes.each_with_index { |ps,index| request_data["scope(#{index})"] = PERMISSIONS[ps] }
|
62
62
|
data = call(url, request_data)
|
63
63
|
|
64
|
-
raise
|
64
|
+
raise ::Paypal::Permissions::FaultMessage.new(data) unless data['token']
|
65
65
|
|
66
66
|
# Redirect URL:
|
67
67
|
# https://www.paypal.com/cgi-bin/webscr?cmd=_grant-permission&request_token= + token
|
@@ -77,7 +77,7 @@ module PaypalPermissions
|
|
77
77
|
url = create_url('GetAccessToken')
|
78
78
|
data = call(url, { 'token' => token, 'verifier' => verifier })
|
79
79
|
|
80
|
-
raise
|
80
|
+
raise ::Paypal::Permissions::FaultMessage.new(data) unless (data['token'] && data['tokenSecret'])
|
81
81
|
|
82
82
|
{
|
83
83
|
token: data['token'],
|
@@ -92,7 +92,7 @@ module PaypalPermissions
|
|
92
92
|
data = call(url, { 'token' => token })
|
93
93
|
|
94
94
|
paypal_scopes = parse_scopes(data)
|
95
|
-
raise
|
95
|
+
raise ::Paypal::Permissions::FaultMessage.new(data) if paypal_scopes.empty?
|
96
96
|
|
97
97
|
{ scopes: paypal_scopes }
|
98
98
|
end
|
@@ -135,12 +135,12 @@ module PaypalPermissions
|
|
135
135
|
case code.to_i
|
136
136
|
when 200
|
137
137
|
data = get_hash(response.body)
|
138
|
-
raise
|
138
|
+
raise ::Paypal::Permissions::FaultMessage.new(data) if data['responseEnvelope.ack'] == 'Failure'
|
139
139
|
return data
|
140
140
|
when 500
|
141
|
-
raise
|
141
|
+
raise ::Paypal::Permissions::InternalServerError.new(response.body)
|
142
142
|
else
|
143
|
-
raise
|
143
|
+
raise ::Paypal::Permissions::UnknownResponse.new(code.to_i, response.body)
|
144
144
|
end
|
145
145
|
end
|
146
146
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{paypal-permissions}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Isaac Hall"]
|
12
|
+
s.date = %q{2011-07-30}
|
13
|
+
s.description = %q{Ruby implementation of the PayPal Permissions API.}
|
14
|
+
s.email = %q{isaac@isaachall.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"lib/paypal-permissions/fault_message.rb",
|
27
|
+
"lib/paypal-permissions/paypal.rb",
|
28
|
+
"lib/paypal-permissions/version.rb",
|
29
|
+
"lib/paypal-permissions.rb",
|
30
|
+
"spec/paypal_spec.rb",
|
31
|
+
"spec/spec_helper.rb",
|
32
|
+
"spec/vcr/cancel_permission.yml",
|
33
|
+
"spec/vcr/cancel_permission_invalid.yml",
|
34
|
+
"spec/vcr/get_access_token_valid.yml",
|
35
|
+
"spec/vcr/lookup_permissions_multiple.yml",
|
36
|
+
"spec/vcr/request_permissions_multiple.yml",
|
37
|
+
"spec/vcr/request_permissions_single.yml"
|
38
|
+
]
|
39
|
+
s.homepage = %q{http://github.com/isaachall/paypal-permissions}
|
40
|
+
s.licenses = ["MIT"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.rubygems_version = %q{1.6.2}
|
43
|
+
s.summary = %q{Ruby implementation of the PayPal Permissions API.}
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<httpclient>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
51
|
+
s.add_development_dependency(%q<rspec>, ["> 2.0.0"])
|
52
|
+
s.add_development_dependency(%q<vcr>, [">= 0"])
|
53
|
+
s.add_development_dependency(%q<webmock>, [">= 0"])
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<httpclient>, [">= 0"])
|
56
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
57
|
+
s.add_dependency(%q<rspec>, ["> 2.0.0"])
|
58
|
+
s.add_dependency(%q<vcr>, [">= 0"])
|
59
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<httpclient>, [">= 0"])
|
63
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
64
|
+
s.add_dependency(%q<rspec>, ["> 2.0.0"])
|
65
|
+
s.add_dependency(%q<vcr>, [">= 0"])
|
66
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/spec/oauth_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Paypal::Permissions
|
4
|
+
describe Oauth do
|
5
|
+
before(:each) do
|
6
|
+
@api_key = 'user.test.com'
|
7
|
+
@secret = '1234567890'
|
8
|
+
@token = '1234567890123456789012345678901234567890'
|
9
|
+
@token_secret = '1234567890'
|
10
|
+
@http_method = 'POST'
|
11
|
+
@endpoint = 'https://api.paypal.com/nvp'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should calculate a X-PP-AUTHORIZATION signature" do
|
15
|
+
Time.stub!(:now).and_return '1311832612'
|
16
|
+
sig = @paypal.generate_signature(@token, @token_secret, @http_method, @endpoint)
|
17
|
+
sig.should == 'timestamp=1311832612,token=1234567890123456789012345678901234567890,signature=d6da5d66e0f33ca7415b420cedf6b7286f05cba3'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/paypal_spec.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module
|
3
|
+
module Paypal::Permissions
|
4
4
|
describe Paypal do
|
5
5
|
it "should request permissions with multiple scopes" do
|
6
6
|
VCR.use_cassette("request_permissions_multiple") do
|
7
7
|
permission_data = @paypal.request_permissions(
|
8
|
-
[:express_checkout, :direct_payment, :auth_capture, :refund, :transaction_details],
|
8
|
+
[:express_checkout, :direct_payment, :auth_capture, :refund, :transaction_details],
|
9
9
|
'http://localhost/')
|
10
10
|
|
11
11
|
permission_data[:token].should == 'AAAAAAATmjdbA3ADelJ6'
|
12
12
|
permission_data[:permissions_url].should == 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_grant-permission&request_token=' + permission_data[:token]
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "should request permissions with a single scopes" do
|
17
17
|
VCR.use_cassette("request_permissions_single") do
|
18
18
|
permission_data = @paypal.request_permissions(
|
19
|
-
[:express_checkout],
|
19
|
+
[:express_checkout],
|
20
20
|
'http://localhost/')
|
21
|
-
|
21
|
+
|
22
22
|
permission_data[:token].should == 'AAAAAAATmnP2wcRCp7Mc'
|
23
23
|
permission_data[:permissions_url].should == 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_grant-permission&request_token=' + permission_data[:token]
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it "should get an access token" do
|
28
28
|
VCR.use_cassette("get_access_token_valid") do
|
29
29
|
access_data = @paypal.get_access_token('AAAAAAATmjdbA3ADelJ6','KVTI4zbTe.QW07vOqPpqYg')
|
@@ -55,7 +55,7 @@ module PaypalPermissions
|
|
55
55
|
VCR.use_cassette("cancel_permission_invalid") do
|
56
56
|
@paypal.cancel_permissions('M-RTGNyaZP5OMNIUxkH29I53eFvQhTJk3UfByH4pWfjSQHlj5csUVA')
|
57
57
|
end
|
58
|
-
}.should raise_error(
|
58
|
+
}.should raise_error(::Paypal::Permissions::FaultMessage)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,7 +6,7 @@ require 'vcr'
|
|
6
6
|
Bundler.setup
|
7
7
|
|
8
8
|
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
9
|
-
require 'paypal
|
9
|
+
require 'paypal/permissions'
|
10
10
|
|
11
11
|
module SpecHelper
|
12
12
|
# add helper methods here
|
@@ -19,7 +19,7 @@ RSpec.configure do |config|
|
|
19
19
|
|
20
20
|
config.before(:all) do
|
21
21
|
credentials = YAML.load(File.read(File.join(File.dirname(__FILE__), 'sandbox_credentials.yml')))
|
22
|
-
@paypal =
|
22
|
+
@paypal = Paypal::Permissions::Paypal.new(
|
23
23
|
credentials['userid'], credentials['password'],credentials['signature'],credentials['application_id'],credentials['mode']
|
24
24
|
)
|
25
25
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paypal-permissions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-06-30 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httpclient
|
16
|
-
requirement: &
|
16
|
+
requirement: &70223949740140 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70223949740140
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: jeweler
|
27
|
-
requirement: &
|
27
|
+
requirement: &70223949739440 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,21 @@ dependencies:
|
|
32
32
|
version: 1.6.4
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70223949739440
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: httpclient
|
38
|
+
requirement: &70223949738780 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70223949738780
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: rspec
|
38
|
-
requirement: &
|
49
|
+
requirement: &70223949738260 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>'
|
@@ -43,10 +54,10 @@ dependencies:
|
|
43
54
|
version: 2.0.0
|
44
55
|
type: :development
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *70223949738260
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: vcr
|
49
|
-
requirement: &
|
60
|
+
requirement: &70223949737500 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,10 +65,10 @@ dependencies:
|
|
54
65
|
version: '0'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *70223949737500
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: webmock
|
60
|
-
requirement: &
|
71
|
+
requirement: &70223949736780 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,7 +76,7 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *70223949736780
|
69
80
|
description: Ruby implementation of the PayPal Permissions API.
|
70
81
|
email: isaac@isaachall.com
|
71
82
|
executables: []
|
@@ -80,10 +91,14 @@ files:
|
|
80
91
|
- LICENSE.txt
|
81
92
|
- README.md
|
82
93
|
- Rakefile
|
83
|
-
-
|
84
|
-
- lib/paypal
|
85
|
-
- lib/paypal
|
86
|
-
- lib/paypal
|
94
|
+
- VERSION
|
95
|
+
- lib/paypal/permissions.rb
|
96
|
+
- lib/paypal/permissions/fault_message.rb
|
97
|
+
- lib/paypal/permissions/oauth.rb
|
98
|
+
- lib/paypal/permissions/paypal.rb
|
99
|
+
- lib/paypal/permissions/version.rb
|
100
|
+
- paypal-permissions.gemspec
|
101
|
+
- spec/oauth_spec.rb
|
87
102
|
- spec/paypal_spec.rb
|
88
103
|
- spec/spec_helper.rb
|
89
104
|
- spec/vcr/cancel_permission.yml
|
@@ -105,6 +120,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
120
|
- - ! '>='
|
106
121
|
- !ruby/object:Gem::Version
|
107
122
|
version: '0'
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
hash: -952150860121832261
|
108
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
127
|
none: false
|
110
128
|
requirements:
|
@@ -118,4 +136,3 @@ signing_key:
|
|
118
136
|
specification_version: 3
|
119
137
|
summary: Ruby implementation of the PayPal Permissions API.
|
120
138
|
test_files: []
|
121
|
-
has_rdoc:
|
data/lib/paypal-permissions.rb
DELETED