plaid-kilt 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.document +5 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +78 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +157 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/design/plaid_flows_connect.png +0 -0
- data/design/plaid_user_set_up.png +0 -0
- data/lib/plaid.rb +35 -0
- data/lib/plaid/client/balance.rb +15 -0
- data/lib/plaid/client/body.rb +101 -0
- data/lib/plaid/client/client.rb +89 -0
- data/lib/plaid/client/configuration.rb +79 -0
- data/lib/plaid/client/connect.rb +67 -0
- data/lib/plaid/client/entity.rb +16 -0
- data/lib/plaid/client/followup.rb +15 -0
- data/lib/plaid/client/thin_client.rb +60 -0
- data/lib/plaid/plaid_error.rb +38 -0
- data/lib/plaid/plaid_object.rb +33 -0
- data/lib/plaid/plaid_response.rb +80 -0
- data/lib/plaid/scaffold/institution.rb +26 -0
- data/lib/plaid/scaffold/scaffold.rb +39 -0
- data/lib/plaid/text/exposition.rb +33 -0
- data/test/helper.rb +18 -0
- data/test/test_plaid.rb +7 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5b97a9853fe6fc505a415b82c258f6d2962c1fb2
|
4
|
+
data.tar.gz: f804262388591a3f8f37af71e3133de10bde95d6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3a6e46925739f73d5a6710f0619c49b4fc20a6d207d46bb450096f9e2817a3b1ae6bcfa6110a49c398cc52279b5ae6e1e7696b9e4cefbe6c8c0664208225f981
|
7
|
+
data.tar.gz: 827cb24aacd8442693ea1d1e469b132b67cacd0410e3ee98011fff6c6b0e1a15718de1cc5031c2eab3f054dc4e750309b9cfa3d284350e3d31d756704a758cfc
|
data/.DS_Store
ADDED
Binary file
|
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "rdoc", "~> 3.12"
|
11
|
+
gem "bundler", "~> 1.0"
|
12
|
+
gem "jeweler", "~> 1.8.7"
|
13
|
+
end
|
14
|
+
|
15
|
+
gem 'httparty'
|
16
|
+
gem 'yard'
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (4.0.3)
|
5
|
+
i18n (~> 0.6, >= 0.6.4)
|
6
|
+
minitest (~> 4.2)
|
7
|
+
multi_json (~> 1.3)
|
8
|
+
thread_safe (~> 0.1)
|
9
|
+
tzinfo (~> 0.3.37)
|
10
|
+
addressable (2.3.5)
|
11
|
+
atomic (1.1.14)
|
12
|
+
builder (3.2.2)
|
13
|
+
faraday (0.8.8)
|
14
|
+
multipart-post (~> 1.2.0)
|
15
|
+
git (1.2.6)
|
16
|
+
github_api (0.10.1)
|
17
|
+
addressable
|
18
|
+
faraday (~> 0.8.1)
|
19
|
+
hashie (>= 1.2)
|
20
|
+
multi_json (~> 1.4)
|
21
|
+
nokogiri (~> 1.5.2)
|
22
|
+
oauth2
|
23
|
+
hashie (2.0.5)
|
24
|
+
highline (1.6.20)
|
25
|
+
httparty (0.12.0)
|
26
|
+
json (~> 1.8)
|
27
|
+
multi_xml (>= 0.5.2)
|
28
|
+
httpauth (0.2.0)
|
29
|
+
i18n (0.6.9)
|
30
|
+
jeweler (1.8.8)
|
31
|
+
builder
|
32
|
+
bundler (~> 1.0)
|
33
|
+
git (>= 1.2.5)
|
34
|
+
github_api (= 0.10.1)
|
35
|
+
highline (>= 1.6.15)
|
36
|
+
nokogiri (= 1.5.10)
|
37
|
+
rake
|
38
|
+
rdoc
|
39
|
+
json (1.8.1)
|
40
|
+
jwt (0.1.8)
|
41
|
+
multi_json (>= 1.5)
|
42
|
+
minitest (4.7.5)
|
43
|
+
multi_json (1.8.4)
|
44
|
+
multi_xml (0.5.5)
|
45
|
+
multipart-post (1.2.0)
|
46
|
+
nokogiri (1.5.10)
|
47
|
+
oauth2 (0.9.2)
|
48
|
+
faraday (~> 0.8)
|
49
|
+
httpauth (~> 0.2)
|
50
|
+
jwt (~> 0.1.4)
|
51
|
+
multi_json (~> 1.0)
|
52
|
+
multi_xml (~> 0.5)
|
53
|
+
rack (~> 1.2)
|
54
|
+
rack (1.5.2)
|
55
|
+
rake (10.1.1)
|
56
|
+
rdoc (3.12.2)
|
57
|
+
json (~> 1.4)
|
58
|
+
shoulda (3.5.0)
|
59
|
+
shoulda-context (~> 1.0, >= 1.0.1)
|
60
|
+
shoulda-matchers (>= 1.4.1, < 3.0)
|
61
|
+
shoulda-context (1.1.6)
|
62
|
+
shoulda-matchers (2.4.0)
|
63
|
+
activesupport (>= 3.0.0)
|
64
|
+
thread_safe (0.1.3)
|
65
|
+
atomic
|
66
|
+
tzinfo (0.3.38)
|
67
|
+
yard (0.8.7.3)
|
68
|
+
|
69
|
+
PLATFORMS
|
70
|
+
ruby
|
71
|
+
|
72
|
+
DEPENDENCIES
|
73
|
+
bundler (~> 1.0)
|
74
|
+
httparty
|
75
|
+
jeweler (~> 1.8.7)
|
76
|
+
rdoc (~> 3.12)
|
77
|
+
shoulda
|
78
|
+
yard
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 John Koisch
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
= plaid
|
2
|
+
|
3
|
+
Accessing the Plaid API using Ruby.
|
4
|
+
|
5
|
+
=== Version
|
6
|
+
|
7
|
+
Head is 0.5.1
|
8
|
+
|
9
|
+
== API
|
10
|
+
|
11
|
+
=== Grab a client
|
12
|
+
|
13
|
+
client = Plaid.client 'user@name.com','pass_word', 'amex'
|
14
|
+
|
15
|
+
Where the last value is the institution.
|
16
|
+
|
17
|
+
=== Connect
|
18
|
+
|
19
|
+
Plaid uses the "connect" Plaid API call to initiate the user flow and to access information.
|
20
|
+
|
21
|
+
info = client.connect <= gets information from Plaid
|
22
|
+
|
23
|
+
=== Responses
|
24
|
+
|
25
|
+
This gem returns values in response objects or error objects. This is not very ruby-esque,
|
26
|
+
but it helps to make sense of the Plaid environment as well as making HTTPParty consumable for a business.
|
27
|
+
|
28
|
+
Response objects are initialized when the client gets a valid response from plaid. In the case of non-MFA banks
|
29
|
+
|
30
|
+
r = client.connect
|
31
|
+
|
32
|
+
* r.raw_response <= the raw HTTPParty response from Plaid
|
33
|
+
* r.accounts <= Array of accounts associated with this institution for this user
|
34
|
+
* r.transactions <= Array of transactions associated with the accounts
|
35
|
+
* r.is_mfa? <= false for this request
|
36
|
+
* r.message <= "Successful retrieved information from bank"
|
37
|
+
* r.http_code <= 200 in this case
|
38
|
+
|
39
|
+
Accounts and Transactions are objects that follow the JSON from Plaid. Thus you can expect to see
|
40
|
+
|
41
|
+
r.transactions[66].category_id <= "52544965f71e87d007000119"
|
42
|
+
r.transactions[66].name <= "Online Payment Processed"
|
43
|
+
r.accounts[2].institution_type <= "fake_institution"
|
44
|
+
r.accounts[2].balance["current"] <= 8.98 (which ruby infers as a double)
|
45
|
+
|
46
|
+
More explicitly
|
47
|
+
|
48
|
+
r.accounts[2].inspect
|
49
|
+
|
50
|
+
"#<PlaidObject:0x007f92853ca770 @type=\"credit\", @_id=\"52db1be4be13cbc36e000006\", @_item=\"52af631671c3bd1b25000064\", @_user=\"52af630f71c3bd1b25000063\", @balance={\"available\"=>3721, \"current\"=>8.98}, @meta={\"limit\"=>3500, \"name\"=>\"Plaid Credit Card\", \"number\"=>\"93004\"}, @institution_type=\"fake_institution\">"
|
51
|
+
|
52
|
+
=== Errors
|
53
|
+
|
54
|
+
Errors use the gem's PlaidError object
|
55
|
+
|
56
|
+
client = Plaid.client 'user@name.com','pass_word_xyz', 'amex'
|
57
|
+
r = client.connect
|
58
|
+
|
59
|
+
* r.http_code <= 402
|
60
|
+
* r.plaid_code <= Plaid's internal error code (https://plaid.com/expand#Response_Code_Detail)
|
61
|
+
* r.error_message <= "Error"
|
62
|
+
* r.resolution <= "The username or password provided were not correct."
|
63
|
+
* r.raw_response <= the raw HTTPParty response
|
64
|
+
|
65
|
+
More explicitly
|
66
|
+
|
67
|
+
r = client.connect
|
68
|
+
|
69
|
+
"#<PlaidError:0x007f928513d638 @code=\"1200\", @message=\"Error\", @resolve=\"The username or password provided were not correct.\", @response=#<HTTParty::Response:0x7f928513d318 parsed_response={\"code\"=>1200, \"message\"=>\"invalid credentials\", \"resolve\"=>\"The username or password provided were not correct.\"}, @response=#<Net::HTTPPaymentRequired 402 Payment Required readbody=true>, @headers={\"content-type\"=>[\"application/json; charset=utf-8\"], \"date\"=>[\"Sat, 15 Mar 2014 17:31:46 GMT\"], \"x-powered-by\"=>[\"Express\"], \"content-length\"=>[\"109\"], \"connection\"=>[\"Close\"]}>>"
|
70
|
+
|
71
|
+
=== MFA
|
72
|
+
|
73
|
+
MFA requires some management of user flow, which is why this gem tries to make the returns / errors from API calls
|
74
|
+
explicit. If it seems heavyweight to you, it is because the MFA process is a heavyweight process. Plaid does a
|
75
|
+
better job managing it than some others, but if you are going to use Plaid extensively,
|
76
|
+
then you are going to have to cope with MFA. See the wiki for more information.
|
77
|
+
|
78
|
+
https://github.com/jkoisch/plaid/wiki/MFA
|
79
|
+
|
80
|
+
These two diagrams go through user set up and user flow with MFA, respectively.
|
81
|
+
|
82
|
+
https://github.com/jkoisch/plaid/blob/master/design/plaid_user_set_up.png
|
83
|
+
https://github.com/jkoisch/plaid/blob/master/design/plaid_flows_connect.png
|
84
|
+
|
85
|
+
=== Raw response
|
86
|
+
|
87
|
+
You can, if you would rather, ignore the PlaidResponse objects.
|
88
|
+
|
89
|
+
#config/initializers/plaid.rb
|
90
|
+
config.save_full_response = true
|
91
|
+
|
92
|
+
#when you get your responses
|
93
|
+
x = client.connect
|
94
|
+
x.raw_response <= the raw http response to the request. Have fun.
|
95
|
+
|
96
|
+
=== Thin Client
|
97
|
+
|
98
|
+
The Plaid gem also has a thin_client for some secure followup operations:
|
99
|
+
|
100
|
+
thin_client = Plaid.thin_client "me@example.com", "chase", "access_token"
|
101
|
+
|
102
|
+
This client can be used where user credentials are NOT needed, but you still want to access scecure information on
|
103
|
+
the Plaid side of things:
|
104
|
+
|
105
|
+
thin_client.followup <= GET operation to get account and transaction information
|
106
|
+
thin_client.get_balance <= GET operation to receive account balances
|
107
|
+
thin_client.get_entity("unique_plaid_entity") <= Entity context information
|
108
|
+
|
109
|
+
== Configuration
|
110
|
+
|
111
|
+
You need to configure access through your own initializers using the values you receive from Plaid.
|
112
|
+
|
113
|
+
#config/initializers/plaid.rb
|
114
|
+
Plaid.configure do |config|
|
115
|
+
config.client_id = 'JUNK'
|
116
|
+
config.secret = 'JUNK'
|
117
|
+
config.endpoint = 'https://tartan.plaid.com/'
|
118
|
+
config.certpath = 'ca-bundle.crt'
|
119
|
+
config.headers = {'Content-Type'=>'application/x-www-form-urlencoded'}
|
120
|
+
config.webhook_address = 'http://If.You.Need.To.You.Can.Use/plaid_webhook/antennas'
|
121
|
+
config.save_full_response = false
|
122
|
+
end
|
123
|
+
|
124
|
+
== Additional Client Methods
|
125
|
+
|
126
|
+
The Plaid Client is not-quite-skinny so that it can handle various parts of the returns from the Plaid API. This is to
|
127
|
+
support alternate user flows or user handling in implementation.
|
128
|
+
|
129
|
+
The Plaid Client supports the following attr_readers, with the attribute settings handled through normal client
|
130
|
+
management.
|
131
|
+
|
132
|
+
client.settings
|
133
|
+
client.username
|
134
|
+
client.password
|
135
|
+
client.institution
|
136
|
+
client.endpoint
|
137
|
+
client.secret
|
138
|
+
client.access_token
|
139
|
+
client.mfa_type
|
140
|
+
client.mfa_message
|
141
|
+
client.mfa_return <= an array of the MFA returns from Plaid
|
142
|
+
|
143
|
+
== Contributing to the plaid gem
|
144
|
+
|
145
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
146
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
147
|
+
* Fork the project.
|
148
|
+
* Start a feature/bugfix branch.
|
149
|
+
* Commit and push until you are happy with your contribution.
|
150
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
151
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
152
|
+
|
153
|
+
== Copyright
|
154
|
+
|
155
|
+
Copyright (c) 2014 John Koisch. See LICENSE.txt for
|
156
|
+
further details.
|
157
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "plaid-kilt"
|
18
|
+
gem.homepage = "http://github.com/jkoisch/plaid"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Access the Plaid API using Ruby}
|
21
|
+
gem.description = %Q{Access the Plaid API using Rubyre}
|
22
|
+
gem.email = "jk@cloudsway.com"
|
23
|
+
gem.authors = ["John Koisch"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => :test
|
36
|
+
|
37
|
+
require 'rdoc/task'
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "plaid #{version}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.5.1
|
Binary file
|
Binary file
|
data/lib/plaid.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Plaid
|
2
|
+
class << self
|
3
|
+
def configure(&block)
|
4
|
+
Plaid::Client::Base.configure(&block)
|
5
|
+
end
|
6
|
+
|
7
|
+
# client for initializing access through Plaid
|
8
|
+
def client(user, email, password, institution)
|
9
|
+
Plaid::Client::Base.new(user, email, password, institution)
|
10
|
+
end
|
11
|
+
|
12
|
+
# a special thin client for accessing Plaid without credentials securely
|
13
|
+
def thin_client(e_mail, institution, access_token)
|
14
|
+
Plaid::Client::ThinClient.new(e_mail, institution, access_token)
|
15
|
+
end
|
16
|
+
|
17
|
+
#scaffolding are general purpose tools for dealing with Plaid
|
18
|
+
def scaffold
|
19
|
+
Plaid::Scaffold::Base
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'plaid/client/client'
|
25
|
+
require 'plaid/client/thin_client'
|
26
|
+
require 'plaid/client/configuration'
|
27
|
+
require 'plaid/client/connect'
|
28
|
+
require 'plaid/client/entity'
|
29
|
+
require 'plaid/client/balance'
|
30
|
+
require 'plaid/client/followup'
|
31
|
+
require 'plaid/scaffold/scaffold'
|
32
|
+
require 'plaid/scaffold/institution'
|
33
|
+
require 'plaid/plaid_object'
|
34
|
+
require 'plaid/plaid_error'
|
35
|
+
require 'plaid/plaid_response'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
module Balances
|
4
|
+
include Plaid::Client::Configurations
|
5
|
+
|
6
|
+
def get_balance
|
7
|
+
body = body_retrieve
|
8
|
+
|
9
|
+
response = self.class.get('/balance', :query => body)
|
10
|
+
handle(response) { PlaidResponse.new(response, "Retrieved Balance") }
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
module Bodies
|
4
|
+
include Plaid::Client::Configurations
|
5
|
+
|
6
|
+
# Used before the organization is obtained and chosen by the user
|
7
|
+
def body
|
8
|
+
{
|
9
|
+
:client_id => self.client_id,
|
10
|
+
:secret => self.secret
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
# For accessing balances associated with an access_token via a GET
|
15
|
+
# * client_id
|
16
|
+
# * secret
|
17
|
+
# * access_token
|
18
|
+
# * institution type
|
19
|
+
# * email of the user
|
20
|
+
def body_retrieve
|
21
|
+
ret = Hash.new
|
22
|
+
ret[:access_token] = self.access_token
|
23
|
+
ret[:type] = self.institution
|
24
|
+
ret[:email] = self.email
|
25
|
+
ret.merge(body)
|
26
|
+
end
|
27
|
+
|
28
|
+
# the fundamental body object used in most calls to Plaid.
|
29
|
+
# * client_id
|
30
|
+
# * secret
|
31
|
+
# * institution_type
|
32
|
+
# * credentials
|
33
|
+
# * email
|
34
|
+
# * options {"list":true}
|
35
|
+
def body_original
|
36
|
+
ret = Hash.new
|
37
|
+
ret[:type] = self.institution
|
38
|
+
ret[:credentials] = {
|
39
|
+
"username" => self.username,
|
40
|
+
"password" => self.password
|
41
|
+
}
|
42
|
+
ret[:email] = 'me@example.com'
|
43
|
+
ret[:options] = options(nil,"list",true)
|
44
|
+
ret.merge(body)
|
45
|
+
end
|
46
|
+
|
47
|
+
def body_test
|
48
|
+
ret = hash.new
|
49
|
+
ret[:options] = options(nil,"pretty","true")
|
50
|
+
ret.merge(body_original)
|
51
|
+
end
|
52
|
+
|
53
|
+
#simple hash providing the entity_id to plaid.
|
54
|
+
def body_entity(entity_id)
|
55
|
+
{
|
56
|
+
:entity_id => entity_id,
|
57
|
+
:options => {"pretty"=>"true"}
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
#adds an mfa answer to the body.
|
62
|
+
#based on {#body}
|
63
|
+
def body_mfa(answer)
|
64
|
+
ret = Hash.new
|
65
|
+
ret[:mfa] = answer.to_s
|
66
|
+
ret[:access_token] = self.access_token
|
67
|
+
ret[:type] = self.institution
|
68
|
+
ret.merge(body)
|
69
|
+
end
|
70
|
+
|
71
|
+
#adds a webhook address to {#body_mfa}
|
72
|
+
def body_mfa_webhook(answer)
|
73
|
+
ret = Hash.new
|
74
|
+
ret[:options] = options(nil,"webhook", webhook_address )
|
75
|
+
ret.merge(body_mfa(answer))
|
76
|
+
end
|
77
|
+
|
78
|
+
def body_mfa_mode(mode)
|
79
|
+
ret = Hash.new
|
80
|
+
ret[:options] = options(nil, "send_method", mode)
|
81
|
+
ret[:access_token] = self.access_token
|
82
|
+
ret[:type] = self.institution
|
83
|
+
ret.merge(body)
|
84
|
+
end
|
85
|
+
|
86
|
+
def body_init_user
|
87
|
+
ret = Hash.new
|
88
|
+
ret[:options] = options(options(nil,"login",true),"webhook",webhook_address )
|
89
|
+
ret.merge(body_original)
|
90
|
+
end
|
91
|
+
|
92
|
+
#helper method to add options to an option hash
|
93
|
+
def options(original_hash=nil, key, value)
|
94
|
+
j = Hash.new
|
95
|
+
j[key] = value
|
96
|
+
j.merge(original_hash) unless original_hash.nil?
|
97
|
+
j
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
|
4
|
+
class Base
|
5
|
+
attr_accessor :mfa_response, :mfa_type, :mfa_message, :username, :password, :institution, :endpoint, :secret, :access_token, :is_mfa_initialized, :email
|
6
|
+
|
7
|
+
require 'plaid/client/configuration'
|
8
|
+
require 'plaid/client/connect'
|
9
|
+
require 'plaid/client/body'
|
10
|
+
require 'plaid/plaid_object'
|
11
|
+
require 'plaid/plaid_error'
|
12
|
+
require 'plaid/plaid_response'
|
13
|
+
require 'httparty'
|
14
|
+
include Plaid::Client::Configurations
|
15
|
+
include Plaid::Client::Logins
|
16
|
+
include Plaid::Client::Bodies
|
17
|
+
include HTTParty
|
18
|
+
|
19
|
+
base_uri endpoint
|
20
|
+
format :json
|
21
|
+
ssl_ca_file certpath
|
22
|
+
ssl_version :SSLv3
|
23
|
+
debug_output $stdout
|
24
|
+
|
25
|
+
def initialize(user, e_mail, pass_word, institution)
|
26
|
+
self.username = user
|
27
|
+
self.email = e_mail
|
28
|
+
self.password = pass_word
|
29
|
+
self.institution = institution
|
30
|
+
self.mfa_response ||= []
|
31
|
+
end
|
32
|
+
|
33
|
+
def settings
|
34
|
+
puts "Base URI: " + endpoint.to_s
|
35
|
+
puts "Cert: " + certpath.to_s
|
36
|
+
puts "User: " + self.username.to_s
|
37
|
+
puts "Email: " + self.email.to_s
|
38
|
+
puts "Plaid Client_id: " + self.client_id.to_s
|
39
|
+
puts "Webhook address: " + webhook_address
|
40
|
+
puts "Save full response: " + save_full_response.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
#generic method for handling the structure of the response. Only creates an error object if there is an error (business error) from Plaid.com. Yields to the block with calling function
|
44
|
+
def handle(response)
|
45
|
+
if response.code.eql? 200
|
46
|
+
self.mfa_type = nil
|
47
|
+
self.mfa_message = nil
|
48
|
+
self.is_mfa_initialized = false
|
49
|
+
yield(response)
|
50
|
+
elsif response.code.eql? 201 #mfa
|
51
|
+
mfa_201 = PlaidResponse.new(response, "MFA")
|
52
|
+
self.access_token = mfa_201.access_token
|
53
|
+
self.mfa_type = mfa_201.raw_response.type
|
54
|
+
self.mfa_response << mfa_201
|
55
|
+
self.mfa_message = mfa_201.message
|
56
|
+
self.is_mfa_initialized = mfa_201.is_mfa?
|
57
|
+
mfa_201
|
58
|
+
else
|
59
|
+
PlaidError.new(response, "Error")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#for testing through IRB
|
64
|
+
def secrets(client_id, secret)
|
65
|
+
self.client_id = client_id
|
66
|
+
self.secret = secret
|
67
|
+
"Set"
|
68
|
+
end
|
69
|
+
|
70
|
+
def is_mfa?
|
71
|
+
@is_mfa_initialized
|
72
|
+
end
|
73
|
+
|
74
|
+
def plaid_response_codes
|
75
|
+
{
|
76
|
+
200 => "Success",
|
77
|
+
201 => "MFA Required",
|
78
|
+
400 => "Bad Request",
|
79
|
+
401 => "Unauthorized",
|
80
|
+
402 => "Request Failed",
|
81
|
+
404 => "Cannot be Found",
|
82
|
+
500 => "Server Error"
|
83
|
+
}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
module Configurations
|
4
|
+
require 'active_support/concern'
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
#Plaid.com
|
9
|
+
add_config :endpoint
|
10
|
+
add_config :headers
|
11
|
+
|
12
|
+
#app
|
13
|
+
add_config :certpath
|
14
|
+
add_config :client_id
|
15
|
+
add_config :secret
|
16
|
+
add_config :webhook_address
|
17
|
+
add_config :save_full_response
|
18
|
+
|
19
|
+
# set default values
|
20
|
+
reset_config
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
def add_config(name)
|
26
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
27
|
+
|
28
|
+
def self.#{name}(value=nil)
|
29
|
+
@#{name} = value if value
|
30
|
+
return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
|
31
|
+
name = superclass.#{name}
|
32
|
+
return nil if name.nil? && !instance_variable_defined?("@#{name}")
|
33
|
+
@#{name} = name && !name.is_a?(Module) && !name.is_a?(Symbol) && !name.is_a?(Numeric) && !name.is_a?(TrueClass) && !name.is_a?(FalseClass) ? name.dup : name
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.#{name}=(value)
|
37
|
+
@#{name} = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def #{name}=(value)
|
41
|
+
@#{name} = value
|
42
|
+
end
|
43
|
+
|
44
|
+
def #{name}
|
45
|
+
value = @#{name} if instance_variable_defined?(:@#{name})
|
46
|
+
value = self.class.#{name} unless instance_variable_defined?(:@#{name})
|
47
|
+
if value.instance_of?(Proc)
|
48
|
+
value.arity >= 1 ? value.call(self) : value.call
|
49
|
+
else
|
50
|
+
value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
|
56
|
+
def configure
|
57
|
+
yield self
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# sets configuration to default
|
62
|
+
#
|
63
|
+
def reset_config
|
64
|
+
configure do |config|
|
65
|
+
|
66
|
+
config.client_id = 'JUNK'
|
67
|
+
config.secret = 'JUNK'
|
68
|
+
config.endpoint = 'https://tartan.plaid.com/'
|
69
|
+
config.certpath = 'ca-bundle.crt'
|
70
|
+
config.headers = {'Content-Type'=>'application/x-www-form-urlencoded'}
|
71
|
+
config.webhook_address = 'http://domain.com/plaid_webhook/antennas'
|
72
|
+
config.save_full_response = true
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
module Logins
|
4
|
+
include Plaid::Client::Configurations
|
5
|
+
|
6
|
+
#connects to the plaid api.
|
7
|
+
#this can be used to retrieve information, get the access token, and initialize a user.
|
8
|
+
#sets the access token on the {Plaid::Client::Base}
|
9
|
+
#@return {PlaidResponse}
|
10
|
+
def connect
|
11
|
+
body = body_original
|
12
|
+
|
13
|
+
response = self.class.post('/connect', :query => body)
|
14
|
+
|
15
|
+
handle(response) do |r|
|
16
|
+
plaid = PlaidResponse.new(r, "Successful retrieved information from bank")
|
17
|
+
self.access_token = plaid.access_token
|
18
|
+
plaid
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
#The basic way to submit MFA information to Plaid.
|
23
|
+
#Simply appends the answer into the parameters for submission.
|
24
|
+
#@return {PlaidResponse} or {PlaidError}
|
25
|
+
def connect_step(mfa_response)
|
26
|
+
body = body_mfa(mfa_response)
|
27
|
+
response = self.class.post('/connect/step', :query => body)
|
28
|
+
|
29
|
+
handle(response) { PlaidResponse.new(response, "Successful MFA submission - retrieved information from bank") }
|
30
|
+
end
|
31
|
+
|
32
|
+
#Submits an MFA answer to Plaid.
|
33
|
+
#Adds a webhook return address as a parameter.
|
34
|
+
#@return {PlaidResponse} or {PlaidError}
|
35
|
+
def connect_step_webhook(mfa_response)
|
36
|
+
body = body_mfa_webhook(mfa_response)
|
37
|
+
response = self.class.post('/connect/step', :query => body)
|
38
|
+
|
39
|
+
handle(response) { PlaidResponse.new(response, "Successful MFA submission - Webhook will notify when retrieved information from bank") }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Plaid's preferred way to initialize a user to their bank via the Plaid Proxy.
|
43
|
+
#
|
44
|
+
def connect_init_user
|
45
|
+
body = body_init_user
|
46
|
+
response = self.class.post('/connect', :query => body)
|
47
|
+
|
48
|
+
handle(response) { PlaidResponse.new(response, "Successfully added user; Wait on Webhook Response") }
|
49
|
+
end
|
50
|
+
|
51
|
+
def connect_filter_response
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def connect_step_specify_mode(mode)
|
56
|
+
body = body_mfa_mode(mode)
|
57
|
+
response = self.class.post('/connect/step', :query => body)
|
58
|
+
handle(response) { PlaidResponse.new(response, "Successful MFA mode submission - You will now be asked to
|
59
|
+
input your code.") }
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
module Entities
|
4
|
+
include Plaid::Client::Configurations
|
5
|
+
|
6
|
+
def get_entity(entity_id)
|
7
|
+
body = body_entity(entity_id)
|
8
|
+
|
9
|
+
response = self.class.get('/entity', :query => body)
|
10
|
+
|
11
|
+
handle(response) { PlaidResponse.new(response, "Retrieved Entity")}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
module Followups
|
4
|
+
include Plaid::Client::Configurations
|
5
|
+
|
6
|
+
#explicitly for following up after an init to retrieve updated information from Plaid
|
7
|
+
def followup
|
8
|
+
body = body_retrieve
|
9
|
+
response = self.class.get('/connect', :query => body)
|
10
|
+
|
11
|
+
handle(response) { PlaidResponse.new(response, "Successfully retrieved Transactions") }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Client
|
3
|
+
class ThinClient
|
4
|
+
attr_accessor :institution, :endpoint, :secret, :access_token, :email, :client_id
|
5
|
+
|
6
|
+
require 'plaid/client/configuration'
|
7
|
+
require 'plaid/client/followup'
|
8
|
+
require 'plaid/client/entity'
|
9
|
+
require 'plaid/client/balance'
|
10
|
+
require 'plaid/client/body'
|
11
|
+
require 'plaid/plaid_object'
|
12
|
+
require 'plaid/plaid_error'
|
13
|
+
require 'plaid/plaid_response'
|
14
|
+
require 'httparty'
|
15
|
+
include Plaid::Client::Configurations
|
16
|
+
include Plaid::Client::Bodies
|
17
|
+
include Plaid::Client::Entities
|
18
|
+
include Plaid::Client::Balances
|
19
|
+
include Plaid::Client::Followups
|
20
|
+
include HTTParty
|
21
|
+
|
22
|
+
base_uri endpoint
|
23
|
+
format :json
|
24
|
+
ssl_ca_file certpath
|
25
|
+
ssl_version :SSLv3
|
26
|
+
debug_output $stdout
|
27
|
+
|
28
|
+
def initialize(e_mail, institution, access_token)
|
29
|
+
self.email = e_mail
|
30
|
+
self.institution = institution
|
31
|
+
self.access_token = access_token
|
32
|
+
end
|
33
|
+
|
34
|
+
#for testing through IRB
|
35
|
+
def secrets(client_id, secret)
|
36
|
+
self.client_id = client_id
|
37
|
+
self.secret = secret
|
38
|
+
"Set"
|
39
|
+
end
|
40
|
+
|
41
|
+
def settings
|
42
|
+
puts "Base URI: " + endpoint.to_s
|
43
|
+
puts "Cert: " + certpath.to_s
|
44
|
+
puts "Email: " + self.email.to_s
|
45
|
+
puts "Plaid Client_id: " + self.client_id.to_s
|
46
|
+
puts "Webhook address: " + webhook_address
|
47
|
+
puts "Save full response: " + save_full_response.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
#generic method for handling the structure of the response. Only creates an error object if there is an error (business error) from Plaid.com. Yields to the block with calling function
|
51
|
+
def handle(response)
|
52
|
+
if response.code.eql? 200
|
53
|
+
yield(response)
|
54
|
+
else
|
55
|
+
PlaidError.new(response, "Error")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class PlaidError < PlaidObject
|
2
|
+
|
3
|
+
require 'plaid/plaid_object'
|
4
|
+
|
5
|
+
@error = nil
|
6
|
+
@message = nil
|
7
|
+
@response = nil
|
8
|
+
|
9
|
+
def initialize(response, message)
|
10
|
+
if response.parsed_response
|
11
|
+
super(response.parsed_response)
|
12
|
+
else
|
13
|
+
super(response)
|
14
|
+
end
|
15
|
+
@response = response
|
16
|
+
@message = message
|
17
|
+
end
|
18
|
+
|
19
|
+
def error_message
|
20
|
+
self.message
|
21
|
+
end
|
22
|
+
|
23
|
+
def http_code
|
24
|
+
@response.code if @response
|
25
|
+
end
|
26
|
+
|
27
|
+
def plaid_code
|
28
|
+
response.code
|
29
|
+
end
|
30
|
+
|
31
|
+
def resolution
|
32
|
+
self.resolve
|
33
|
+
end
|
34
|
+
|
35
|
+
def raw_response
|
36
|
+
@response if @response
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class PlaidObject
|
2
|
+
|
3
|
+
def initialize(hash)
|
4
|
+
hash.keys.each do |key|
|
5
|
+
self.class.send(:define_method, "#{key}") do
|
6
|
+
instance_variable_get("@#{key}")
|
7
|
+
end
|
8
|
+
|
9
|
+
if hash[key].is_a? Array
|
10
|
+
arr = []
|
11
|
+
hash[key].each do |chunk|
|
12
|
+
if chunk.is_a? Hash
|
13
|
+
arr << PlaidObject.new(chunk)
|
14
|
+
else
|
15
|
+
arr << chunk
|
16
|
+
end
|
17
|
+
end
|
18
|
+
instance_variable_set("@#{key}", arr)
|
19
|
+
elsif hash[key].is_a? Hash
|
20
|
+
h = hash[key]
|
21
|
+
instance_variable_set("@#{key}", h)
|
22
|
+
else
|
23
|
+
eval("@#{key} = '#{encode(hash[key].to_s)}'")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def encode(str)
|
30
|
+
str.gsub("'", "")
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class PlaidResponse
|
2
|
+
include Plaid::Client::Configurations
|
3
|
+
|
4
|
+
require 'plaid/plaid_object'
|
5
|
+
require 'plaid/client/configuration'
|
6
|
+
|
7
|
+
attr_reader :http_code, :mfa_message, :accounts, :transactions, :access_token
|
8
|
+
|
9
|
+
@response = nil
|
10
|
+
@message = "N/A"
|
11
|
+
@mfa_type
|
12
|
+
@mfa_message
|
13
|
+
@questions = nil
|
14
|
+
@mfa_modes = nil
|
15
|
+
@is_mfa_initialized = false
|
16
|
+
|
17
|
+
def initialize(response, message=nil)
|
18
|
+
@http_code = response.code
|
19
|
+
zed = PlaidObject.new(response)
|
20
|
+
|
21
|
+
if save_full_response.eql?(save_full_response)
|
22
|
+
@response = zed
|
23
|
+
end
|
24
|
+
|
25
|
+
unless message.eql?("MFA")
|
26
|
+
@accounts = zed.accounts
|
27
|
+
@transactions = zed.transactions
|
28
|
+
@is_mfa_initialized = false
|
29
|
+
else
|
30
|
+
manage_mfa_type(zed)
|
31
|
+
@is_mfa_initialized = true
|
32
|
+
end
|
33
|
+
|
34
|
+
@access_token = zed.access_token
|
35
|
+
@message = message if message
|
36
|
+
zed = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def raw_response
|
40
|
+
@response
|
41
|
+
end
|
42
|
+
|
43
|
+
def message
|
44
|
+
@message.eql?("MFA") ? @message + ": " + @mfa_message : @message
|
45
|
+
end
|
46
|
+
|
47
|
+
def mfa_type
|
48
|
+
@message.eql?("MFA") ? @mfa_type : "Not a response from an MFA request to a bank"
|
49
|
+
end
|
50
|
+
|
51
|
+
def is_mfa?
|
52
|
+
@is_mfa_initialized
|
53
|
+
end
|
54
|
+
|
55
|
+
def mfa_modes
|
56
|
+
@mfa_modes
|
57
|
+
end
|
58
|
+
|
59
|
+
def manage_mfa_type(zed)
|
60
|
+
@mfa_type = zed.type
|
61
|
+
|
62
|
+
if @mfa_type.eql?("device")
|
63
|
+
@mfa_message = zed.mfa["message"]
|
64
|
+
elsif @mfa_type.eql?("questions")
|
65
|
+
@questions ||= []
|
66
|
+
zed.mfa.each do |q|
|
67
|
+
@questions << q.question
|
68
|
+
end
|
69
|
+
@mfa_message = @questions.reverse.pop
|
70
|
+
elsif @mfa_type.eql?("list")
|
71
|
+
@mfa_modes ||= []
|
72
|
+
@mfa_message = "There are several ways to authenticate, or it will default to your email"
|
73
|
+
zed.mfa.each do |q|
|
74
|
+
@mfa_modes << q
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Scaffold
|
3
|
+
module Institutions
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def index_institutions
|
7
|
+
ret = []
|
8
|
+
response = self.get('/institutions')
|
9
|
+
response.each do |piece|
|
10
|
+
ret << PlaidObject.new(piece)
|
11
|
+
end
|
12
|
+
self.institutions = ret
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_institution(id)
|
16
|
+
response = self.get('/institutions/' + id.to_s)
|
17
|
+
PlaidObject.new(response)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.included(base)
|
22
|
+
base.extend(ClassMethods)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Scaffold
|
3
|
+
class Base
|
4
|
+
|
5
|
+
require 'plaid/scaffold/institution'
|
6
|
+
require 'plaid/client/configuration'
|
7
|
+
require 'plaid/plaid_object'
|
8
|
+
require 'plaid/plaid_error'
|
9
|
+
require 'plaid/plaid_response'
|
10
|
+
require 'httparty'
|
11
|
+
require 'singleton'
|
12
|
+
include Plaid::Scaffold::Institutions
|
13
|
+
include Plaid::Client::Configurations
|
14
|
+
include HTTParty
|
15
|
+
include Singleton
|
16
|
+
|
17
|
+
base_uri endpoint
|
18
|
+
format :json
|
19
|
+
ssl_ca_file certpath
|
20
|
+
ssl_version :SSLv3
|
21
|
+
debug_output $stdout
|
22
|
+
|
23
|
+
@@institutions ||= []
|
24
|
+
|
25
|
+
def self.institutions=(i)
|
26
|
+
@@institutions = i
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.institutions
|
30
|
+
if @@institutions.empty?
|
31
|
+
self.index_institutions rescue "There is something wrong with Plaid!"
|
32
|
+
end
|
33
|
+
|
34
|
+
@@institutions
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Plaid
|
2
|
+
module Text
|
3
|
+
class Narrative
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def introduction
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def submit_credentials
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def get_transaction
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def updating_institution_info
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def mfa
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'plaid'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
data/test/test_plaid.rb
ADDED
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: plaid-kilt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Koisch
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: shoulda
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: jeweler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.8.7
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.8.7
|
97
|
+
description: Access the Plaid API using Rubyre
|
98
|
+
email: jk@cloudsway.com
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files:
|
102
|
+
- LICENSE.txt
|
103
|
+
- README.rdoc
|
104
|
+
files:
|
105
|
+
- .DS_Store
|
106
|
+
- .document
|
107
|
+
- Gemfile
|
108
|
+
- Gemfile.lock
|
109
|
+
- LICENSE.txt
|
110
|
+
- README.rdoc
|
111
|
+
- Rakefile
|
112
|
+
- VERSION
|
113
|
+
- design/plaid_flows_connect.png
|
114
|
+
- design/plaid_user_set_up.png
|
115
|
+
- lib/plaid.rb
|
116
|
+
- lib/plaid/client/balance.rb
|
117
|
+
- lib/plaid/client/body.rb
|
118
|
+
- lib/plaid/client/client.rb
|
119
|
+
- lib/plaid/client/configuration.rb
|
120
|
+
- lib/plaid/client/connect.rb
|
121
|
+
- lib/plaid/client/entity.rb
|
122
|
+
- lib/plaid/client/followup.rb
|
123
|
+
- lib/plaid/client/thin_client.rb
|
124
|
+
- lib/plaid/plaid_error.rb
|
125
|
+
- lib/plaid/plaid_object.rb
|
126
|
+
- lib/plaid/plaid_response.rb
|
127
|
+
- lib/plaid/scaffold/institution.rb
|
128
|
+
- lib/plaid/scaffold/scaffold.rb
|
129
|
+
- lib/plaid/text/exposition.rb
|
130
|
+
- test/helper.rb
|
131
|
+
- test/test_plaid.rb
|
132
|
+
homepage: http://github.com/jkoisch/plaid
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 2.1.11
|
153
|
+
signing_key:
|
154
|
+
specification_version: 4
|
155
|
+
summary: Access the Plaid API using Ruby
|
156
|
+
test_files: []
|