recurly 0.4.11 → 0.4.13
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of recurly might be problematic. Click here for more details.
- data/README.md +4 -8
- data/lib/recurly.rb +10 -19
- data/lib/recurly/config_parser.rb +5 -2
- data/lib/recurly/plan.rb +0 -1
- data/lib/recurly/rails3/recurly.rake +10 -26
- data/lib/recurly/transparent.rb +2 -0
- data/lib/recurly/verification.rb +14 -8
- data/lib/recurly/version.rb +1 -1
- data/spec/config/recurly.yml +3 -3
- data/spec/config/test1.yml +1 -3
- data/spec/config/test2.yml +2 -6
- data/spec/unit/config_spec.rb +9 -16
- data/spec/unit/transparent_spec.rb +0 -20
- data/spec/unit/verification_spec.rb +15 -9
- data/spec/vcr/account/accept-language-account/1313708721.yml +52 -31
- data/spec/vcr/account/close/1313708721.yml +107 -79
- data/spec/vcr/account/create-blank/1313708721.yml +37 -26
- data/spec/vcr/account/create-duplicate/1313708721.yml +83 -54
- data/spec/vcr/account/create-min/1313708721.yml +48 -30
- data/spec/vcr/account/create/1313708721.yml +52 -31
- data/spec/vcr/account/find/1313708721.yml +111 -81
- data/spec/vcr/account/list/1313708721.yml +1148 -719
- data/spec/vcr/account/update/1313708721.yml +182 -124
- data/spec/vcr/billing/create/1313708721.yml +156 -93
- data/spec/vcr/billing/destroy/1313708721.yml +198 -135
- data/spec/vcr/billing/errors/1313708721.yml +91 -56
- data/spec/vcr/billing/find/1313708721.yml +200 -122
- data/spec/vcr/billing/update/1313708721.yml +218 -126
- data/spec/vcr/charge/create/1313708721.yml +189 -120
- data/spec/vcr/charge/delete-uninvoiced/1313708721.yml +195 -154
- data/spec/vcr/charge/list-all/1313708721.yml +235 -157
- data/spec/vcr/charge/list-invoiced/1313708721.yml +351 -234
- data/spec/vcr/charge/list-pending/1313708721.yml +235 -159
- data/spec/vcr/charge/lookup/1313708721.yml +127 -87
- data/spec/vcr/coupon/create/1296774903.yml +83 -95
- data/spec/vcr/coupon/destroy/1296774903.yml +81 -115
- data/spec/vcr/credit/create/1313708090.yml +127 -87
- data/spec/vcr/credit/delete/1313708090.yml +169 -129
- data/spec/vcr/credit/list/1313708090.yml +235 -157
- data/spec/vcr/credit/lookup/1313708090.yml +127 -87
- data/spec/vcr/invoice/create-no-charges/1296674173.yml +140 -89
- data/spec/vcr/invoice/create/1296674173.yml +259 -162
- data/spec/vcr/invoice/list/1296674173.yml +342 -227
- data/spec/vcr/invoice/lookup/1296674173.yml +260 -167
- data/spec/vcr/plan/all.yml +206 -198
- data/spec/vcr/plan/find.yml +109 -103
- data/spec/vcr/plan/update.yml +126 -93
- data/spec/vcr/subscription/addons/add/1296674173.yml +156 -261
- data/spec/vcr/subscription/addons/create/1296674173.yml +156 -164
- data/spec/vcr/subscription/addons/remove/1296674173.yml +156 -249
- data/spec/vcr/subscription/cancel-with-code/1296674173.yml +340 -243
- data/spec/vcr/subscription/cancel/1296674173.yml +297 -210
- data/spec/vcr/subscription/change1/1296674173.yml +303 -213
- data/spec/vcr/subscription/change2/1296674173.yml +303 -214
- data/spec/vcr/subscription/create/1296674173.yml +167 -111
- data/spec/vcr/subscription/find/1296674173.yml +210 -145
- data/spec/vcr/subscription/reactivate/1296674173.yml +318 -233
- data/spec/vcr/subscription/refund-full/1296674173.yml +277 -199
- data/spec/vcr/subscription/refund-none/1296674173.yml +277 -199
- data/spec/vcr/subscription/refund-partial/1296674173.yml +277 -199
- data/spec/vcr/transaction/all/1311126815.yml +388 -206
- data/spec/vcr/transaction/create-no-account/1311126815.yml +74 -43
- data/spec/vcr/transaction/create-with-account/1311126815.yml +172 -101
- data/spec/vcr/transaction/list-filled/1311126815.yml +486 -291
- data/spec/vcr/transaction/list-initial/1311126815.yml +159 -98
- data/spec/vcr/transaction/lookup/1311126815.yml +420 -268
- data/spec/vcr/transaction/void/1311126815.yml +280 -174
- metadata +109 -77
- data/spec/vcr/transaction/refund/1311126815.yml +0 -163
- data/spec/vcr/transparent/post-url/1311239470.yml +0 -76
data/README.md
CHANGED
@@ -16,7 +16,7 @@ Installation
|
|
16
16
|
|
17
17
|
**Stable Version:**
|
18
18
|
|
19
|
-
gem 'recurly'
|
19
|
+
gem 'recurly', '~> 0.4.11'
|
20
20
|
|
21
21
|
**Bleeding Edge Version:**
|
22
22
|
|
@@ -37,10 +37,8 @@ Setup (Rails 2 and other frameworks)
|
|
37
37
|
Alternatively, if not using Rails 3, just make sure to call a Recurly configure block somewhere in your applications initialization.
|
38
38
|
|
39
39
|
Recurly.configure do |c|
|
40
|
-
c.
|
41
|
-
c.password = 'your_api_key'
|
40
|
+
c.api_key = 'your_api_key'
|
42
41
|
c.private_key = 'your_private_key'
|
43
|
-
c.environment = :production # or :sandbox for test sites
|
44
42
|
c.subdomain = 'your-recurly-subdomain'
|
45
43
|
end
|
46
44
|
|
@@ -48,7 +46,7 @@ In Rails 2.x, this code should be in config/initializers/recurly.rb
|
|
48
46
|
|
49
47
|
In Sinatra, it should be within a `configure` block.
|
50
48
|
|
51
|
-
**Please Note:** the setup parameters changed in version 0.4.0.
|
49
|
+
**Please Note:** the setup parameters changed in version 0.4.0. Additional configuration options were also added for the [Transparent Post API](http://docs.recurly.com/transparent-post/basics).
|
52
50
|
|
53
51
|
Manual Setup via YAML or JSON
|
54
52
|
--------------
|
@@ -58,10 +56,8 @@ You can also configure Recurly via a YAML file by using:
|
|
58
56
|
|
59
57
|
The Recurly Configuration YAML is in the format of:
|
60
58
|
|
61
|
-
|
62
|
-
password: your_api_key
|
59
|
+
api_key: your_api_key
|
63
60
|
private_key: your_private_key
|
64
|
-
environment: :production
|
65
61
|
subdomain: your_recurly_subdomain
|
66
62
|
|
67
63
|
|
data/lib/recurly.rb
CHANGED
@@ -41,7 +41,7 @@ module Recurly
|
|
41
41
|
autoload :Verification, 'recurly/verification'
|
42
42
|
|
43
43
|
class << self
|
44
|
-
attr_accessor :
|
44
|
+
attr_accessor :api_key, :environment, :subdomain, :private_key
|
45
45
|
|
46
46
|
# default Recurly.settings_path to config/recurly.yml
|
47
47
|
unless respond_to?(:settings_path)
|
@@ -55,15 +55,14 @@ module Recurly
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def configured?
|
58
|
-
Base.user && Base.
|
58
|
+
Base.user && Base.site
|
59
59
|
end
|
60
60
|
|
61
61
|
def configure
|
62
62
|
if block_given?
|
63
63
|
yield self
|
64
64
|
|
65
|
-
Base.user =
|
66
|
-
Base.password = password
|
65
|
+
Base.user = api_key
|
67
66
|
Base.site = site_for_environment(environment)
|
68
67
|
|
69
68
|
return true
|
@@ -77,22 +76,16 @@ module Recurly
|
|
77
76
|
end
|
78
77
|
|
79
78
|
def site_for_environment(environment)
|
80
|
-
|
81
|
-
|
82
|
-
when :development
|
83
|
-
"http://app.lvh.me:3000"
|
84
|
-
when :production
|
85
|
-
"https://api-production.recurly.com"
|
86
|
-
when :sandbox
|
87
|
-
"https://api-sandbox.recurly.com"
|
79
|
+
if environment == :development
|
80
|
+
"http://api.lvh.me:3000"
|
88
81
|
else
|
89
|
-
|
82
|
+
"https://api.recurly.com"
|
90
83
|
end
|
91
84
|
end
|
92
85
|
|
93
86
|
|
94
87
|
# allows configuration from a yml file that contains the fields:
|
95
|
-
#
|
88
|
+
# api_key,site,private_key
|
96
89
|
def configure_from_yaml(path = nil)
|
97
90
|
configure do |c|
|
98
91
|
# parse configuration from yml
|
@@ -105,8 +98,7 @@ module Recurly
|
|
105
98
|
recurly_env ||= ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
106
99
|
recurly_config = recurly_config[recurly_env] if recurly_config.has_key?(recurly_env)
|
107
100
|
|
108
|
-
c.
|
109
|
-
c.password = recurly_config["password"]
|
101
|
+
c.api_key = recurly_config["api_key"] || recurly_config["password"]
|
110
102
|
c.subdomain = recurly_config["subdomain"]
|
111
103
|
c.private_key = recurly_config["private_key"]
|
112
104
|
c.environment = recurly_config["environment"]
|
@@ -115,12 +107,11 @@ module Recurly
|
|
115
107
|
end
|
116
108
|
|
117
109
|
# allows configuration from a json string that contains the fields:
|
118
|
-
#
|
110
|
+
# api_key,site,private_key
|
119
111
|
def configure_from_json(json_string)
|
120
112
|
config_data = ActiveSupport::JSON.decode(json_string)
|
121
113
|
configure do |c|
|
122
|
-
c.
|
123
|
-
c.password = config_data['password']
|
114
|
+
c.api_key = config_data['api_key'] || config_data['password']
|
124
115
|
c.subdomain = config_data['subdomain']
|
125
116
|
c.private_key = config_data['private_key']
|
126
117
|
c.environment = config_data['environment']
|
@@ -1,4 +1,7 @@
|
|
1
|
+
require 'erb'
|
1
2
|
require 'fileutils'
|
3
|
+
require 'yaml'
|
4
|
+
|
2
5
|
module Recurly
|
3
6
|
module ConfigParser
|
4
7
|
class << self
|
@@ -7,7 +10,7 @@ module Recurly
|
|
7
10
|
path ||= Recurly.settings_path
|
8
11
|
settings = {}
|
9
12
|
if File.exists?(path)
|
10
|
-
settings = YAML.
|
13
|
+
settings = YAML::load(ERB.new(File.read(path)).result) || {}
|
11
14
|
else
|
12
15
|
puts "\n#{path} file not found. Run rake recurly:setup to create one\n\n"
|
13
16
|
end
|
@@ -25,4 +28,4 @@ module Recurly
|
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
28
|
-
end
|
31
|
+
end
|
data/lib/recurly/plan.rb
CHANGED
@@ -6,7 +6,7 @@ namespace :recurly do
|
|
6
6
|
@recurly_config = Recurly::ConfigParser.parse
|
7
7
|
end
|
8
8
|
|
9
|
-
desc "Clears out the Test data from your configured Recurly site (does not touch your production
|
9
|
+
desc "Clears out the Test data from your configured Recurly site (does not touch your data in production mode)"
|
10
10
|
task :clear_test_data => :load_settings do
|
11
11
|
puts "\n"
|
12
12
|
|
@@ -17,42 +17,26 @@ namespace :recurly do
|
|
17
17
|
exit
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# lets try logging into site
|
24
|
-
login_response = nil
|
25
|
-
begin
|
26
|
-
RestClient.post "https://app.recurly.com/login",
|
27
|
-
:user_session => {
|
28
|
-
:email => username,
|
29
|
-
:password => password
|
30
|
-
}
|
31
|
-
|
32
|
-
# yes, RestClient api is weird
|
33
|
-
raise "Login Failed for #{username} (we should have gotten a redirect)"
|
34
|
-
rescue RestClient::Found => e
|
35
|
-
# we got a redirect. horray!
|
36
|
-
login_response = e.response
|
37
|
-
end
|
20
|
+
api_key = @recurly_config["api_key"]
|
21
|
+
environment = @recurly_config["environment"]
|
38
22
|
|
39
23
|
# now lets clear site data
|
40
24
|
begin
|
41
|
-
|
42
|
-
|
43
|
-
|
25
|
+
if environment == :development
|
26
|
+
RestClient.delete("http://#{api_key}@api.lvh.me:3000/configuration/test_data")
|
27
|
+
else
|
28
|
+
RestClient.delete("https://#{api_key}@api.recurly.com/configuration/test_data")
|
29
|
+
end
|
44
30
|
raise "Clearing Didn't work for some reason. Is your site setting correct?"
|
45
31
|
rescue RestClient::Found => e
|
46
|
-
puts "Test Data Cleared
|
32
|
+
puts "Test Data Cleared"
|
47
33
|
end
|
48
34
|
end
|
49
35
|
|
50
36
|
def setup_static
|
51
|
-
@recurly_config["
|
52
|
-
@recurly_config["password"] ||= "my_api_key"
|
37
|
+
@recurly_config["api_key"] ||= "my_api_key"
|
53
38
|
@recurly_config["private_key"] ||= "my_private_key"
|
54
39
|
@recurly_config["subdomain"] ||= "mysite"
|
55
|
-
@recurly_config["site"] ||= "https://api-production.recurly.com"
|
56
40
|
end
|
57
41
|
|
58
42
|
desc "Creates a recurly.yml config file"
|
data/lib/recurly/transparent.rb
CHANGED
data/lib/recurly/verification.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
module Recurly
|
2
2
|
module Verification
|
3
|
+
|
4
|
+
def stringify_keys data
|
5
|
+
Hash[data.map { |k, v| [k.to_s, v] }]
|
6
|
+
end
|
7
|
+
|
3
8
|
class PreEscapedString < String
|
4
9
|
end
|
5
10
|
|
@@ -8,7 +13,8 @@ module Recurly
|
|
8
13
|
return nil if data.empty?
|
9
14
|
PreEscapedString.new( '[%s]' % data.map{|v|digest_data(v)}.compact.join(',') )
|
10
15
|
elsif data.is_a? Hash
|
11
|
-
|
16
|
+
data = stringify_keys data
|
17
|
+
digest_data data.sort.map {|k,v|
|
12
18
|
prefix = (k =~ /\A\d+\Z/) ? '' : (k.to_s+':')
|
13
19
|
(v=digest_data(v)).nil? ? nil : PreEscapedString.new('%s%s' % [prefix,v])
|
14
20
|
}
|
@@ -35,11 +41,11 @@ module Recurly
|
|
35
41
|
|
36
42
|
# Raises a Recurly::ForgedQueryString exception if the signature cannot be validated
|
37
43
|
def verify_params!(claim, args)
|
38
|
-
args =
|
44
|
+
args = stringify_keys args
|
39
45
|
signature = args.delete('signature') or raise Recurly::ForgedQueryString.new('Signature is missing')
|
40
46
|
hmac, timestamp = signature.split('-')
|
41
47
|
age = Time.now.to_i - timestamp.to_i
|
42
|
-
raise Recurly::ForgedQueryString.new('Timestamp is too old or new') if age > 3600 || age <
|
48
|
+
raise Recurly::ForgedQueryString.new('Timestamp is too old or new') if age > 3600 || age < -3600
|
43
49
|
|
44
50
|
if signature != generate_signature(claim, args, timestamp)
|
45
51
|
raise Recurly::ForgedQueryString.new('Signature cannot be verified')
|
@@ -48,15 +54,15 @@ module Recurly
|
|
48
54
|
|
49
55
|
def sign_billing_info_update(account_code)
|
50
56
|
generate_signature('billinginfoupdate', {
|
51
|
-
account_code
|
57
|
+
:account_code => account_code
|
52
58
|
})
|
53
59
|
end
|
54
60
|
|
55
|
-
def sign_transaction(
|
61
|
+
def sign_transaction(amount_in_cents, currency, account_code=nil)
|
56
62
|
generate_signature('transactioncreate', {
|
57
|
-
account_code
|
58
|
-
currency
|
59
|
-
amount_in_cents
|
63
|
+
:account_code => account_code,
|
64
|
+
:currency => currency,
|
65
|
+
:amount_in_cents => amount_in_cents
|
60
66
|
})
|
61
67
|
end
|
62
68
|
|
data/lib/recurly/version.rb
CHANGED
data/spec/config/recurly.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
---
|
2
|
-
username:
|
3
|
-
password:
|
2
|
+
username: hello@test.com
|
3
|
+
password: 2a655d41659d4ae0b37fcaec06331bf5
|
4
4
|
private_key: 4cdbdfbb90f84b3c8fb4ca337d1b2cfc
|
5
|
-
subdomain:
|
5
|
+
subdomain: intuit
|
6
6
|
environment: :development
|
data/spec/config/test1.yml
CHANGED
data/spec/config/test2.yml
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
development:
|
2
|
-
|
3
|
-
password: asdf4jk31
|
2
|
+
api_key: asdf4jk31
|
4
3
|
subdomain: site1
|
5
|
-
environment: :sandbox
|
6
4
|
|
7
5
|
test:
|
8
|
-
|
9
|
-
password: asdf4jk32
|
6
|
+
api_key: asdf4jk32
|
10
7
|
subdomain: site2
|
11
|
-
environment: :production
|
data/spec/unit/config_spec.rb
CHANGED
@@ -5,15 +5,13 @@ describe "RecurlyConfig" do
|
|
5
5
|
context "loading from YML" do
|
6
6
|
it "should load traditional configuration from a YML file" do
|
7
7
|
Recurly.configure_from_yaml("#{File.dirname(__FILE__)}/../config/test1.yml")
|
8
|
-
Recurly.
|
9
|
-
Recurly.password.should == "asdf4jk31"
|
8
|
+
Recurly.api_key.should == "asdf4jk31"
|
10
9
|
Recurly.subdomain.should == "site1"
|
11
10
|
end
|
12
11
|
|
13
12
|
it "should load configuration from a YML file based on running environment" do
|
14
13
|
Recurly.configure_from_yaml("#{File.dirname(__FILE__)}/../config/test2.yml")
|
15
|
-
Recurly.
|
16
|
-
Recurly.password.should == "asdf4jk32"
|
14
|
+
Recurly.api_key.should == "asdf4jk32"
|
17
15
|
Recurly.subdomain.should == "site2"
|
18
16
|
end
|
19
17
|
end
|
@@ -21,28 +19,23 @@ describe "RecurlyConfig" do
|
|
21
19
|
context "loading from json" do
|
22
20
|
it "should load configuration from a json config string" do
|
23
21
|
Recurly.configure_from_json({
|
24
|
-
:
|
25
|
-
:password => "somepass",
|
26
|
-
:environment => :sandbox,
|
22
|
+
:api_key => "somepass",
|
27
23
|
:subdomain => 'recurlytest3-test',
|
28
24
|
}.to_json)
|
29
|
-
Recurly.
|
30
|
-
Recurly.password.should == "somepass"
|
25
|
+
Recurly.api_key.should == "somepass"
|
31
26
|
Recurly.subdomain.should == 'recurlytest3-test'
|
32
|
-
Recurly::Base.site.to_s.should == "https://api
|
27
|
+
Recurly::Base.site.to_s.should == "https://api.recurly.com"
|
33
28
|
|
34
29
|
# test with some crazy chars in the password
|
35
30
|
Recurly.configure_from_json({
|
36
|
-
:
|
37
|
-
:password => "*$&!!::@&!)*)*_",
|
31
|
+
:api_key => "*$&!!::@&!)*)*_",
|
38
32
|
:subdomain => "recurlytest3-test",
|
39
|
-
:environment => :sandbox,
|
40
33
|
}.to_json)
|
41
34
|
|
42
|
-
Recurly.
|
43
|
-
Recurly.
|
35
|
+
Recurly.api_key.should == "*$&!!::@&!)*)*_"
|
36
|
+
Recurly::Base.user.should == Recurly.api_key
|
44
37
|
Recurly.subdomain.should == 'recurlytest3-test'
|
45
|
-
Recurly::Base.site.to_s.should == "https://api
|
38
|
+
Recurly::Base.site.to_s.should == "https://api.recurly.com"
|
46
39
|
end
|
47
40
|
|
48
41
|
end
|
@@ -16,26 +16,6 @@ module Recurly
|
|
16
16
|
Transparent.url(Action::UpdateBilling).should == "#{Recurly::Base.site}/transparent/#{Recurly.subdomain}/billing_info"
|
17
17
|
Transparent.url(Action::CreateTransaction).should == "#{Recurly::Base.site}/transparent/#{Recurly.subdomain}/transaction"
|
18
18
|
end
|
19
|
-
|
20
|
-
it "should equal api-sandbox for sandbox" do
|
21
|
-
Recurly.configure do |config|
|
22
|
-
config.environment = :sandbox
|
23
|
-
config.subdomain = 'testtest'
|
24
|
-
end
|
25
|
-
Transparent.url(Action::CreateSubscription).should == "#{Recurly::Base.site}/transparent/testtest/subscription"
|
26
|
-
Transparent.url(Action::UpdateBilling).should == "#{Recurly::Base.site}/transparent/testtest/billing_info"
|
27
|
-
Transparent.url(Action::CreateTransaction).should == "#{Recurly::Base.site}/transparent/testtest/transaction"
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should equal api-production for sandbox" do
|
31
|
-
Recurly.configure do |config|
|
32
|
-
config.environment = :production
|
33
|
-
config.subdomain = 'testtest'
|
34
|
-
end
|
35
|
-
Transparent.url(Action::CreateSubscription).should == "#{Recurly::Base.site}/transparent/testtest/subscription"
|
36
|
-
Transparent.url(Action::UpdateBilling).should == "#{Recurly::Base.site}/transparent/testtest/billing_info"
|
37
|
-
Transparent.url(Action::CreateTransaction).should == "#{Recurly::Base.site}/transparent/testtest/transaction"
|
38
|
-
end
|
39
19
|
end
|
40
20
|
|
41
21
|
describe ".encrypt_string" do
|
@@ -18,10 +18,16 @@ module Recurly
|
|
18
18
|
|
19
19
|
it "should encode nested arrays and hashes" do
|
20
20
|
Verification::digest_data(
|
21
|
-
{a
|
21
|
+
{:a => [1,2,3], :b => {:c => '123', :d => '456'}}
|
22
22
|
).should == '[a:[1,2,3],b:[c:123,d:456]]'
|
23
23
|
end
|
24
24
|
|
25
|
+
it "should alphabetize keys" do
|
26
|
+
Verification::digest_data(
|
27
|
+
{:a => 1, :c => 3, :b => 2}
|
28
|
+
).should == '[a:1,b:2,c:3]'
|
29
|
+
end
|
30
|
+
|
25
31
|
it "should treat hashes with numeric indexes as arrays" do
|
26
32
|
Verification::digest_data(
|
27
33
|
{'1' => 4, '2' => 5, '3' => 6}
|
@@ -30,13 +36,13 @@ module Recurly
|
|
30
36
|
|
31
37
|
it "should escape syntax characters" do
|
32
38
|
Verification::digest_data(
|
33
|
-
{syntaxchars
|
39
|
+
{ :syntaxchars => ' \\ [ ] : , '}
|
34
40
|
).should == '[syntaxchars: \\\\ \[ \] \: \, ]'
|
35
41
|
end
|
36
42
|
|
37
43
|
it "should generate proper signatures" do
|
38
44
|
Time.stub!(:now).and_return(origin_time) # gen at origin time
|
39
|
-
sig = Verification.generate_signature('update',{a
|
45
|
+
sig = Verification.generate_signature('update',{ :a => 'foo', :b => 'bar'})
|
40
46
|
sig.should == test_sig
|
41
47
|
end
|
42
48
|
|
@@ -44,7 +50,7 @@ module Recurly
|
|
44
50
|
Time.stub!(:now).and_return(Time.at(origin_time+60)) # one minute passed
|
45
51
|
lambda {
|
46
52
|
good = Verification.verify_params!('update',
|
47
|
-
{a
|
53
|
+
{ :a => 'foo', :b => 'bar', :signature => test_sig})
|
48
54
|
}.should_not raise_error
|
49
55
|
end
|
50
56
|
|
@@ -52,7 +58,7 @@ module Recurly
|
|
52
58
|
Time.stub!(:now).and_return(Time.at(origin_time+60)) # one minute passed
|
53
59
|
lambda {
|
54
60
|
good = Verification.verify_params!('update',
|
55
|
-
{a
|
61
|
+
{ :a => 'foo', :b => 'bar', :signature => 'badsig'})
|
56
62
|
}.should raise_error(Recurly::ForgedQueryString)
|
57
63
|
end
|
58
64
|
|
@@ -60,15 +66,15 @@ module Recurly
|
|
60
66
|
Time.stub!(:now).and_return(Time.at(origin_time+7200)) # two hours passed
|
61
67
|
lambda {
|
62
68
|
good = Verification.verify_params!('update',
|
63
|
-
{a
|
69
|
+
{ :a => 'foo', :b => 'bar', :signature => test_sig})
|
64
70
|
}.should raise_error(Recurly::ForgedQueryString)
|
65
71
|
end
|
66
72
|
|
67
|
-
it "should reject time traveling signatures from the future" do
|
68
|
-
Time.stub!(:now).and_return(Time.at(origin_time-
|
73
|
+
it "should reject time traveling signatures from the future (with 1 hour grace period)" do
|
74
|
+
Time.stub!(:now).and_return(Time.at(origin_time-7200)) # two hours earlier
|
69
75
|
lambda {
|
70
76
|
good = Verification.verify_params!('update',
|
71
|
-
{a
|
77
|
+
{ :a => 'foo', :b => 'bar', :signature => test_sig})
|
72
78
|
}.should raise_error(Recurly::ForgedQueryString)
|
73
79
|
end
|
74
80
|
end
|