atpay_tokens 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -2
  3. data/atpay_tokens.gemspec +4 -3
  4. data/bin/atpay_tokens +117 -173
  5. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a0da37b9f59dd6d2a5dd925c3b4fe9a222fbd36
4
- data.tar.gz: 9c831dc125d62188bc521c45cb9b948373ac15c3
3
+ metadata.gz: 4f9e7b7a65d0e4f05625ca9fd5bbf4937fb887fb
4
+ data.tar.gz: 21fd295ab59fb0ff9de4163a6d1d5c6ba4f9df44
5
5
  SHA512:
6
- metadata.gz: 58ea9b2e354abf2e707cbd147ff7bac187abbf3a4510ee60a6cfbc34a6c8a65451189dcbb96bc22b9c6ca2097178b738a833f92ab14efc4904c4efa49c662584
7
- data.tar.gz: 82d1c9b5b7ae4467926abf9f3dd7d37ef5e66f0ced7d7e62689974f19fb405bec08b2bd141dc128885765267d261e577dc17e5c1e19a670cda9ace1aee20fd56
6
+ metadata.gz: 8640e0071f39dd7185cccefc5926d07f8dcf64c8ea5bcd8172ee417e459c3f8afad08338d9ccd44882aa93c839588466cf3a5593ad79be403838a95e302377da
7
+ data.tar.gz: 5a6dcc2f9bd5282ffa11af90320819f583c303c42e6a09e5b02502aef38b957074a771af4ec40f445ebd6a649ed1cd3b3c269ef6d0e220067a9fd330243cfa55
data/README.md CHANGED
@@ -13,14 +13,18 @@ Interfaces here are implemented after receiving OAuth 2.0
13
13
  privileges for the partner/user record. You cannot authenticate
14
14
  directly to the API with this library at this moment.
15
15
 
16
+ ## Requirements
17
+
18
+ ruby >= 1.9
19
+
16
20
  ## Installation
17
21
 
18
- Add the 'atpay-client' gem to your Gemfile:
22
+ Add the 'atpay_tokens' gem to your Gemfile:
19
23
 
20
24
  ```ruby
21
25
  #Gemfile
22
26
 
23
- gem 'atpay', :github => "atpay/atpay-client"
27
+ gem 'atpay_tokens', :github => "atpay/atpay-client"
24
28
  ```
25
29
 
26
30
  ## Configuration
@@ -41,6 +45,63 @@ session = AtPay::Session.new({
41
45
  })
