bankscrap-bbva 1.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ef32ec6a56dd9b9352ca60ff3a86b14e9b70f21
4
- data.tar.gz: ad37699ac93f8a959cd8562a0e6dd590a466bbdb
3
+ metadata.gz: 34df67e80fb703b3062b1ddb00ec2be8ad25b285
4
+ data.tar.gz: bd806c0c5b61626262b542f0f2dd0e91f5c2562d
5
5
  SHA512:
6
- metadata.gz: 023c42192b35b82f99a8fe7f4e704e42a2419fbf0963a8317131ffe7299e75eb820d68ae09a341134480f08c5358bd54f49001f5e58639b7ffb5771d59c8c62e
7
- data.tar.gz: ff6b7afb3e00a79649cd3b4313f094de12ad50032d7d80b7172a4dead6337d96f63e31d42bf5e9dc3c08c1bbd59c96bb1b2730e4dca58ee729775183a51ee1a4
6
+ metadata.gz: ccb5d6536cb19ca254d51708175c2a88f87dadcccb8a80f5dc156c309f48a3038b8d2812958f5b5d3e3f30a187bc015ce0863a37059fd864a1ddcf4496b40c00
7
+ data.tar.gz: 35c34f71df5a9cee1dfa2f261ba657e9b72c78de72a848b8a1972cb2c630a4a5274eeb1bc63c393337e115b3486e1b15742c53675d0348e58bf107818f2d4ed0
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.1
3
+
4
+ Metrics/LineLength:
5
+ Max: 120
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Bankscrap::BBVA
2
2
 
3
- Bankscrap adapter for the API behind BBVA's [mobile app](https://play.google.com/store/apps/developer?id=BBVA&hl=en).
3
+ Bankscrap adapter for the API behind BBVA's [mobile app](https://play.google.com/store/apps/details?id=com.bbva.bbvacontigo&hl=en).
4
4
  This adapter is only valid for personal accounts (the ones that work with that mobile APP), not for company accounts.
5
5
 
6
6
  ## Installation
