open-banking-io 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b6ab2de9b335f7edc7203e5723066756103876c5f986dfd6ac6ff1ac7bf263f
4
- data.tar.gz: 4ede77b0da39a399387d49d7b47ec4c76b7c7277c4983b61d928fbca320adf7f
3
+ metadata.gz: 52d72498c008ed13bec684867aef1f1b693c6f9ba0ed824e981ae554787c19a8
4
+ data.tar.gz: 47d0c4dbfc8511f80b0ac8b9d2270fbd68f969141b222c7dda61a2c8254e577c
5
5
  SHA512:
6
- metadata.gz: e8af173269a9036665b494976ccb5292754a6984f6f18f356e2e7946edc6cd7387919cf348c73d226f96bed1ae6e65dc6fb35b8881a64dfc5788b6574c53a8b9
7
- data.tar.gz: 5a91e86f5fdfaf166b1e1fe691efb86fc39cdeb2b9246838af679b2c8693f222100d6dafaa1db92df1ea976ec87b9947072eef93ee553f2e46090c0b34cf4472
6
+ metadata.gz: 13cce72e500507d12756086fc0d3dd6595556fb4200f6d9da9c69bc112558aefafa684043814988b8e58a0ee1907a2480d9d29b0721c9f6de73677afb3b25818
7
+ data.tar.gz: f607fde4595bf4b1499d32db231d7939d60b064dfe2308cdcecd80557735bf7c0ad062052003d11787c5f2d661269b24518130dd41c5c5a1e52dd8963c97b6fe
data/README.md CHANGED
@@ -1,3 +1,9 @@
1
+ <p align="center">
2
+ <a href="https://open-banking.io">
3
+ <img src="https://raw.githubusercontent.com/open-banking-io/clients/main/.github/logo.png" alt="open-banking.io" height="56">
4
+ </a>
5
+ </p>
6
+
1
7
  # open-banking-io (Ruby)
2
8
 