42
46
  ```
43
47
 
48
+ ## Command Line Usage
49
+
50
+ $ atpay-client --help
51
+
52
+
53
+ ### Parameters
54
+
55
+ atpay-token-generator v2.0
56
+ Options:
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)
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. Incomptible when `type` is 'site'
65
+ --amount, -o <f>: [token] The amount a user should be charged for the transaction you're generating a token for (default: 5.0)
66
+ --user-data, -s <s>: [token] Data to pass back as a reference
67
+ --expires, -x <i>: [token] Expiration date for token, integer value of seconds since epoch
68
+ --header-user-agent, -h <s>: [site-token] The HTTP_USER_AGENT from the client's request header (if `type` is 'site')
69
+ --header-accept-language, -d <s>: [site-token] The HTTP_ACCEPT_LANGUAGE from the client's request header (if `type` is 'site')
70
+ --header-accept-charset <s>: [site-token] The HTTP_ACCEPT_CHARSET from the client's request header (if `type` is 'site')
71
+ --ip-address, -i <s>: [site-token] The IP address of the token recipient (if `type` is 'site')
72
+ --version, -v: Print version and exit
73
+ --help, -l: Show this message
74
+
75
+ * Parameters marked as [global] must be passed on the command line
76
+ * Parameters marked with [site-token] are required for site tokens
77
+ * Parameters marked with [email-token] are required for email tokens
78
+ * Parameters marked with [token] are accepted for both site and email tokens
79
+
80
+ ### CSV via STDIN
81
+
82
+ All token arguments (arguments not marked as [global]) may be passed
83
+ to the command line utility via STDIN in CSV format. The first line of
84
+ the incoming CSV must be the headers for each column, using the full
85
+ option names above. For instance, to pass a CSV with amount, card tokens,
86
+ user_data, and email address:
87
+
88
+ ```
89
+ $ atpay_tokens --private-key="XYZ" --partner-id=999 --type=email < data.csv
90
+ ```
91
+
92
+ ```
93
+ amount,user-data,card,email
94
+ 50.00,refid1,XbsfrYUjAHh0lWSoWS0q3ahIpxohpcM=,james@example.com
95
+ 100.00,refid2,XbsfrYUjAHh0lWSoWS0q3ahIpxohpcM=,james@example.com
96
+ 200.00,refid3,XbsfrYUjAHh0lWSoWS0q3ahIpxohpcM=,james@example.com
97
+ ```
98
+
99
+ The above will print 3 tokens for amounts between 50 and 200 dollars,
100
+ all to charge the same credit card at the same email address.
101
+
102
+ If you need to change the keys, partner id, or type, you'll need to
103
+ start a new instance of the utility for each change.
104
+
44
105
  ## Usage
45
106
 
46
107
  In order for an @Pay user to make a purchase via email, they'll
data/atpay_tokens.gemspec CHANGED
@@ -1,15 +1,16 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'atpay_tokens'
3
- s.version = '1.0.2'
3
+ s.version = '2.0.0'
4
4
  s.date = '2013-07-25'
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"]
8
- s.email = 'james@atpay.com'
8
+ s.email = 'dev@atpay.com'
9
9
  s.files = `git ls-files`.split($/)
10
10
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
11
11
  s.homepage = "https://atpay.com"
12
- s.executables << 'atpay_tokens'
12
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
13
  s.add_runtime_dependency 'ffi'
14
14
  s.add_runtime_dependency 'rbnacl'
15
+ s.add_runtime_dependency 'trollop'
15
16
  end
data/bin/atpay_tokens CHANGED
@@ -4,215 +4,159 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
4
 
5
5
  require 'atpay_tokens'
6
6
  require 'yaml'
7
-
8
-
9
- class Arguments
10
- attr_reader :values
11
-
12
- def initialize
13
- @values = YAML.load_file(File.expand_path('../../config/credentials.yml', __FILE__))
14
- end
15
- end
16
-
17
- module Usage
18
- USAGE = <<-EOS
19
-
20
- The @Pay Client will generate @Pay Tokens for you. You can use this tool to generate both email
21
- and site tokens. There are quite a few arguments but only a handfull are required:
22
-
23
-
24
- Examples:
25
- atpay_tokens email_token targets bob@bob.com amount 8.0 expires 1454673223
26
- atpay_tokens email_token targets bob@bob.com group "8.0 9.5 23.28"
27
- atpay_tokens email_token cards OGQ3OWE0OWNhMFFTL4mMpQA= amount 12.0
28
- atpay_tokens email_token cards OGQ3OWE0OWNhMFFTL4mMpQA= targets bob@bob.com amount 12.0
29
-
30
- atpay_tokens site_token cards OGQ3OWE0OWNhMFFTL4mMpQA= amount 5.0 user_agent "curl/7.9.8" lang "en-US,en;q=0.8" charset "utf8" addr 173.163.242.213
31
-
32
-
33
- Required:
34
- site_token|email_token You must specify the type of token you wish to generate
35
- cards|targets You must at least specify a card or email address. For a site token
36
- you must provide a card. If you are building multiple tokens ensure
37
- that you provide a card token for each email and that the order is
38
- correct.
39
- amount|group You also need to specify either a single amount or a group of amounts.
40
-
41
-
42
- Required (for site token):
43
- user_agent The HTTP_USER_AGENT from the client's request header.
44
- lang The HTTP_ACCEPT_LANGUAGE from the client's request header.
45
- charset The HTTP_ACCEPT_CHARSET from the client's request header.
46
- addr The IP address corresponding to the requesting source (The user's IP)
47
-
48
-
49
- Optional:
50
- expires This is the expiration date. This should be an integer value of
51
- seconds since epoch.
52
-
53
- EOS
7
+ require 'csv'
8
+ require 'trollop'
9
+
10
+ $opts = Trollop::options do
11
+ version "atpay-token-generator v2.0"
12
+
13
+ # Global
14
+ opt :private_key, "[global] The private key given to you by @Pay", :type => :string
15
+ opt :public_key, "[global] @Pay's public key, given to you by @Pay", :type => :string
16
+ opt :partner_id, "[global] The partner ID given to you by @Pay", :type => :integer
17
+ opt :environment, "[global] The environment you want to generate buttons for. Currently sandbox or production", :default => 'production', :type => :string
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
20
+
21
+ # Per Token
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. Incomptible when `type` is 'site'", :type => :string
24
+
25
+ opt :amount, "[token] The amount a user should be charged for the transaction you're generating a token for", :default => 5.0
26
+ opt :user_data, "[token] Data to pass back as a reference", :type => :string
27
+ opt :expires, "[token] Expiration date for token, integer value of seconds since epoch", :type => :integer
28
+
29
+ # Site Token Specific
30
+ opt :header_user_agent, "[site-token] The HTTP_USER_AGENT from the client's request header (if `type` is 'site')", :type => :string
31
+ opt :header_accept_language, "[site-token] The HTTP_ACCEPT_LANGUAGE from the client's request header (if `type` is 'site')", :type => :string
32
+ opt :header_accept_charset, "[site-token] The HTTP_ACCEPT_CHARSET from the client's request header (if `type` is 'site')", :type => :string
33
+ opt :ip_address, "[site-token] The IP address of the token recipient (if `type` is 'site')", :type => :string
54
34
  end
55
35
 
36
+ Trollop::die :amount, "must not be negative" if $opts[:amount] < 0
37
+ Trollop::die :private_key, "required" if $opts[:private_key].nil?
38
+ Trollop::die :partner_id, "required" if $opts[:partner_id].nil?
56
39
 
57
- class ClientRunner
58
- OPTIONS = %w(expires group amount)
59
- HEADERS = %w(HTTP_USER_AGENT HTTP_ACCEPT_LANGUAGE HTTP_ACCEPT_CHARSET)
60
- EMAIL = /[\w\d\.]+@[\w\.]+[\w]+/
61
- CARD = /.*=$/
40
+ module Args
41
+ class Main
42
+ def to_hash
43
+ read_from_file.update(read_from_cli)
44
+ end
62
45
 
63
- def initialize(args)
64
- @config = Arguments.new
65
- @session = AtPay::Session.new(@config.values)
66
- @options = {}
67
- @site_params = [{}]
68
- @targets = []
46
+ def tokens
47
+ @token_set ||= TokenSet.new
48
+ end
49
+
50
+ private
51
+ def read_from_file
52
+ {} || (YAML.load_file($opts[:config]) if $opts[:config])
53
+ end
69
54
 
70
- parse args
55
+ def read_from_cli
56
+ %w(
57
+ private_key
58
+ public_key
59
+ partner_id
60
+ environment
61
+ ).inject({}) { |h,v| h[v]=$opts[v.to_sym]; h }
62
+ end
71
63
  end
72
64
 
73
- # Parse our arguments for all of our values
74
- def parse(args)
75
- OPTIONS.each do |option|
76
- @options[option.to_sym] = args[args.index(option) + 1] unless args.grep(option).empty?
65
+ class TokenSet
66
+ def next_token
67
+ if cli?
68
+ cli
69
+ else
70
+ stdin
71
+ end
77
72
  end
78
73
 
79
- site_params args if ARGV[0] == 'site_token'
80
- convert_amounts
81
- convert_expiration
82
- get_emails args
83
- get_cards args
84
-
85
- unless @options[:card] or @options[:email]
86
- puts USAGE and exit
74
+ private
75
+ def cli?
76
+ ($opts[:card] or $opts[:email]) and $opts[:type]
87
77
  end
88
- end
89
78
 
90
- # Build our list of email addresses to generate tokens for
91
- def get_emails(args)
92
- return unless args.index('targets')
79
+ def cli
80
+ return nil if @cli_read
81
+ @cli_read = true
93
82
 
94
- args[args.index('targets') + 1].split(' ')[0].match(EMAIL) ? @options[:email] = args[(args.index('targets') + 1)].split(' ') : @options[:email] = File.read(args[args.index('targets') + 1]).split("\n")
95
- end
96
-
97
- # Grab all the card tokens
98
- def get_cards(args)
99
- return unless args.index('cards')
83
+ $opts
84
+ end
100
85
 
101
- args[args.index('cards') + 1].split(' ')[0].match(CARD) ? @options[:card] = args[(args.index('cards') + 1)].split(' ') : @options[:card] = File.read(args[args.index('cards') + 1]).split("\n")
102
- end
86
+ def csv
87
+ @csv ||= CSV.new($stdin, :headers => true)
88
+ end
103
89
 
104
- # Need expiration as an integer
105
- def convert_expiration
106
- @options[:expires] = @options[:expires].to_i if @options[:expires]
90
+ def stdin
91
+ unless csv.eof?
92
+ csv.shift.to_hash
93
+ end
94
+ end
107
95
  end
96
+ end
108
97
 
109
- # Convert any amounts to floats.
110
- def convert_amounts
111
- @options[:amount] = @options[:amount].to_f if @options[:amount]
112
- @options[:amount] = @options[:group].split(' ').map(&:to_f) if @options[:group]
113
-
114
- @options.delete :group
98
+ class Generator
99
+ def initialize(config)
100
+ @config = config
115
101
  end
116
102
 
117
- # Check our input for site params.
118
- def site_params(args)
119
- if args.grep('addr').empty?
120
- puts "You must provide an IP Address for a site token.\n" + USAGE
121
- exit
122
- end
123
-
124
- @site_params[1] = args[args.index('addr') + 1]
103
+ def session
104
+ options = @config.to_hash
125
105
 
126
- headers(args)
106
+ @session ||= AtPay::Session.new({
107
+ :private_key => options["private_key"],
108
+ :public_key => options["public_key"],
109
+ :partner_id => options["partner_id"].to_i,
110
+ :environment => options["environment"].to_sym
111
+ })
127
112
  end
128
113
 
129
- def headers(args)
130
- if args.grep('user_agent').empty? or args.grep('charset').empty? or args.grep('lang').empty?
131
- puts "You must provide a user_agent, charset, and lang for a site token.\n" + USAGE
132
- exit
133
- end
134
-
135
- @site_params[0][HEADERS[0]] = args[args.index('user_agent') + 1]
136
- @site_params[0][HEADERS[1]] = args[args.index('lang') + 1]
137
- @site_params[0][HEADERS[2]] = args[args.index('charset') + 1]
114
+ def row_option_check(options)
115
+ Trollop::die :card, "must be present for site tokens" if site? and options[:card].nil?
116
+ Trollop::die :header_user_agent, "must be present for site_tokens" if site? and options[:header_user_agent].nil?
117
+ Trollop::die :header_accept_language, "must be present for site_tokens" if site? and options[:header_accept_language].nil?
118
+ Trollop::die :header_accept_charset, "must be present for site_tokens" if site? and options[:header_accept_charset].nil?
119
+ Trollop::die :ip_address, "must be present for site_tokens" if site? and options[:ip_address].nil?
120
+ Trollop::die :email, "or card must be present for all rows" if email? and (options[:card].nil? and options[:email].nil?)
121
+ Trollop::die :amount, "must be present" if options[:amount].nil?
138
122
  end
139
123
 
140
- # Generate multiple site tokens
141
- def site_tokens
142
- options = @options.clone
124
+ def next
125
+ return unless options=next_config
126
+ options[:amount] = options[:amount].to_f
143
127
 
144
- @options[:card].each_with_index do |card, index|
145
- options[:card] = card
146
- options[:email] = @options[:email][index] if @options[:email]
128
+ row_option_check(options)
147
129
 
148
- site_token options
149
- end
150
- end
130
+ security_key = session.security_key(options)
151
131
 
152
- # Generate a site token
153
- def site_token(options = @options)
154
- if options[:card].is_a? Array
155
- site_tokens
156
- return
157
- end
158
-
159
- keys = security_key(options)
160
-
161
- if keys.is_a? Array
162
- puts keys.map { |key| key.site_token @site_params[1], @site_params[0] }
163
- else
164
- puts keys.site_token @site_params[1], @site_params[0]
132
+ if email?
133
+ security_key.email_token
134
+ elsif site?
135
+ security_key.site_token
165
136
  end
166
137
  end
167
138
 
168
- # Generate multiple email tokens
169
- def email_tokens
170
- options = @options.clone
171
-
172
- @options[:email].each_with_index do |email, index|
173
- options[:email] = email
174
- options[:card] = @options[:card][index] if @options[:card]
139
+ private
140
+ def next_config
141
+ options = @config.tokens.next_token
175
142
 
176
- email_token options
177
- end
143
+ options.inject({}){|h,(k,v)|
144
+ h[k.to_sym] = v; h
145
+ } if options
178
146
  end
179
147
 
180
- # Generate an email token
181
- def email_token(options = @options)
182
- if options[:email].is_a? Array
183
- email_tokens
184
- return
185
- end
186
-
187
- keys = security_key(options)
188
-
189
- if keys.is_a? Array
190
- puts keys.map { |key| key.email_token }
191
- else
192
- puts keys.email_token
193
- end
148
+ def email?
149
+ $opts[:type] == "email"
194
150
  end
195
151
 
196
- # Get a security key object we can ask to generate keys for us.
197
- def security_key(options = @options)
198
- @session.security_key(options)
152
+ def site?
153
+ $opts[:type] == "site"
199
154
  end
200
155
  end
201
156
 
157
+ config = Args::Main.new
158
+ generator = Generator.new(config)
202
159
 
203
- operation = ARGV[0]
204
- arguments = ARGV[1..-1]
205
-
206
- unless operation
207
- puts Usage::USAGE
208
- exit
209
- end
210
-
211
- unless arguments.length > 0 and arguments.length % 2 == 0
212
- puts Usage::USAGE
213
- exit
160
+ while token=generator.next
161
+ puts token
214
162
  end
215
-
216
- runner = ClientRunner.new arguments
217
-
218
- runner.send operation
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: 1.0.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Kassemi
@@ -39,8 +39,22 @@ dependencies:
39
39
  - - '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: trollop
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  description: Client interface for the @Pay API, key generation for performance optimization
43
- email: james@atpay.com
57
+ email: dev@atpay.com
44
58
  executables:
45
59
  - atpay_tokens
46
60
  extensions: []