plaid 1.4.3 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,173 +0,0 @@
1
- require_relative 'account/account'
2
- require_relative 'transaction/transaction'
3
- require_relative 'info/info'
4
- require 'plaid/util'
5
- require 'json'
6
- module Plaid
7
- class Plaid::User
8
- include Plaid::Util
9
-
10
- # Define user vars
11
- attr_accessor(:accounts, :transactions, :access_token, :type, :permissions, :api_res, :pending_mfa_questions, :info, :information)
12
-
13
- def initialize
14
- self.accounts = [], self.transactions = [], self.permissions = [], self.access_token = '', self.api_res = '', self.info = {}, self.information = Information.new
15
- end
16
-
17
- # Instantiate a new user with the results of the successful API call
18
- # Build an array of nested accounts, and return self if successful
19
- def new(res,api_level=nil)
20
- build_user(res,api_level)
21
- end
22
-
23
- def mfa_authentication(auth,type=nil)
24
- type = self.type if type.nil?
25
- auth_path = self.permissions.last + '/step'
26
- res = Plaid.post(auth_path,{mfa:auth,access_token:self.access_token,type:type})
27
- self.accounts = [], self.transactions = []
28
- build_user(res)
29
- end
30
-
31
- def select_mfa_method(selection,type=nil)
32
- type = self.type if type.nil?
33
- auth_path = self.permissions.last + '/step'
34
- res = Plaid.post(auth_path,{options:{send_method: selection}.to_json, access_token:self.access_token,type:type})
35
- build_user(res,self.permissions.last)
36
- end
37
-
38
- def get_auth
39
- if self.permissions.include? 'auth'
40
- res = Plaid.post('auth/get',{access_token:self.access_token})
41
- build_user(res)
42
- else
43
- false
44
- end
45
- end
46
-
47
- def get_connect(options=nil)
48
- if self.permissions.include? 'connect'
49
- payload = {access_token:self.access_token}
50
- payload.merge!(options) if options
51
- res = Plaid.post('connect/get',payload)
52
- build_user(res)
53
- else
54
- false
55
- end
56
- end
57
-
58
- def get_info
59
- if self.permissions.include? 'info'
60
- res = Plaid.secure_get('info',self.access_token)
61
- build_user(res)
62
- else
63
- false
64
- end
65
- end
66
-
67
- def update_info(username,pass,pin=nil)
68
- if self.permissions.include? 'info'
69
- payload = {username:username,password:pass,access_token:self.access_token}
70
- payload.merge!({pin:pin}) if pin
71
- res = Plaid.patch('info',payload)
72
- puts res
73
- build_user(res)
74
- else
75
- false
76
- end
77
- end
78
-
79
- def update_balance
80
- res = Plaid.post('balance',{access_token:self.access_token})
81
- build_user(res)
82
- end
83
-
84
- def upgrade(api_level=nil)
85
- if api_level.nil?
86
- api_level = 'auth' unless self.permissions.include? 'auth'
87
- api_level = 'connect' unless self.permissions.include? 'connect'
88
- end
89
- res = Plaid.post('upgrade',{access_token:self.access_token,upgrade_to:api_level})
90
- self.accounts = [], self.transactions = []
91
- build_user(res)
92
- end
93
-
94
- def delete_user
95
- Plaid.delete('info',{access_token:self.access_token})
96
- end
97
-
98
- protected
99
-
100
- def build_user(res,api_level=nil)
101
- begin
102
- if res[:msg].nil?
103
- populate_user(self,res,api_level)
104
- clean_up_user(self)
105
- else
106
- set_mfa_request(self,res,api_level)
107
- end
108
- rescue => e
109
- error_handler(e)
110
- else
111
- self
112
- end
113
- end
114
-
115
- # Instantiate and build a new account object, return this to the accounts array
116
- def new_account(res)
117
- account = Account.new
118
- account.new(res)
119
- end
120
-
121
- # Instantiate and build a new account object, return this to the accounts array
122
- def new_transaction(res)
123
- transaction = Transaction.new
124
- transaction.new(res)
125
- end
126
-
127
- private
128
-
129
- def clean_up_user(user)
130
- user.accounts.reject! { |c| !c.instance_of? Plaid::Account }
131
- user
132
- end
133
-
134
- def set_mfa_request(user,res,api_level)
135
- user.access_token = res[:body]['access_token']
136
- user.pending_mfa_questions = res[:body]
137
- user.api_res = res[:msg]
138
- user.permissions << api_level unless self.permissions.include? api_level && api_level.nil?
139
- end
140
-
141
- def populate_user(user,res,api_level)
142
- res['accounts'].each do |account|
143
- if user.accounts.any? { |h| h == account['_id'] }
144
- owned_account = user.accounts.find { |h| h == account['_id'] }
145
- owned_account.new(account)
146
- else
147
- user.accounts << new_account(account)
148
- end
149
- end if res['accounts']
150
-
151
- res['transactions'].each do |transaction|
152
- if user.transactions.any? { |t| t == transaction['_id'] }
153
- owned_transaction = user.transactions.find { |h| h == transaction['_id'] }
154
- owned_transaction.new(transaction)
155
- else
156
- user.transactions << new_transaction(transaction)
157
- end
158
- end if res['transactions']
159
-
160
- user.permissions << api_level unless user.permissions.include? api_level && api_level.nil?
161
- user.pending_mfa_questions = ''
162
- user.information.update_info(res['info']) if res['info']
163
- user.api_res = 'success'
164
-
165
- # TODO: Remove the following line when upgrading to V-2
166
- user.info.merge!(res['info']) if res['info']
167
- # End TODO
168
- user.access_token = res['access_token'].split[0]
169
- user.type = res['access_token'].split[1]
170
- end
171
-
172
- end
173
- end
data/lib/plaid/util.rb DELETED
@@ -1,120 +0,0 @@
1
- require 'net/http'
2
- require 'json'
3
- require 'uri'
4
- module Plaid
5
- module Util
6
-
7
- def post(path,options={})
8
- uri = build_uri(path)
9
- options.merge!({client_id: self.instance_variable_get(:'@customer_id') ,secret: self.instance_variable_get(:'@secret')})
10
- res = Net::HTTP.post_form(uri,options)
11
- parse_response(res)
12
- end
13
-
14
- def get(path,id=nil)
15
- uri = build_uri(path,id)
16
- res = Net::HTTP.get(uri)
17
- parse_get_response(res)
18
- end
19
-
20
- def secure_get(path,access_token,options={})
21
- uri = build_uri(path)
22
- options.merge!({access_token:access_token})
23
- req = Net::HTTP::Get.new(uri)
24
- req.body = URI.encode_www_form(options) if options
25
- req.content_type = 'multipart/form-data'
26
- res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
27
- parse_response(res)
28
- end
29
-
30
- def patch(path,options={})
31
- uri = build_uri(path)
32
- options.merge!({client_id: self.instance_variable_get(:'@customer_id') ,secret: self.instance_variable_get(:'@secret')})
33
- req = Net::HTTP::Patch.new(uri)
34
- req.body = URI.encode_www_form(options) if options
35
- req.content_type = 'multipart/form-data'
36
- res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
37
- parse_response(res)
38
- end
39
-
40
- def delete(path,options={})
41
- uri = build_uri(path)
42
- options.merge!({client_id: self.instance_variable_get(:'@customer_id') ,secret: self.instance_variable_get(:'@secret')})
43
- req = Net::HTTP::Delete.new(uri)
44
- req.body = URI.encode_www_form(options) if options
45
- req.content_type = 'multipart/form-data'
46
- Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
47
- end
48
-
49
- def error_handler(err,res=nil)
50
- case err
51
- when 'Bad Request'
52
- puts res.body
53
- raise 'The request was malformed. Did you check the API docs?'
54
- when 'Unauthorized'
55
- raise 'Access denied: Try using the correct credentials.'
56
- when 'Request Failed'
57
- raise 'Request Failed'
58
- when 'Not Found'
59
- raise 'Not Found'
60
- when 'Institution not supported'
61
- raise 'Institution not supported'
62
- when 'Corrupted token'
63
- raise 'It appears that the access token has been corrupted'
64
- else
65
- raise err
66
- end
67
- end
68
-
69
- protected
70
-
71
- def build_uri(path,option=nil)
72
- path = path + '/' + option unless option.nil?
73
- URI.parse(self.instance_variable_get(:'@environment_location') + path)
74
- end
75
-
76
- private
77
-
78
- def parse_response(res)
79
- body = JSON.parse(res.body)
80
- case res.code.delete('.').to_i
81
- when 200
82
- return body
83
- when 201
84
- return { msg: 'Requires further authentication', body: body}
85
- when 400
86
- error_handler('Bad Request',res)
87
- when 401
88
- error_handler('Institution not supported',res) if body['code'] == 1108
89
- error_handler('Corrupted token',res) if body['code'] == 1105
90
- error_handler('Not Found',res) if body['code'] == 1501
91
- error_handler('Unauthorized',res)
92
- when 402
93
- return {msg: 'User account is locked', body: body} if body['code'] == 1205
94
- error_handler('Request Failed', res)
95
- when 404
96
- error_handler('Not Found',res)
97
- else
98
- error_handler('Server Error',res)
99
- end
100
- end
101
-
102
- def parse_get_response(res)
103
- body = JSON.parse(res)
104
- if body.class == Array
105
- body
106
- else
107
- if body['code'].nil?
108
- body
109
- else
110
- if body['code'] == 1301 || body['code'] == 1401 || body['code'] == 1501 || body['code'] == 1601
111
- error_handler('Not Found',body)
112
- else
113
- body
114
- end
115
- end
116
- end
117
- end
118
-
119
- end
120
- end
@@ -1,113 +0,0 @@
1
- require 'spec_helper.rb'
2
- # Authentication flow specs - returns Plaid::User
3
- describe '.add_user' do
4
-
5
- Plaid.config do |p|
6
- p.customer_id = 'test_id'
7
- p.secret = 'test_secret'
8
- p.environment_location = 'https://tartan.plaid.com/'
9
- end
10
-
11
- context 'has correct credentials for single factor auth, authenticates to the connect level of api access' do
12
- user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
13
- it { expect(user.accounts.empty?).to be_falsey }
14
- end
15
-
16
- context 'has correct credentials for single factor auth, authenticates to the auth level of api access' do
17
- user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
18
- it { expect(user.accounts[0].numbers.nil?).to be_falsey }
19
- end
20
-
21
- context 'has correct credentials for single factor auth, authenticates to the info level of api access' do
22
- user = Plaid.add_user('info','plaid_test','plaid_good','wells')
23
- it { expect(user.info).to be_truthy }
24
- end
25
-
26
- context 'has correct username, but incorrect password for single factor auth under auth level of api access' do
27
- it { expect{Plaid.add_user('auth','plaid_test','plaid_bad','wells')}.to raise_error }
28
- end
29
-
30
- context 'has incorrect username under auth level of api access' do
31
- it { expect{Plaid.add_user('auth','plaid_bad','plaid_bad','wells')}.to raise_error }
32
- end
33
-
34
- context 'has correct username, but incorrect password for single factor auth under connect level of api access' do
35
- it { expect{Plaid.add_user('connect','plaid_test','plaid_bad','wells')}.to raise_error }
36
- end
37
-
38
- context 'has incorrect username under connect level of api access' do
39
- it { expect{Plaid.add_user('connect','plaid_bad','plaid_bad','wells')}.to raise_error }
40
- end
41
-
42
- context 'has correct username, but incorrect password for single factor auth under info level of api access' do
43
- it { expect{Plaid.add_user('info','plaid_test','plaid_bad','wells')}.to raise_error }
44
- end
45
-
46
- context 'has incorrect username under info level of api access' do
47
- it { expect{Plaid.add_user('info','plaid_bad','plaid_bad','wells')}.to raise_error }
48
- end
49
-
50
- context 'enters pin for extra parameter authentication required by certain institutions' do
51
- user = Plaid.add_user('connect','plaid_test','plaid_good','usaa','1234')
52
- it { expect(user.api_res).to eq 'Requires further authentication' }
53
- end
54
-
55
- context 'enters incorrect pin for extra parameter authentication required by certain institutions' do
56
- it { expect{Plaid.add_user('connect','plaid_test','plaid_good','usaa','0000')}.to raise_error }
57
- end
58
-
59
- context 'has to enter MFA credentials' do
60
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','bofa')
61
- it { expect(user.api_res).to eq 'Requires further authentication' }
62
- end
63
-
64
- context 'enters correct information with locked account' do
65
- user = Plaid.add_user('connect','plaid_test', 'plaid_locked','wells')
66
- it { expect(user.api_res).to eq 'User account is locked' }
67
- end
68
-
69
- context 'enters webhook option as part of standard call' do
70
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','wells',{login_only: true, webhook: 'test.com/test.endpoint.aspx'})
71
- it { expect(user.accounts.empty?).to be_falsey }
72
- end
73
-
74
- context 'enters webhook option as part of mfa required institution authentication' do
75
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','bofa',{login_only: true, webhook: 'test.com/test.endpoint.aspx'})
76
- it { expect(user.api_res).to eq 'Requires further authentication' }
77
- end
78
-
79
- context 'requests pending transactions from an institution' do
80
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','wells',{pending: true})
81
- it { expect(user.accounts.empty?).to be_falsey }
82
- end
83
-
84
- context 'sets the login only option to true' do
85
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','wells',{login_only:true})
86
- it { expect(user.accounts.empty?).to be_falsey }
87
- end
88
-
89
- context 'requests a list of options for code based MFA' do
90
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','citi',{list: true})
91
- it { expect(user.pending_mfa_questions.nil?).to be_falsey }
92
- end
93
-
94
- context 'sets a start date for transactions' do
95
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','wells',{login_only:true, start_date:'10 days ago'})
96
- it { expect(user.accounts.empty?).to be_falsey }
97
- end
98
-
99
- context 'sets an end date for transactions' do
100
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','wells',{login_only:true, end_date: '10 days ago'})
101
- it { expect(user.accounts.empty?).to be_falsey }
102
- end
103
-
104
- context 'sets start and end dates for transactions' do
105
- user = Plaid.add_user('connect','plaid_test','plaid_good','wells',"{'gte':'05/10/2014' , 'lte':'06/10/2014'}")
106
- it{ expect(user.transactions).to be_truthy }
107
- end
108
-
109
- context 'sets a user with an existing access token' do
110
- user = Plaid.set_user('test')
111
- it{ expect(user.access_token).to eq('test')}
112
- end
113
- end