@@ -26,7 +26,7 @@ For usage instructions please read [Bankscrap readme](https://github.com/bankscr
26
26
 
27
27
  ## Contributing
28
28
 
29
- 1. Fork it ( https://github.com/[my-github-username]/bankscrap-bbva/fork )
29
+ 1. Fork it ( https://github.com/bankscrap/bankscrap-bbva/fork )
30
30
  2. Create your feature branch (`git checkout -b my-new-feature`)
31
31
  3. Commit your changes (`git commit -am 'Add some feature'`)
32
32
  4. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
- require "bundler/gem_tasks"
2
-
1
+ require 'bundler/gem_tasks'
@@ -4,20 +4,20 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'bankscrap/bbva/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "bankscrap-bbva"
7
+ spec.name = 'bankscrap-bbva'
8
8
  spec.version = Bankscrap::BBVA::VERSION
9
9
  spec.authors = ['Javier Cuevas']
10
- spec.email = ["javier@diacode.com"]
11
- spec.summary = %q{BBVA adapter for Bankscrap}
12
- spec.homepage = ""
13
- spec.license = "MIT"
10
+ spec.email = ['javier@diacode.com']
11
+ spec.summary = 'BBVA adapter for Bankscrap'
12
+ spec.homepage = ''
13
+ spec.license = 'MIT'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
19
19
 
20
- spec.add_runtime_dependency "bankscrap", "~> 1.0"
21
- spec.add_development_dependency "bundler", "~> 1.7"
22
- spec.add_development_dependency "rake", "~> 10.0"
20
+ spec.add_runtime_dependency 'bankscrap', '~> 2.0.3'
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
23
  end
@@ -1,2 +1,3 @@
1
1
  require_relative 'bankscrap/bbva/bank'
2
2
  require_relative 'bankscrap/bbva/version'
3
+ require_relative 'monkey_patch/mechanize'
@@ -3,35 +3,35 @@ require 'bankscrap'
3
3
  module Bankscrap
4
4
  module BBVA
5
5
  class Bank < ::Bankscrap::Bank
6
- BASE_ENDPOINT = 'https://servicios.bbva.es'
7
- LOGIN_ENDPOINT = '/DFAUTH/slod/DFServletXML'
8
- PRODUCTS_ENDPOINT = '/ENPP/enpp_mult_web_mobility_02/products/v1'
9
- ACCOUNT_ENDPOINT = '/ENPP/enpp_mult_web_mobility_02/accounts/'
10
- # BBVA expects an identifier before the actual User Agent, but 12345 works fine
11
- USER_AGENT = '12345;Android;LGE;Nexus 5;1080x1776;Android;5.1.1;BMES;4.4;xxhd'
12
-
13
- def initialize(user, password, log: false, debug: false, extra_args: nil)
14
- @user = format_user(user.dup)
15
- @password = password
16
- @log = log
17
- @debug = debug
18
-
19
- initialize_connection
20
-
21
- add_headers(
22
- 'User-Agent' => USER_AGENT,
23
- 'BBVA-User-Agent' => USER_AGENT,
24
- 'Accept-Language' => 'spa',
25
- 'Content-Language' => 'spa',
26
- 'Accept' => 'application/json',
27
- 'Accept-Charset' => 'UTF-8',
28
- 'Connection' => 'Keep-Alive',
29
- 'Host' => 'bancamovil.grupobbva.com',
30
- 'Cookie2' => '$Version=1'
31
- )
6
+ BASE_ENDPOINT = 'https://servicios.bbva.es'.freeze
7
+ LOGIN_ENDPOINT = '/DFAUTH/slod/DFServletXML'.freeze
8
+ SESSIONS_ENDPOINT = '/ENPP/enpp_mult_web_mobility_02/sessions/v1'.freeze
9
+ PRODUCTS_ENDPOINT = '/ENPP/enpp_mult_web_mobility_02/products/v2'.freeze
10
+ ACCOUNT_ENDPOINT = '/ENPP/enpp_mult_web_mobility_02/accounts/'.freeze
32
11
 
33
- login
34
- super
12
+ # BBVA expects an identifier before the actual User Agent, but 12345 works fine
13
+ USER_AGENT = SecureRandom.hex(64).upcase + ';iPhone;Apple;iPhone5,2;640x1136;iOS;9.3.2;WOODY;5.1.2;xhdpi'.freeze
14
+ REQUIRED_CREDENTIALS = [:user, :password].freeze
15
+
16
+ # This is probably some sort of identifier of Android vs iOS consumer app
17
+ CONSUMER_ID = '00000013'.freeze
18
+
19
+ def initialize(credentials = {})
20
+ super do
21
+ @user = format_user(@user.dup)
22
+
23
+ add_headers(
24
+ 'User-Agent' => USER_AGENT,
25
+ 'BBVA-User-Agent' => USER_AGENT,
26
+ 'Accept-Language' => 'spa',
27
+ 'Content-Language' => 'spa',
28
+ 'Accept' => 'application/json',
29
+ 'Accept-Charset' => 'UTF-8',
30
+ 'Connection' => 'Keep-Alive',
31
+ 'Host' => 'servicios.bbva.es',
32
+ 'ConsumerID' => CONSUMER_ID
33
+ )
34
+ end
35
35
  end
36
36
 
37
37
  # Fetch all the accounts for the given user
@@ -65,11 +65,11 @@ module Bankscrap
65
65
  'BBVA-Method' => 'GET'
66
66
  }
67
67
 
68
- # The API accepts a toDate param that we could pass the end_date argument,
68
+ # The API accepts a toDate param that we could pass the end_date argument,
69
69
  # however when we pass the toDate param, the API stops returning the account balance.
70
- # Therefore we need to take a workaround: only filter with fromDate and loop
71
- # over all the available pages, filtering out the movements that doesn't match
72
- # the end_date argument.
70
+ # Therefore we need to take a workaround: only filter with fromDate and loop
71
+ # over all the available pages, filtering out the movements that doesn't match
72
+ # the end_date argument.
73
73
  url = BASE_ENDPOINT +
74
74
  ACCOUNT_ENDPOINT +
75
75
  account.id +
@@ -113,7 +113,7 @@ module Bankscrap
113
113
  def format_user(user)
114
114
  user.upcase!
115
115
 
116
- if user.match(/^[0-9]{8}[A-Z]$/)
116
+ if user =~ /^[0-9]{8}[A-Z]$/
117
117
  # It's a DNI
118
118
  "0019-0#{user}"
119
119
  else
@@ -130,6 +130,19 @@ module Bankscrap
130
130
  'eai_password' => @password
131
131
  }
132
132
  post(BASE_ENDPOINT + LOGIN_ENDPOINT, fields: params)
133
+
134
+ # We also need to initialize a session
135
+ with_headers('Content-Type' => 'application/json') do
136
+ post(SESSIONS_ENDPOINT, fields: {
137
+ consumerID: CONSUMER_ID
138
+ }.to_json)
139
+ end
140
+
141
+ # We need to extract the "tsec" header from the last response.
142
+ # As the Bankscrap core library doesn't expose the headers of each response
143
+ # we have to use Mechanize's HTTP client "current_page" method.
144
+ tsec = @http.current_page.response['tsec']
145
+ add_headers('tsec' => tsec)
133
146
  end
134
147
 
135
148
  # Build an Account object from API data
@@ -138,9 +151,8 @@ module Bankscrap
138
151
  bank: self,
139
152
  id: data['id'],
140
153
  name: data['name'],
141
- available_balance: data['availableBalance'],
142
- balance: data['availableBalance'],
143
- currency: data['currency'],
154
+ available_balance: Money.new(data['availableBalance'].to_f * 100, data['currency']),
155
+ balance: Money.new(data['actualBalance'].to_f * 100, data['currency']),
144
156
  iban: data['iban'],
145
157
  description: "#{data['typeDescription']} #{data['familyCode']}"
146
158
  )
