atpay_tokens 2.0.2 → 2.1.0
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 +4 -4
- data/README.md +21 -19
- data/atpay_tokens.gemspec +2 -2
- data/bin/atpay_tokens +16 -12
- data/lib/atpay/security_key.rb +4 -12
- data/lib/atpay/tokenator.rb +16 -16
- data/spec/atpay/security_key_spec.rb +34 -0
- data/spec/atpay/tokenator_spec.rb +8 -0
- data/spec/atpay_tokens_spec.rb +57 -0
- data/spec/helper.rb +0 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b287a2d69504b635b56368a27f7c2c9c2b6d6d4
|
4
|
+
data.tar.gz: 294d9c0723c657eb277d246aa2a79f238ec7a4b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 257ed967ee374de94b602d2d598d72bac190eb64c2d7612a0bf5b1eb8627ad8c1e5d0cd0229a21252d9e714cfb6e7c12aa01d4bc29efbb82748a5b8bbebcd3a8
|
7
|
+
data.tar.gz: 633db21ac4d51830a0d10019fcb74937104b4151beb60a98e4f4d58268b500d66d6098073cfad2cbbb42b1e2e0fdcb64802f36bbc7b731a51a782fad11642af5
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# @Pay API Client
|
2
2
|
|
3
|
-
[](https://travis-ci.org/atpay/atpay-client)
|
3
|
+
[](https://travis-ci.org/atpay/atpay-client) [](https://coveralls.io/repos/atpay/atpay-client/badge.png?branch=master)
|
4
4
|
|
5
5
|
|
6
6
|
Client interface for the @Pay API and key generation for
|
@@ -47,34 +47,36 @@ session = AtPay::Session.new({
|
|
47
47
|
|
48
48
|
## Command Line Usage
|
49
49
|
|
50
|
-
$
|
50
|
+
$ atpay_tokens --help
|
51
51
|
|
52
52
|
|
53
53
|
### Parameters
|
54
54
|
|
55
|
-
|
55
|
+
atpay_tokens v2.1
|
56
56
|
Options:
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
57
|
+
--private-key, -p <s>: [global] The private key given to you by @Pay
|
58
|
+
--public-key, -u <s>: [global] @Pay's public key, given to you by @Pay
|
59
|
+
--partner-id, -a <i>: [global] The partner ID given to you by @Pay
|
60
|
+
--environment, -e <s>: [global] The environment you want to generate buttons for. Currently sandbox or production (default: production)
|
61
|
+
--config, -c <s>: [global] The path to a configuration file in yml format
|
62
|
+
--type, -t <s>: [global] The type of token to generate (site,email,universal)
|
63
|
+
--card, -r <s>: [site-token, email-token] The card token associated with the recipient of this token. If `type` is site, this must be present
|
64
|
+
--email, -m <s>: [email-token] The email associated with the receipt of this token. Incompatible when `type` is 'site'
|
65
|
+
--url, -l <s>: [universal-token] The Signup url the recipient should go to if they don't have payment informaiton. Incompatible when `type` is 'site' or 'email'
|
66
|
+
--amount, -o <f>: [token] The amount a user should be charged for the transaction you're generating a token for (default: 5.0)
|
67
|
+
--user-data, -s <s>: [token] Data to pass back as a reference
|
68
|
+
--expires, -x <i>: [token] Expiration date for token, integer value of seconds since epoch
|
69
|
+
--header-user-agent, -h <s>: [site-token] The HTTP_USER_AGENT from the client's request header (if `type` is 'site')
|
69
70
|
--header-accept-language, -d <s>: [site-token] The HTTP_ACCEPT_LANGUAGE from the client's request header (if `type` is 'site')
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
--help
|
71
|
+
--header-accept-charset <s>: [site-token] The HTTP_ACCEPT_CHARSET from the client's request header (if `type` is 'site')
|
72
|
+
--ip-address, -i <s>: [site-token] The IP address of the token recipient (if `type` is 'site')
|
73
|
+
--version, -v: Print version and exit
|
74
|
+
--help: Show this message
|
74
75
|
|
75
76
|
* Parameters marked as [global] must be passed on the command line
|
76
77
|
* Parameters marked with [site-token] are required for site tokens
|
77
78
|
* Parameters marked with [email-token] are required for email tokens
|
79
|
+
* Parameters marked with [universal-token] are required for universal tokens
|
78
80
|
* Parameters marked with [token] are accepted for both site and email tokens
|
79
81
|
|
80
82
|
### CSV via STDIN
|
data/atpay_tokens.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'atpay_tokens'
|
3
|
-
s.version = '2.0
|
4
|
-
s.date = '2013-
|
3
|
+
s.version = '2.1.0'
|
4
|
+
s.date = '2013-08-12'
|
5
5
|
s.summary = "@Pay Token Generator"
|
6
6
|
s.description = "Client interface for the @Pay API, key generation for performance optimization"
|
7
7
|
s.authors = ["James Kassemi", "Glen Holcomb"]
|
data/bin/atpay_tokens
CHANGED
@@ -8,7 +8,7 @@ require 'csv'
|
|
8
8
|
require 'trollop'
|
9
9
|
|
10
10
|
$opts = Trollop::options do
|
11
|
-
version "
|
11
|
+
version "atpay_tokens v2.1"
|
12
12
|
|
13
13
|
# Global
|
14
14
|
opt :private_key, "[global] The private key given to you by @Pay", :type => :string
|
@@ -16,11 +16,12 @@ $opts = Trollop::options do
|
|
16
16
|
opt :partner_id, "[global] The partner ID given to you by @Pay", :type => :integer
|
17
17
|
opt :environment, "[global] The environment you want to generate buttons for. Currently sandbox or production", :default => 'production', :type => :string
|
18
18
|
opt :config, "[global] The path to a configuration file in yml format", :type => :string
|
19
|
-
opt :type, "[global] The type of token to generate (site,email)", :type => :string
|
19
|
+
opt :type, "[global] The type of token to generate (site,email,universal)", :type => :string
|
20
20
|
|
21
21
|
# Per Token
|
22
22
|
opt :card, "[site-token, email-token] The card token associated with the recipient of this token. If `type` is site, this must be present", :type => :string
|
23
|
-
opt :email, "[email-token] The email associated with the receipt of this token.
|
23
|
+
opt :email, "[email-token] The email associated with the receipt of this token. Incompatible when `type` is 'site'", :type => :string
|
24
|
+
opt :url, "[universal-token] The Signup url the recipient should go to if they don't have payment informaiton. Incompatible when `type` is 'site' or 'email'", :type => :string
|
24
25
|
|
25
26
|
opt :amount, "[token] The amount a user should be charged for the transaction you're generating a token for", :default => 5.0
|
26
27
|
opt :user_data, "[token] Data to pass back as a reference", :type => :string
|
@@ -64,16 +65,12 @@ module Args
|
|
64
65
|
|
65
66
|
class TokenSet
|
66
67
|
def next_token
|
67
|
-
|
68
|
-
cli
|
69
|
-
else
|
70
|
-
stdin
|
71
|
-
end
|
68
|
+
cli? ? cli : stdin
|
72
69
|
end
|
73
70
|
|
74
71
|
private
|
75
72
|
def cli?
|
76
|
-
($opts[:card] or $opts[:email]) and $opts[:type]
|
73
|
+
($opts[:card] or $opts[:email] or $opts[:url]) and $opts[:type]
|
77
74
|
end
|
78
75
|
|
79
76
|
def cli
|
@@ -119,17 +116,20 @@ class Generator
|
|
119
116
|
Trollop::die :ip_address, "must be present for site_tokens" if site? and options[:ip_address].nil?
|
120
117
|
Trollop::die :email, "or card must be present for all rows" if email? and (options[:card].nil? and options[:email].nil?)
|
121
118
|
Trollop::die :amount, "must be present" if options[:amount].nil?
|
119
|
+
Trollop::die :url, "must be present" if universal? and options[:url].nil?
|
120
|
+
Trollop::die :email, "incompatible with universal tokens" if universal? and options[:email]
|
121
|
+
Trollop::die :card, "incompatible with universal tokens" if universal? and options[:card]
|
122
122
|
end
|
123
123
|
|
124
124
|
def next
|
125
|
-
return unless options=next_config
|
125
|
+
return unless options = next_config
|
126
126
|
options[:amount] = options[:amount].to_f
|
127
127
|
|
128
128
|
row_option_check(options)
|
129
129
|
|
130
130
|
security_key = session.security_key(options)
|
131
131
|
|
132
|
-
if email?
|
132
|
+
if email? or universal?
|
133
133
|
security_key.email_token
|
134
134
|
elsif site?
|
135
135
|
headers = {
|
@@ -158,11 +158,15 @@ class Generator
|
|
158
158
|
def site?
|
159
159
|
$opts[:type] == "site"
|
160
160
|
end
|
161
|
+
|
162
|
+
def universal?
|
163
|
+
$opts[:type] == 'universal'
|
164
|
+
end
|
161
165
|
end
|
162
166
|
|
163
167
|
config = Args::Main.new
|
164
168
|
generator = Generator.new(config)
|
165
169
|
|
166
|
-
while token=generator.next
|
170
|
+
while token = generator.next
|
167
171
|
puts token
|
168
172
|
end
|
data/lib/atpay/security_key.rb
CHANGED
@@ -8,7 +8,7 @@ module AtPay
|
|
8
8
|
raise ArgumentError.new("User Data can't exceed 2500 characters.") if options[:user_data] and options[:user_data].length > 2500
|
9
9
|
raise ArgumentError.new("email") unless options[:email].nil? or options[:email] =~ /.+@.+/
|
10
10
|
raise ArgumentError.new("amount") unless options[:amount].is_a? Float
|
11
|
-
raise ArgumentError.new("card or email or member required") if options[:email].nil? and options[:card].nil? and options[:member].nil?
|
11
|
+
raise ArgumentError.new("card or email or member or url required") if options[:email].nil? and options[:card].nil? and options[:member].nil? and options[:url].nil?
|
12
12
|
|
13
13
|
@session = session
|
14
14
|
@options = options
|
@@ -78,19 +78,11 @@ module AtPay
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def target
|
81
|
-
|
81
|
+
format_target [:card, :member, :email, :url].detect { |key| @options[key] }
|
82
82
|
end
|
83
83
|
|
84
|
-
def
|
85
|
-
"
|
86
|
-
end
|
87
|
-
|
88
|
-
def member_format
|
89
|
-
"member<#{@options[:member]}>" if @options[:member]
|
90
|
-
end
|
91
|
-
|
92
|
-
def email_format
|
93
|
-
"email<#{@options[:email]}>" if @options[:email]
|
84
|
+
def format_target(key)
|
85
|
+
"#{key.to_s}<#{@options[key]}>"
|
94
86
|
end
|
95
87
|
|
96
88
|
def expires
|
data/lib/atpay/tokenator.rb
CHANGED
@@ -11,6 +11,13 @@ module AtPay
|
|
11
11
|
:ip,
|
12
12
|
:user_data
|
13
13
|
|
14
|
+
TARGETS = {
|
15
|
+
/url<(.*?)>/ => [:@url, 6],
|
16
|
+
/card<(.*?)>/ => [:@card, 7],
|
17
|
+
/email<(.*?)>/ => [:@email, 8],
|
18
|
+
/member<(.*?)>/ => [:@member, 9]
|
19
|
+
}
|
20
|
+
|
14
21
|
# A bit clunky but useful for testing token decomposition.
|
15
22
|
# If you provide a test session then the config values there
|
16
23
|
# will be used so that decryption will function without @Pay's
|
@@ -74,7 +81,7 @@ module AtPay
|
|
74
81
|
end
|
75
82
|
|
76
83
|
def source
|
77
|
-
{email: @email, card: @card, member: @member}
|
84
|
+
{ email: @email, card: @card, member: @member, url: @url }
|
78
85
|
end
|
79
86
|
|
80
87
|
# Return parts in a hash structure, handy for ActiveRecord.
|
@@ -165,22 +172,15 @@ module AtPay
|
|
165
172
|
return @user_data
|
166
173
|
end
|
167
174
|
|
168
|
-
# Find the target of the token. This could be a Credit Card
|
169
|
-
# Email Address or Member UUID.
|
175
|
+
# Find the target of the token. This could be a Credit Card,
|
176
|
+
# Email Address, URL or Member UUID.
|
170
177
|
def target(target)
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
@payload.slice!(0, ($1.length + 8))
|
178
|
-
when /member<(.*?)>/
|
179
|
-
@member = $1
|
180
|
-
@payload.slice!(0, ($1.length + 9))
|
181
|
-
else
|
182
|
-
raise "No target found"
|
183
|
-
end
|
178
|
+
match = TARGETS.keys.detect { |key| target.match key }
|
179
|
+
|
180
|
+
raise "No target found" if match.nil?
|
181
|
+
|
182
|
+
instance_variable_set TARGETS[match][0], $1.dup
|
183
|
+
@payload.slice!(0, ($1.length + TARGETS[match][1]))
|
184
184
|
end
|
185
185
|
end
|
186
186
|
end
|
@@ -42,6 +42,40 @@ describe AtPay::SecurityKey do
|
|
42
42
|
})
|
43
43
|
}.to raise_error
|
44
44
|
end
|
45
|
+
|
46
|
+
it "fails when not given an email or card or member or url" do
|
47
|
+
expect {
|
48
|
+
AtPay::SecurityKey.new(session, {
|
49
|
+
amount: 25.00
|
50
|
+
})
|
51
|
+
}.to raise_error
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#target" do
|
56
|
+
it "builds a card string if card option given" do
|
57
|
+
for_card = AtPay::SecurityKey.new(session, amount: 25.0, card: 'fakecardtoken')
|
58
|
+
|
59
|
+
expect(for_card.send(:target)).to eq("card<fakecardtoken>")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "builds an email string if email option given" do
|
63
|
+
for_email = AtPay::SecurityKey.new(session, amount: 25.0, email: 'bob@bob')
|
64
|
+
|
65
|
+
expect(for_email.send(:target)).to eq("email<bob@bob>")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "builds a member string if member option given" do
|
69
|
+
for_member = AtPay::SecurityKey.new(session, amount: 25.0, member: 'fakemember')
|
70
|
+
|
71
|
+
expect(for_member.send(:target)).to eq("member<fakemember>")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "builds a url string if url option given" do
|
75
|
+
for_url = AtPay::SecurityKey.new(session, amount: 25.0, url: 'http://fake.url.com')
|
76
|
+
|
77
|
+
expect(for_url.send(:target)).to eq("url<http://fake.url.com>")
|
78
|
+
end
|
45
79
|
end
|
46
80
|
|
47
81
|
describe "#to_s" do
|
@@ -13,6 +13,7 @@ describe AtPay::Tokenator do
|
|
13
13
|
let(:version) { AtPay::Tokenator.new token(50.00, [:email_token], {email: 'email@address', version: 2}), build_session }
|
14
14
|
let(:member) { AtPay::Tokenator.new token(50.00, [:email_token], {member: '4DF08A79-C16C-4842-AA1B-AE878C9C6C2C'}), build_session }
|
15
15
|
let(:group) { AtPay::Tokenator.new token(50.00, [:email_token], {member: '4DF08A79-C16C-4842-AA1B-AE878C9C6C2C', group: '18', user_data: 'hello from data'}), build_session }
|
16
|
+
let(:url) { AtPay::Tokenator.new token(50.00, [:email_token], {url: 'http://fake.url' }), build_session }
|
16
17
|
|
17
18
|
describe "Parsing" do
|
18
19
|
it "Uses the key specified in ENCRYPTION if not given a session" do
|
@@ -58,6 +59,13 @@ describe AtPay::Tokenator do
|
|
58
59
|
group.group.should eq('18')
|
59
60
|
group.user_data.should eq('hello from data')
|
60
61
|
end
|
62
|
+
|
63
|
+
it "processes a url token" do
|
64
|
+
url.header
|
65
|
+
url.body Base64.decode64(public_key)
|
66
|
+
|
67
|
+
url.source[:url].should eq('http://fake.url')
|
68
|
+
end
|
61
69
|
end
|
62
70
|
|
63
71
|
describe "Exceptions" do
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'atpay_tokens'
|
3
|
+
|
4
|
+
describe "atpay_tokens" do
|
5
|
+
let(:key_pattern) { /@((([A-Za-z0-9+=*]{4})*-)?([A-Za-z0-9+=\/]{4}){5,})/ }
|
6
|
+
let(:base_args) { "--environment test --private-key \"#{private_key}\" --public-key \"#{public_key}\" --partner-id 1 --amount 24.0"}
|
7
|
+
let(:universal_token_args) { "#{base_args} --type universal --url http://bob.com" }
|
8
|
+
let(:site_token_args) { "#{base_args} --type site --card cardtoken --header-user-agent bob --header-accept-language en --header-accept-charset us --ip-address 127.0.0.1" }
|
9
|
+
let(:email_token_args) { "#{base_args} --type email --email bob@bob.com" }
|
10
|
+
let(:command) { File.dirname(__FILE__) + '/../bin/atpay_tokens' }
|
11
|
+
|
12
|
+
describe "Universal Tokens" do
|
13
|
+
it "returns an @Pay Token" do
|
14
|
+
expect(`#{command} #{universal_token_args}`).to match(key_pattern)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns a universal token" do
|
18
|
+
tokenator = AtPay::Tokenator.new(`#{command} #{universal_token_args}`, build_session)
|
19
|
+
|
20
|
+
tokenator.header
|
21
|
+
tokenator.body Base64.decode64(public_key)
|
22
|
+
|
23
|
+
expect(tokenator.source[:url]).to eq('http://bob.com')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "Site Tokens" do
|
28
|
+
it "returns an @Pay Token" do
|
29
|
+
expect(`#{command} #{site_token_args}`).to match(key_pattern)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns a site token" do
|
33
|
+
tokenator = AtPay::Tokenator.new(`#{command} #{site_token_args}`, build_session)
|
34
|
+
|
35
|
+
tokenator.header
|
36
|
+
tokenator.browser_data Base64.decode64(public_key)
|
37
|
+
tokenator.body Base64.decode64(public_key)
|
38
|
+
|
39
|
+
expect(tokenator.source[:card]).to eq('cardtoken')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "Email Tokens" do
|
44
|
+
it "returns an @Pay Token" do
|
45
|
+
expect(`#{command} #{email_token_args}`).to match(key_pattern)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns an email token" do
|
49
|
+
tokenator = AtPay::Tokenator.new(`#{command} #{email_token_args}`, build_session)
|
50
|
+
|
51
|
+
tokenator.header
|
52
|
+
tokenator.body Base64.decode64(public_key)
|
53
|
+
|
54
|
+
expect(tokenator.source[:email]).to eq('bob@bob.com')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atpay_tokens
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Kassemi
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- spec/atpay/security_key_spec.rb
|
79
79
|
- spec/atpay/session_spec.rb
|
80
80
|
- spec/atpay/tokenator_spec.rb
|
81
|
+
- spec/atpay_tokens_spec.rb
|
81
82
|
- spec/helper.rb
|
82
83
|
homepage: https://atpay.com
|
83
84
|
licenses: []
|
@@ -107,4 +108,5 @@ test_files:
|
|
107
108
|
- spec/atpay/security_key_spec.rb
|
108
109
|
- spec/atpay/session_spec.rb
|
109
110
|
- spec/atpay/tokenator_spec.rb
|
111
|
+
- spec/atpay_tokens_spec.rb
|
110
112
|
- spec/helper.rb
|