3
9
  Server-to-server client for [open-banking.io](https://open-banking.io). It authenticates with your
@@ -55,8 +61,9 @@ Every request sets connect/read timeouts (15s/60s) and a `User-Agent: open-banki
55
61
 
56
62
  Envelopes use **ECDH P-256 → HKDF-SHA256 → AES-256-GCM**, implemented entirely with Ruby's OpenSSL
57
63
  standard library. Decryption requires the private key from your credentials bundle and happens fully
58
- in-process. See the [repo README](https://github.com/open-banking-io/clients) for the full scheme and
59
- the other language clients (.NET, Node, Python, Rust, Go, Java).
64
+ in-process. Full wire format and the other language clients:
65
+ [repo README](https://github.com/open-banking-io/clients) ·
66
+ [`THREAT_MODEL.md`](https://github.com/open-banking-io/clients/blob/main/THREAT_MODEL.md).
60
67
 
61
68
  ## Development
62
69
 
@@ -32,7 +32,12 @@ module OpenBankingIO
32
32
  USER_AGENT = "open-banking-io/ruby/#{VERSION}".freeze
33
33
 
34
34
  # Builds a client from a credentials-bundle JSON string or a path to a bundle file.
35
- def self.from_credentials(path_or_json)
35
+ #
36
+ # Optional +open_timeout+/+read_timeout+ (seconds) and a caller-supplied +http_client+
37
+ # (an object responding to +#request+, e.g. a preconfigured Net::HTTP) are threaded
38
+ # straight through to +#initialize+; the defaults preserve the previous behaviour.
39
+ def self.from_credentials(path_or_json, open_timeout: DEFAULT_OPEN_TIMEOUT,
40
+ read_timeout: DEFAULT_READ_TIMEOUT, http_client: nil)
36
41
  raw = if File.file?(path_or_json.to_s)
37
42
  File.read(path_or_json)
38
43
  else
@@ -50,17 +55,37 @@ module OpenBankingIO
50
55
  raise ArgumentError, "The credentials bundle has no encryption private key"
51
56
  end
52
57
 
53
- new(api_base_url: api_base_url, api_key: api_key, private_key_pkcs8: private_key)
58
+ new(
59
+ api_base_url: api_base_url,
60
+ api_key: api_key,
61
+ private_key_pkcs8: private_key,
62
+ open_timeout: open_timeout,
63
+ read_timeout: read_timeout,
64
+ http_client: http_client
65
+ )
54
66
  end
55
67
 
56
- def initialize(api_base_url:, api_key:, private_key_pkcs8:)
68
+ # +open_timeout+/+read_timeout+ are seconds applied to the internally built Net::HTTP.
69
+ # +http_client+, when given, is any object responding to +#request+ (e.g. a preconfigured
70
+ # Net::HTTP for a proxy, custom CA/mTLS or connection pooling); it is used as-is instead
71
+ # of building one internally. All three are optional and default to the previous behaviour.
72
+ def initialize(api_base_url:, api_key:, private_key_pkcs8:,
73
+ open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT,
74
+ http_client: nil)
57
75
  raise ArgumentError, "api_base_url is required" if blank?(api_base_url)
58
76
  raise ArgumentError, "api_key is required" if blank?(api_key)
59
77
  raise ArgumentError, "private_key_pkcs8 is required" if blank?(private_key_pkcs8)
60
78
 
61
- @base_uri = URI.parse(api_base_url.to_s.sub(%r{/+\z}, "") + "/")
79
+ # Strip any trailing slashes without a backtracking regex (avoids ReDoS on
80
+ # pathological input) then re-append a single one, so the base always ends in "/".
81
+ base = api_base_url.to_s
82
+ base = base.chomp("/") while base.end_with?("/")
83
+ @base_uri = URI.parse(base + "/")
62
84
  @api_key = api_key
63
85
  @private_key = Envelope.load_private_key(private_key_pkcs8)
86
+ @open_timeout = open_timeout
87
+ @read_timeout = read_timeout
88
+ @http_client = http_client
64
89
  end
65
90
 
66
91
  # Lists the user's accounts with all sensitive fields decrypted.
@@ -255,10 +280,7 @@ module OpenBankingIO
255
280
  request["Accept"] = "application/json"
256
281
  request["User-Agent"] = USER_AGENT
257
282
 
258
- http = Net::HTTP.new(uri.host, uri.port)
259
- http.use_ssl = (uri.scheme == "https")
260
- http.open_timeout = DEFAULT_OPEN_TIMEOUT
261
- http.read_timeout = DEFAULT_READ_TIMEOUT
283
+ http = @http_client || build_http(uri)
262
284
 
263
285
  response = http.request(request)
264
286
  code = response.code.to_i
@@ -269,5 +291,13 @@ module OpenBankingIO
269
291
 
270
292
  JSON.parse(body)
271
293
  end
294
+
295
+ def build_http(uri)
296
+ http = Net::HTTP.new(uri.host, uri.port)
297
+ http.use_ssl = (uri.scheme == "https")
298
+ http.open_timeout = @open_timeout
299
+ http.read_timeout = @read_timeout
300
+ http
301
+ end
272
302
  end
273
303
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenBankingIO
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open-banking-io
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - open-banking.io
@@ -85,22 +85,19 @@ dependencies:
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '2.1'
88
+ version: '3.1'
89
89
  type: :development
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '2.1'
95
+ version: '3.1'
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: rexml
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '3.3'
103
- - - "<"
104
101
  - !ruby/object:Gem::Version
105
102
  version: '3.4'
106
103
  type: :development
@@ -108,9 +105,6 @@ dependencies:
108
105
  version_requirements: !ruby/object:Gem::Requirement
109
106
  requirements:
110
107
  - - "~>"
111
- - !ruby/object:Gem::Version
112
- version: '3.3'
113
- - - "<"
114
108
  - !ruby/object:Gem::Version
115
109
  version: '3.4'
116
110
  - !ruby/object:Gem::Dependency