@@ -154,7 +166,6 @@ module Bankscrap
154
166
  amount: transaction_amount(data),
155
167
  description: data['conceptDescription'] || data['description'],
156
168
  effective_date: Date.strptime(data['operationDate'], '%Y-%m-%d'),
157
- currency: data['currency'],
158
169
  balance: transaction_balance(data)
159
170
  )
160
171
  end
@@ -1,5 +1,5 @@
1
1
  module Bankscrap
2
2
  module BBVA
3
- VERSION = "1.0.0"
3
+ VERSION = '2.0.1'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,55 @@
1
+ # Extracted from http://scottwb.com/blog/2013/11/09/defeating-the-infamous-mechanize-too-many-connection-resets-bug/
2
+
3
+ class Mechanize::HTTP::Agent
4
+ MAX_RESET_RETRIES = 10
5
+
6
+ # We need to replace the core Mechanize HTTP method:
7
+ #
8
+ # Mechanize::HTTP::Agent#fetch
9
+ #
10
+ # with a wrapper that handles the infamous "too many connection resets"
11
+ # Mechanize bug that is described here:
12
+ #
13
+ # https://github.com/sparklemotion/mechanize/issues/123
14
+ #
15
+ # The wrapper shuts down the persistent HTTP connection when it fails with
16
+ # this error, and simply tries again. In practice, this only ever needs to
17
+ # be retried once, but I am going to let it retry a few times
18
+ # (MAX_RESET_RETRIES), just in case.
19
+ #
20
+ def fetch_with_retry(
21
+ uri,
22
+ method = :get,
23
+ headers = {},
24
+ params = [],
25
+ referer = current_page,
26
+ redirects = 0
27
+ )
28
+ action = "#{method.to_s.upcase} #{uri.to_s}"
29
+ retry_count = 0
30
+
31
+ begin
32
+ fetch_without_retry(uri, method, headers, params, referer, redirects)
33
+ rescue Net::HTTP::Persistent::Error => e
34
+ # Pass on any other type of error.
35
+ raise unless e.message =~ /too many connection resets/
36
+
37
+ # Pass on the error if we've tried too many times.
38
+ if retry_count >= MAX_RESET_RETRIES
39
+ puts "**** WARN: Mechanize retried connection reset #{MAX_RESET_RETRIES} times and never succeeded: #{action}" if Bankscrap.debug
40
+ raise
41
+ end
42
+
43
+ # Otherwise, shutdown the persistent HTTP connection and try again.
44
+ puts "**** WARN: Mechanize retrying connection reset error: #{action}" if Bankscrap.debug
45
+ retry_count += 1
46
+ self.http.shutdown
47
+ retry
48
+ end
49
+ end
50
+
51
+ # Alias so #fetch actually uses our new #fetch_with_retry to wrap the
52
+ # old one aliased as #fetch_without_retry.
53
+ alias_method :fetch_without_retry, :fetch
54
+ alias_method :fetch, :fetch_with_retry
55
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bankscrap-bbva
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Cuevas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-30 00:00:00.000000000 Z
11
+ date: 2017-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bankscrap
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: 2.0.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: 2.0.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +60,7 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
+ - ".rubocop.yml"
63
64
  - Gemfile
64
65
  - LICENSE.txt
65
66
  - README.md
@@ -68,6 +69,7 @@ files:
68
69
  - lib/bankscrap-bbva.rb
69
70
  - lib/bankscrap/bbva/bank.rb
70
71
  - lib/bankscrap/bbva/version.rb
72
+ - lib/monkey_patch/mechanize.rb
71
73
  homepage: ''
72
74
  licenses:
73
75
  - MIT
@@ -88,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
90
  version: '0'
89
91
  requirements: []
90
92
  rubyforge_project:
91
- rubygems_version: 2.6.4
93
+ rubygems_version: 2.4.8
92
94
  signing_key:
93
95
  specification_version: 4
94
96
  summary: BBVA adapter for Bankscrap